Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp	(revision 50680)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp	(revision 50681)
@@ -23,7 +23,4 @@
 #include "UIMachineLogic.h"
 #include "UIMachineWindow.h"
-#ifdef Q_WS_MAC
-# include <ApplicationServices/ApplicationServices.h>
-#endif /* Q_WS_MAC */
 
 /* Visual state interface: */
@@ -40,7 +37,4 @@
         , m_pSession(pSession)
         , m_pMachineLogic(0)
-#ifdef Q_WS_MAC
-        , m_fadeToken(kCGDisplayFadeReservationInvalidToken)
-#endif /* Q_WS_MAC */
     {
     }
@@ -66,24 +60,8 @@
 
     /* Method to prepare change one visual state to another: */
-    bool prepareChange(UIVisualStateType previousVisualStateType)
+    bool prepareChange()
     {
         m_pMachineLogic = UIMachineLogic::create(this, m_pSession, visualStateType());
-        bool fResult = m_pMachineLogic->checkAvailability();
-#ifdef Q_WS_MAC
-        /* If the new is or the old type was fullscreen we add the blending
-         * transition between the mode switches.
-         * TODO: make this more general. */
-        if (   fResult
-            && (   visualStateType() == UIVisualStateType_Fullscreen
-                || previousVisualStateType == UIVisualStateType_Fullscreen))
-        {
-            /* Fade to black */
-            CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &m_fadeToken);
-            CGDisplayFade(m_fadeToken, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true);
-        }
-#else /* Q_WS_MAC */
-        Q_UNUSED(previousVisualStateType);
-#endif /* !Q_WS_MAC */
-        return fResult;
+        return m_pMachineLogic->checkAvailability();
     }
 
@@ -93,20 +71,4 @@
         /* Prepare the logic object: */
         m_pMachineLogic->prepare();
-    }
-
-    /* Method to finish change one visual state to another: */
-    void finishChange()
-    {
-#ifdef Q_WS_MAC
-        /* If there is a valid fade token, fade back to normal color in any
-         * case. */
-        if (m_fadeToken != kCGDisplayFadeReservationInvalidToken)
-        {
-            /* Fade back to the normal gamma */
-            CGDisplayFade(m_fadeToken, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false);
-            CGReleaseDisplayFadeReservation(m_fadeToken);
-            m_fadeToken = kCGDisplayFadeReservationInvalidToken;
-        }
-#endif /* Q_WS_MAC */
     }
 
@@ -117,7 +79,4 @@
     UISession *m_pSession;
     UIMachineLogic *m_pMachineLogic;
-#ifdef Q_WS_MAC
-    CGDisplayFadeReservationToken m_fadeToken;
-#endif /* Q_WS_MAC */
 };
 
@@ -200,10 +159,7 @@
     UIVisualState *pNewVisualState = new UIVisualState(this, m_pSession, newVisualStateType);
 
-    /* Get previous visual state type: */
-    UIVisualStateType previousVisualStateType = m_pVisualState ? m_pVisualState->visualStateType() : UIVisualStateType_Normal;
-
     /* First we have to check if the selected mode is available at all.
      * Only then we delete the old mode and switch to the new mode. */
-    if (pNewVisualState->prepareChange(previousVisualStateType))
+    if (pNewVisualState->prepareChange())
     {
         /* Delete previous state: */
@@ -213,7 +169,4 @@
         m_pVisualState = pNewVisualState;
         m_pVisualState->change();
-
-        /* Finish any setup: */
-        m_pVisualState->finishChange();
     }
     else
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp	(revision 50680)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp	(revision 50681)
@@ -36,4 +36,7 @@
 UIMachineLogicFullscreen::UIMachineLogicFullscreen(QObject *pParent, UISession *pSession)
     : UIMachineLogic(pParent, pSession, UIVisualStateType_Fullscreen)
+#ifdef Q_WS_MAC
+    , m_fadeToken(kCGDisplayFadeReservationInvalidToken)
+#endif /* Q_WS_MAC */
 {
     /* Create multiscreen layout: */
@@ -99,5 +102,5 @@
 
 #ifdef RT_OS_DARWIN
-void UIMachineLogicFullscreen::sltHandleNativeFullscreenDidEnter()
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenWillEnter()
 {
     /* Make sure this method is only used for ML and next: */
@@ -108,7 +111,42 @@
     AssertReturnVoid(pMachineWindow);
 
+    /* Fade to black: */
+    fadeToBlack();
+}
+
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenDidEnter()
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Get sender machine-window: */
+    UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(sender());
+    AssertReturnVoid(pMachineWindow);
+
     /* Add machine-window to corresponding set: */
     m_fullscreenMachineWindows.insert(pMachineWindow);
     AssertReturnVoid(m_fullscreenMachineWindows.contains(pMachineWindow));
+
+    /* Fade to normal if necessary: */
+    QSet<UIMachineWindow*> visibleMachineWindows;
+    foreach (UIMachineWindow *pMachineWindow, machineWindows())
+        if (uisession()->isScreenVisible(pMachineWindow->screenId()))
+            visibleMachineWindows << pMachineWindow;
+    if (   !darwinScreensHaveSeparateSpaces()
+        || m_fullscreenMachineWindows == visibleMachineWindows)
+        fadeToNormal();
+}
+
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenWillExit()
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Get sender machine-window: */
+    UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(sender());
+    AssertReturnVoid(pMachineWindow);
+
+    /* Fade to black: */
+    fadeToBlack();
 }
 
@@ -164,4 +202,7 @@
             uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
             uisession()->changeVisualState(type);
+
+            /* Fade to normal: */
+            fadeToNormal();
         }
     }
@@ -360,4 +401,7 @@
      * This is necessary for Qt versions > 4.3.3: */
     darwinSetFrontMostProcess();
+
+    /* Fade to black: */
+    fadeToBlack();
 #endif /* Q_WS_MAC */
 
@@ -376,4 +420,9 @@
     /* Activate 'presentation mode': */
     setPresentationModeEnabled(true);
+
+    /* For Lion and previous fade to normal: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        fadeToNormal();
+
     /* For ML and next: */
     if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
@@ -388,6 +437,10 @@
                     pMachineWindow, SLOT(sltExitNativeFullscreen(UIMachineWindow*)));
             /* Window => logic signals: */
+            connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenWillEnter()),
+                    this, SLOT(sltHandleNativeFullscreenWillEnter()));
             connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenDidEnter()),
                     this, SLOT(sltHandleNativeFullscreenDidEnter()));
+            connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenWillExit()),
+                    this, SLOT(sltHandleNativeFullscreenWillExit()));
             connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenDidExit()),
                     this, SLOT(sltHandleNativeFullscreenDidExit()));
@@ -418,4 +471,10 @@
         return;
 
+#ifdef Q_WS_MAC
+    /* For Lion and previous fade to black: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        fadeToBlack();
+#endif/* Q_WS_MAC */
+
     /* Mark machine-window(s) destroyed: */
     setMachineWindowsCreated(false);
@@ -428,4 +487,7 @@
     /* Deactivate 'presentation mode': */
     setPresentationModeEnabled(false);
+
+    /* Fade to normal: */
+    fadeToNormal();
 #endif/* Q_WS_MAC */
 }
@@ -499,4 +561,27 @@
 }
 
+void UIMachineLogicFullscreen::fadeToBlack()
+{
+    /* Make sure fade-token invalid: */
+    if (m_fadeToken != kCGDisplayFadeReservationInvalidToken)
+        return;
+
+    /* Acquire fade-token: */
+    CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &m_fadeToken);
+    CGDisplayFade(m_fadeToken, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true);
+}
+
+void UIMachineLogicFullscreen::fadeToNormal()
+{
+    /* Make sure fade-token valid: */
+    if (m_fadeToken == kCGDisplayFadeReservationInvalidToken)
+        return;
+
+    /* Release fade-token: */
+    CGDisplayFade(m_fadeToken, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false);
+    CGReleaseDisplayFadeReservation(m_fadeToken);
+    m_fadeToken = kCGDisplayFadeReservationInvalidToken;
+}
+
 void UIMachineLogicFullscreen::revalidateFullscreenWindow(UIMachineWindow *pMachineWindow)
 {
@@ -534,4 +619,7 @@
                 LogRel(("UIMachineLogicFullscreen::revalidateFullscreenWindow: "
                         "Ask machine-window #%d to enter fullscreen.\n", (int)uScreenID));
+
+                /* Fade to black: */
+                fadeToBlack();
 
                 /* Update 'presentation mode': */
@@ -569,4 +657,7 @@
                         "Ask machine-window #%d to exit fullscreen.\n", (int)uScreenID));
 
+                /* Fade to black: */
+                fadeToBlack();
+
                 /* Mark window as invalidated: */
                 m_invalidFullscreenMachineWindows << pMachineWindow;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h	(revision 50680)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h	(revision 50681)
@@ -18,6 +18,11 @@
 #define ___UIMachineLogicFullscreen_h___
 
-/* Local includes: */
+/* GUI includes: */
 #include "UIMachineLogic.h"
+
+/* Other includes: */
+#ifdef Q_WS_MAC
+# include <ApplicationServices/ApplicationServices.h>
+#endif /* Q_WS_MAC */
 
 /* Forward declarations: */
@@ -54,8 +59,11 @@
 
 #ifdef RT_OS_DARWIN
-    /** Mac OS X: Marks sender() machine-window as 'fullscreen' one. */
+    /** Mac OS X: Handles native notification about 'fullscreen' will be entered. */
+    void sltHandleNativeFullscreenWillEnter();
+    /** Mac OS X: Handles native notification about 'fullscreen' entered. */
     void sltHandleNativeFullscreenDidEnter();
-    /** Mac OS X: Marks sender() machine-window as 'non-fullscreen' one,
-      * changes visual-state to requested if there is/are no more fullscreen window(s). */
+    /** Mac OS X: Handles native notification about 'fullscreen' will be exited. */
+    void sltHandleNativeFullscreenWillExit();
+    /** Mac OS X: Handles native notification about 'fullscreen' exited. */
     void sltHandleNativeFullscreenDidExit();
 
@@ -104,4 +112,9 @@
     void setPresentationModeEnabled(bool fEnabled);
 
+    /** Mac OS X: Performs fade to black if possible. */
+    void fadeToBlack();
+    /** Mac OS X: Performs fade to normal if possible. */
+    void fadeToNormal();
+
     /** Mac OS X: Revalidates 'fullscreen' mode for @a pMachineWindow. */
     void revalidateFullscreenWindow(UIMachineWindow *pMachineWindow);
@@ -114,4 +127,7 @@
 
 #ifdef Q_WS_MAC
+    /** Mac OS X: Fade token. */
+    CGDisplayFadeReservationToken m_fadeToken;
+
     /** Mac OS X: Contains machine-window(s) marked as 'fullscreen'. */
     QSet<UIMachineWindow*> m_fullscreenMachineWindows;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp	(revision 50680)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp	(revision 50681)
@@ -60,6 +60,13 @@
             strNativeNotificationName.toAscii().constData()));
 
+    /* Handle 'NSWindowWillEnterFullScreenNotification' notification: */
+    if (strNativeNotificationName == "NSWindowWillEnterFullScreenNotification")
+    {
+        LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
+                "Native fullscreen mode about to enter, notifying listener...\n"));
+        emit sigNotifyAboutNativeFullscreenWillEnter();
+    }
     /* Handle 'NSWindowDidEnterFullScreenNotification' notification: */
-    if (strNativeNotificationName == "NSWindowDidEnterFullScreenNotification")
+    else if (strNativeNotificationName == "NSWindowDidEnterFullScreenNotification")
     {
         /* Mark window transition complete: */
@@ -68,4 +75,11 @@
                 "Native fullscreen mode entered, notifying listener...\n"));
         emit sigNotifyAboutNativeFullscreenDidEnter();
+    }
+    /* Handle 'NSWindowWillExitFullScreenNotification' notification: */
+    else if (strNativeNotificationName == "NSWindowWillExitFullScreenNotification")
+    {
+        LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
+                "Native fullscreen mode about to exit, notifying listener...\n"));
+        emit sigNotifyAboutNativeFullscreenWillExit();
     }
     /* Handle 'NSWindowDidExitFullScreenNotification' notification: */
@@ -189,5 +203,9 @@
             darwinEnableTransienceSupport(this);
         /* Register to native fullscreen notifications: */
+        UICocoaApplication::instance()->registerToNativeNotification("NSWindowWillEnterFullScreenNotification", this,
+                                                                     UIMachineWindow::handleNativeNotification);
         UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidEnterFullScreenNotification", this,
+                                                                     UIMachineWindow::handleNativeNotification);
+        UICocoaApplication::instance()->registerToNativeNotification("NSWindowWillExitFullScreenNotification", this,
                                                                      UIMachineWindow::handleNativeNotification);
         UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidExitFullScreenNotification", this,
@@ -252,5 +270,7 @@
     {
         /* Unregister from native fullscreen notifications: */
+        UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowWillEnterFullScreenNotification", this);
         UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidEnterFullScreenNotification", this);
+        UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowWillExitFullScreenNotification", this);
         UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidExitFullScreenNotification", this);
     }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h	(revision 50680)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h	(revision 50681)
@@ -33,6 +33,10 @@
 #ifdef RT_OS_DARWIN
 signals:
+    /** Mac OS X: Notifies listener about native 'fullscreen' will be entered. */
+    void sigNotifyAboutNativeFullscreenWillEnter();
     /** Mac OS X: Notifies listener about native 'fullscreen' entered. */
     void sigNotifyAboutNativeFullscreenDidEnter();
+    /** Mac OS X: Notifies listener about native 'fullscreen' will be exited. */
+    void sigNotifyAboutNativeFullscreenWillExit();
     /** Mac OS X: Notifies listener about native 'fullscreen' exited. */
     void sigNotifyAboutNativeFullscreenDidExit();
