Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 49105)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 49121)
@@ -83,41 +83,33 @@
  * MacOS X: Application Services: Core Graphics: Display reconfiguration callback.
  *
- * Notifies about @a display configuration change.
- * Corresponding change described by CoreGraphics @a flags.
- * Calls for corresponding UISession slots through @a pHandlerObject to handle this callback.
+ * Notifies UISession about @a display configuration change.
+ * Corresponding change described by Core Graphics @a flags.
+ * Uses UISession @a pHandler to process this change.
  *
- * @note Last argument (@a pHandlerObject) must always be valid pointer to UISession object.
- * @note Calls for UISession::sltHandleHostScreenCountChange() if display count was changed.
- * @note Calls for UISession::sltHandleHostScreenGeometryChange() if display mode was changed.
+ * @note Last argument (@a pHandler) must always be valid pointer to UISession object.
+ * @note Calls for UISession::sltHandleHostDisplayAboutToChange() slot if display configuration changed.
  */
-void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandlerObject)
-{
+void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandler)
+{
+    /* Which flags we are handling? */
+    int iHandledFlags = kCGDisplayAddFlag     /* display added */
+                      | kCGDisplayRemoveFlag  /* display removed */
+                      | kCGDisplaySetModeFlag /* display mode changed */;
+
     /* Handle 'display-add' case: */
     if (flags & kCGDisplayAddFlag)
-    {
         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display added.\n"));
-
-        /* Ask receiver to handle our callback, can't believe I'm using r_c here... */
-        UISession *pReceiver = reinterpret_cast<UISession*>(pHandlerObject);
-        QTimer::singleShot(0, pReceiver, SLOT(sltHandleHostScreenCountChange()));
-    }
     /* Handle 'display-remove' case: */
     else if (flags & kCGDisplayRemoveFlag)
-    {
         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display removed.\n"));
-
-        /* Ask receiver to handle our callback, can't believe I'm using r_c here... */
-        UISession *pReceiver = reinterpret_cast<UISession*>(pHandlerObject);
-        QTimer::singleShot(0, pReceiver, SLOT(sltHandleHostScreenCountChange()));
-    }
     /* Handle 'mode-set' case: */
     else if (flags & kCGDisplaySetModeFlag)
-    {
         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display mode changed.\n"));
 
-        /* Ask receiver to handle our callback, can't believe I'm using r_c here... */
-        UISession *pReceiver = reinterpret_cast<UISession*>(pHandlerObject);
-        QTimer::singleShot(0, pReceiver, SLOT(sltHandleHostScreenGeometryChange()));
-    }
+    /* Ask handler to process our callback: */
+    if (flags & iHandledFlags)
+        QTimer::singleShot(0, static_cast<UISession*>(pHandler),
+                           SLOT(sltHandleHostDisplayAboutToChange()));
+
     Q_UNUSED(display);
 }
@@ -136,4 +128,7 @@
     , m_alphaCursor(0)
 #endif /* Q_WS_WIN */
+#ifdef Q_WS_MAC
+    , m_pWatchdogDisplayChange(0)
+#endif /* Q_WS_MAC */
     /* Common flags: */
     , m_fIsFirstTimeStarted(false)
@@ -838,4 +833,75 @@
 }
 
+#ifdef RT_OS_DARWIN
+/**
+ * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
+ * @note Watchdog is trying to determine display reconfiguration in
+ *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
+ */
+void UISession::sltHandleHostDisplayAboutToChange()
+{
+    LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
+
+    if (m_pWatchdogDisplayChange->isActive())
+        m_pWatchdogDisplayChange->stop();
+    m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
+    m_pWatchdogDisplayChange->start();
+}
+
+/**
+ * MacOS X: Determines display reconfiguration.
+ * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
+ * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
+ */
+void UISession::sltCheckIfHostDisplayChanged()
+{
+    LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
+
+    /* Acquire desktop wrapper: */
+    QDesktopWidget *pDesktop = QApplication::desktop();
+
+    /* Check if display count changed: */
+    if (pDesktop->screenCount() != m_screens.size())
+    {
+        /* Recache display data: */
+        recacheDisplayData();
+        /* Reset watchdog: */
+        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
+        /* Notify listeners about screen-count changed: */
+        return sltHandleHostScreenCountChange();
+    }
+    else
+    {
+        /* Check if at least one display geometry changed: */
+        for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
+        {
+            if (pDesktop->screenGeometry(iScreenIndex) != m_screens.at(iScreenIndex))
+            {
+                /* Recache display data: */
+                recacheDisplayData();
+                /* Reset watchdog: */
+                m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
+                /* Notify listeners about screen-geometry changed: */
+                return sltHandleHostScreenGeometryChange();
+            }
+        }
+    }
+
+    /* Check if watchdog expired, restart if not: */
+    int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
+    if (cTryNumber > 0 && cTryNumber < 40)
+    {
+        /* Restart watchdog again: */
+        m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
+        m_pWatchdogDisplayChange->start();
+    }
+    else
+    {
+        /* Reset watchdog: */
+        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
+    }
+}
+#endif /* RT_OS_DARWIN */
+
 void UISession::sltHandleHostScreenCountChange()
 {
@@ -942,4 +1008,8 @@
     connect(this, SIGNAL(sigCloseRuntimeUI()), this, SLOT(sltCloseRuntimeUI()));
 
+#ifdef Q_WS_MAC
+    /* Install native display reconfiguration callback: */
+    CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
+#else /* !Q_WS_MAC */
     /* Install Qt display reconfiguration callbacks: */
     connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)),
@@ -949,13 +1019,22 @@
     connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
             this, SLOT(sltHandleHostScreenGeometryChange()));
-
+#endif /* !Q_WS_MAC */
+}
+
+void UISession::prepareScreens()
+{
 #ifdef Q_WS_MAC
-    /* Install display reconfiguration callback: */
-    CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
+    /* Recache display data: */
+    recacheDisplayData();
+    /* Prepare display-change watchdog: */
+    m_pWatchdogDisplayChange = new QTimer(this);
+    {
+        m_pWatchdogDisplayChange->setInterval(500);
+        m_pWatchdogDisplayChange->setSingleShot(true);
+        connect(m_pWatchdogDisplayChange, SIGNAL(timeout()),
+                this, SLOT(sltCheckIfHostDisplayChanged()));
+    }
 #endif /* Q_WS_MAC */
-}
-
-void UISession::prepareScreens()
-{
+
     /* Get machine: */
     CMachine machine = m_session.GetMachine();
@@ -1533,4 +1612,16 @@
 }
 
+#ifdef Q_WS_MAC
+/** MacOS X: Recaches display-configuration data. */
+void UISession::recacheDisplayData()
+{
+    /* Recache display data: */
+    m_screens.clear();
+    QDesktopWidget *pDesktop = QApplication::desktop();
+    for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
+        m_screens << pDesktop->screenGeometry(iScreenIndex);
+}
+#endif /* Q_WS_MAC */
+
 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
 /**
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h	(revision 49105)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h	(revision 49121)
@@ -234,5 +234,9 @@
     void sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo);
 
-    /* Handlers: Host callback stuff: */
+    /* Handlers: Display reconfiguration stuff: */
+#ifdef RT_OS_DARWIN
+    void sltHandleHostDisplayAboutToChange();
+    void sltCheckIfHostDisplayChanged();
+#endif /* RT_OS_DARWIN */
     void sltHandleHostScreenCountChange();
     void sltHandleHostScreenGeometryChange();
@@ -270,4 +274,9 @@
     int countOfVisibleWindows();
 
+#ifdef Q_WS_MAC
+    /* Helper: Display reconfiguration stuff: */
+    void recacheDisplayData();
+#endif /* Q_WS_MAC */
+
 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     static void signalHandlerSIGUSR1(int sig, siginfo_t *pInfo, void *pSecret);
@@ -293,4 +302,13 @@
     HCURSOR m_alphaCursor;
 #endif
+#ifdef Q_WS_MAC
+    /** @name MacOS X: Display reconfiguration variables.
+     * @{ */
+    /** MacOS X: Watchdog timer looking for display reconfiguration. */
+    QTimer *m_pWatchdogDisplayChange;
+    /** MacOS X: A list of display geometries we currently have. */
+    QList<QRect> m_screens;
+    /** @} */
+#endif /* Q_WS_MAC */
 
     /* Common flags: */
