Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 39023)
@@ -169,4 +169,6 @@
 /**
  * Returns whether we like the given video mode.
+ * @note We always like a mode smaller than the current framebuffer
+ *       size.
  *
  * @returns COM status code
@@ -185,7 +187,11 @@
     *pbSupported = TRUE;
     QSize screen = m_pMachineView->maxGuestSize();
-    if ((screen.width() != 0) && (uWidth > (ULONG)screen.width()))
+    if (   (screen.width() != 0)
+        && (uWidth > (ULONG)screen.width())
+        && (uWidth > (ULONG)width()))
         *pbSupported = FALSE;
-    if ((screen.height() != 0) && (uHeight > (ULONG)screen.height()))
+    if (   (screen.height() != 0)
+        && (uHeight > (ULONG)screen.height())
+        && (uHeight > (ULONG)height()))
         *pbSupported = FALSE;
     LogFlowThisFunc(("screenW=%lu, screenH=%lu -> aSupported=%s\n",
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 39023)
@@ -25,4 +25,5 @@
 #include <QScrollBar>
 #include <VBox/VBoxVideo.h>
+#include <iprt/asm.h>
 
 /* Local includes */
@@ -160,6 +161,4 @@
     AssertMsg(newSize.isValid(), ("Size should be valid!\n"));
 
-    /* Store the new hint */
-    storeHintForGuestSizePolicy(newSize.width(), newSize.height());
     /* Send new size-hint to the guest: */
     session().GetConsole().GetDisplay().SetVideoModeHint(newSize.width(), newSize.height(), 0, screenId());
@@ -240,4 +239,5 @@
     , m_previousState(KMachineState_Null)
     , m_maxGuestSizePolicy(MaxGuestSizePolicy_Invalid)
+    , m_u64MaxGuestSize(0)
 #ifdef VBOX_WITH_VIDEOHWACCEL
     , m_fAccelerate2DVideo(bAccelerate2DVideo)
@@ -485,12 +485,13 @@
         QString maxGuestSize = vboxGlobal().settings().publicProperty("GUI/MaxGuestResolution");
         if ((maxGuestSize == QString::null) || (maxGuestSize == "auto"))
-            setMaxGuestSizePolicy(MaxGuestSizePolicy_Automatic, 0, 0);
+            m_maxGuestSizePolicy = MaxGuestSizePolicy_Automatic;
         else if (maxGuestSize == "any")
-            setMaxGuestSizePolicy(MaxGuestSizePolicy_Any, 0, 0);
+            m_maxGuestSizePolicy = MaxGuestSizePolicy_Any;
         else  /** @todo Mea culpa, but what about error checking? */
         {
             int width  = maxGuestSize.section(',', 0, 0).toInt();
             int height = maxGuestSize.section(',', 1, 1).toInt();
-            setMaxGuestSizePolicy(MaxGuestSizePolicy_Fixed, width, height);
+            m_maxGuestSizePolicy = MaxGuestSizePolicy_Fixed;
+            m_fixedMaxGuestSize = QSize(width, height);
         }
     }
@@ -597,5 +598,5 @@
 }
 
-QSize UIMachineView::maxGuestSize() const
+void UIMachineView::setMaxGuestSize()
 {
     QSize maxSize;
@@ -603,16 +604,25 @@
     {
         case MaxGuestSizePolicy_Fixed:
+            maxSize = m_fixedMaxGuestSize;
+            break;
         case MaxGuestSizePolicy_Automatic:
-            maxSize = QSize(qMax(m_fixedMaxGuestSize.width(), m_storedGuestHintSize.width()),
-                             qMax(m_fixedMaxGuestSize.height(), m_storedGuestHintSize.height()));
+            maxSize = calculateMaxGuestSize();
             break;
         case MaxGuestSizePolicy_Any:
+        default:
+            AssertMsg(m_maxGuestSizePolicy == MaxGuestSizePolicy_Any,
+                      ("Invalid maximum guest size policy %d!\n",
+                       m_maxGuestSizePolicy));
+            /* (0, 0) means any of course. */
             maxSize = QSize(0, 0);
-            break;
-        default:
-            AssertMsgFailed(("Invalid maximum guest size policy %d!\n",
-                             m_maxGuestSizePolicy));
-    }
-    return maxSize;
+    }
+    ASMAtomicWriteU64(&m_u64MaxGuestSize,
+                      RT_MAKE_U64(maxSize.width(), maxSize.height()));
+}
+
+QSize UIMachineView::maxGuestSize()
+{
+    uint64_t u64Size = ASMAtomicReadU64(&m_u64MaxGuestSize);
+    return QSize(int(RT_HI_U32(u64Size)), int(RT_LO_U32(u64Size)));
 }
 
@@ -650,39 +660,4 @@
     /* Return result: */
     return sizeHint;
-}
-
-void UIMachineView::setMaxGuestSizePolicy(MaxGuestSizePolicy policy, int cwMax,
-                                          int chMax)
-{
-    switch (policy)
-    {
-        case MaxGuestSizePolicy_Fixed:
-            m_maxGuestSizePolicy = MaxGuestSizePolicy_Fixed;
-            if (cwMax != 0 && chMax != 0)
-                m_fixedMaxGuestSize = QSize(cwMax, chMax);
-            else
-                m_fixedMaxGuestSize = QSize(0, 0);
-            storeHintForGuestSizePolicy(0, 0);
-            break;
-        case MaxGuestSizePolicy_Automatic:
-            m_maxGuestSizePolicy = MaxGuestSizePolicy_Automatic;
-            m_fixedMaxGuestSize = QSize(0, 0);
-            storeHintForGuestSizePolicy(0, 0);
-            break;
-        case MaxGuestSizePolicy_Any:
-            m_maxGuestSizePolicy = MaxGuestSizePolicy_Any;
-            m_fixedMaxGuestSize = QSize(0, 0);
-            break;
-        default:
-            AssertMsgFailed(("Invalid maximum guest size policy %d\n",
-                             policy));
-            m_maxGuestSizePolicy = MaxGuestSizePolicy_Invalid;
-    }
-}
-
-void UIMachineView::storeHintForGuestSizePolicy(int cWidth, int cHeight)
-{
-    if (m_maxGuestSizePolicy == MaxGuestSizePolicy_Automatic)
-        m_storedGuestHintSize = QSize(cWidth, cHeight);
 }
 
@@ -892,9 +867,4 @@
     /* Report to the VM thread that we finished resizing: */
     session().GetConsole().GetDisplay().ResizeCompleted(screenId());
-
-    /* We also recalculate the maximum guest size if necessary.  In fact we
-     * only need this on the first resize, but it is done every time to keep
-     * the code simpler. */
-    calculateMaxGuestSize();
 
     /* Emit a signal about guest was resized: */
@@ -1009,4 +979,8 @@
 {
     updateSliders();
+    /* We call this on every resize as on X11 it sets information which becomes
+     * available asynchronously at an unknown time after window creation.  As
+     * long as the information is not available we make a best guess. */
+    setMaxGuestSize();
     return QAbstractScrollArea::resizeEvent(pEvent);
 }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 39023)
@@ -135,16 +135,11 @@
     UIFrameBuffer* frameBuffer() const { return m_pFrameBuffer; }
     const QPixmap& pauseShot() const { return m_pauseShot; }
-    /** Helper to retrieve the last non-fullscreen guest size hint
-     * sent.  @note Currently unused. */
-    QSize storedGuestHintSize() const { return m_storedGuestHintSize; }
-    /** What policy are we currently applying for limiting guest
-     * resolutions? */
-    MaxGuestSizePolicy maxGuestSizePolicy() const
-    { return m_maxGuestSizePolicy; }
-    /** The maximum guest resolution which we currently wish to handle.
-     * @note This must be safely called from another thread.
-     * @todo So make it atomic.
-     */
-    QSize maxGuestSize() const;
+    /** Atomically store the maximum guest resolution which we currently wish
+     * to handle for @a maxGuestSize() to read. */
+    void setMaxGuestSize();
+    /** Atomically read the maximum guest resolution which we currently wish to
+     * handle.  This may safely be called from another thread (called by
+     * UIFramebuffer on EMT). */
+    QSize maxGuestSize();
     /** Retrieve the last non-fullscreen guest size hint (from extra data).
      */
@@ -152,7 +147,6 @@
 
     /* Protected setters: */
-    void setMaxGuestSizePolicy(MaxGuestSizePolicy policy, int cwMax,
-                               int chMax);
-    void storeHintForGuestSizePolicy(int cWidth, int cHeight);
+    /** Store a guest size hint value to extra data, called on switching to
+     * fullscreen. */
     void storeGuestSizeHint(const QSize &sizeHint);
 
@@ -165,5 +159,5 @@
     /** Calculate how big the guest desktop can be while still fitting on one
      * host screen. */
-    virtual void calculateMaxGuestSize() = 0;
+    virtual QSize calculateMaxGuestSize() const = 0;
     virtual void maybeRestrictMinimumSize() = 0;
     virtual void updateSliders();
@@ -204,12 +198,13 @@
     KMachineState m_previousState;
 
-    /** The policy for calculating the maximum guest resolution we wish to
-     * support. */
+    /** The policy for calculating the maximum guest resolution which we wish
+     * to handle. */
     MaxGuestSizePolicy m_maxGuestSizePolicy;
     /** The maximum guest size for fixed size policy. */
     QSize m_fixedMaxGuestSize;
-    /** The last guest size hint sent out, used for calculating the maximum
-     * supported guest resolution. */
-    QSize m_storedGuestHintSize;
+    /** Maximum guest resolution which we wish to handle.  Must be accessed
+     * atomically. */
+    /** @todo This should be private. */
+    volatile uint64_t m_u64MaxGuestSize;
 
 #ifdef VBOX_WITH_VIDEOHWACCEL
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp	(revision 39023)
@@ -95,6 +95,5 @@
 void UIMachineViewFullscreen::sltDesktopResized()
 {
-    /* Recalculate the maximum guest size if necessary. */
-    calculateMaxGuestSize();
+
 }
 
@@ -205,11 +204,7 @@
 }
 
-void UIMachineViewFullscreen::calculateMaxGuestSize()
-{
-    /* This method should not get called until we have initially set up the desktop geometry type: */
-    Assert((maxGuestSizePolicy() != MaxGuestSizePolicy_Invalid));
-    /* If we are not doing automatic adjustment then there is nothing to do. */
-    if (maxGuestSizePolicy() == MaxGuestSizePolicy_Automatic)
-        m_fixedMaxGuestSize = workingArea().size();
+QSize UIMachineViewFullscreen::calculateMaxGuestSize() const
+{
+    return workingArea().size();
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.h	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.h	(revision 39023)
@@ -71,5 +71,5 @@
     void normalizeGeometry(bool /* fAdjustPosition */) {}
     QRect workingArea() const;
-    void calculateMaxGuestSize();
+    QSize calculateMaxGuestSize() const;
     void maybeRestrictMinimumSize();
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp	(revision 39023)
@@ -98,6 +98,5 @@
 void UIMachineViewNormal::sltDesktopResized()
 {
-    /* Recalculate the maximum guest size if necessary. */
-    calculateMaxGuestSize();
+
 }
 
@@ -304,28 +303,19 @@
 }
 
-void UIMachineViewNormal::calculateMaxGuestSize()
-{
-    /* This method should not get called until we have initially set up the
-     * maximum guest size policy. */
-    Assert((maxGuestSizePolicy() != MaxGuestSizePolicy_Invalid));
-    /* If we are not doing automatic adjustment then there is nothing to do. */
-    if (maxGuestSizePolicy() == MaxGuestSizePolicy_Automatic)
-    {
-        /* The area taken up by the machine window on the desktop,
-         * including window frame, title, menu bar and status bar: */
-        QRect windowGeo = machineWindowWrapper()->machineWindow()->frameGeometry();
-        /* The area taken up by the machine central widget, so excluding all decorations: */
-        QRect centralWidgetGeo = static_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->centralWidget()->geometry();
-        /* To work out how big we can make the console window while still fitting on the desktop,
-         * we calculate workingArea() - (windowGeo - centralWidgetGeo).
-         * This works because the difference between machine window and machine central widget
-         * (or at least its width and height) is a constant. */
-        m_fixedMaxGuestSize = QSize(  workingArea().width()
-                                    - (windowGeo.width()
-                                    - centralWidgetGeo.width()),
-                                      workingArea().height()
-                                    - (windowGeo.height()
-                                    - centralWidgetGeo.height()));
-    }
+QSize UIMachineViewNormal::calculateMaxGuestSize() const
+{
+    /* The area taken up by the machine window on the desktop,
+     * including window frame, title, menu bar and status bar: */
+    QRect windowGeo = machineWindowWrapper()->machineWindow()->frameGeometry();
+    /* The area taken up by the machine central widget, so excluding all decorations: */
+    QRect centralWidgetGeo = static_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->centralWidget()->geometry();
+    /* To work out how big we can make the console window while still fitting on the desktop,
+     * we calculate workingArea() - (windowGeo - centralWidgetGeo).
+     * This works because the difference between machine window and machine central widget
+     * (or at least its width and height) is a constant. */
+    return QSize(  workingArea().width()
+                 - (windowGeo.width() - centralWidgetGeo.width()),
+                   workingArea().height()
+                 - (windowGeo.height() - centralWidgetGeo.height()));
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h	(revision 39023)
@@ -80,5 +80,5 @@
     void normalizeGeometry(bool fAdjustPosition);
     QRect workingArea() const;
-    void calculateMaxGuestSize();
+    QSize calculateMaxGuestSize() const;
     void maybeRestrictMinimumSize();
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.cpp	(revision 39023)
@@ -154,6 +154,5 @@
 void UIMachineViewScale::sltDesktopResized()
 {
-    /* Recalculate the maximum guest size if necessary. */
-    calculateMaxGuestSize();
+
 }
 
@@ -185,9 +184,4 @@
             /* Report to the VM thread that we finished resizing: */
             session().GetConsole().GetDisplay().ResizeCompleted(screenId());
-
-            /* We also recalculate the maximum guest size if necessary.  In
-             * fact we only need this on the first resize, but it is done
-             * every time to keep the code simpler. */
-            calculateMaxGuestSize();
 
             /* Emit a signal about guest was resized: */
@@ -368,28 +362,19 @@
 }
 
-void UIMachineViewScale::calculateMaxGuestSize()
-{
-    /* This method should not get called until we have initially set up the
-     * maximum guest size policy. */
-    Assert((maxGuestSizePolicy() != MaxGuestSizePolicy_Invalid));
-    /* If we are not doing automatic adjustment then there is nothing to do. */
-    if (maxGuestSizePolicy() == MaxGuestSizePolicy_Automatic)
-    {
-        /* The area taken up by the machine window on the desktop,
-         * including window frame, title, menu bar and status bar: */
-        QRect windowGeo = machineWindowWrapper()->machineWindow()->frameGeometry();
-        /* The area taken up by the machine central widget, so excluding all decorations: */
-        QRect centralWidgetGeo = static_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->centralWidget()->geometry();
-        /* To work out how big we can make the console window while still fitting on the desktop,
-         * we calculate workingArea() - (windowGeo - centralWidgetGeo).
-         * This works because the difference between machine window and machine central widget
-         * (or at least its width and height) is a constant. */
-        m_fixedMaxGuestSize = QSize(  workingArea().width()
-                                    - (windowGeo.width()
-                                    - centralWidgetGeo.width()),
-                                      workingArea().height()
-                                    - (windowGeo.height()
-                                    - centralWidgetGeo.height()));
-    }
+QSize UIMachineViewScale::calculateMaxGuestSize() const
+{
+    /* The area taken up by the machine window on the desktop,
+     * including window frame, title, menu bar and status bar: */
+    QRect windowGeo = machineWindowWrapper()->machineWindow()->frameGeometry();
+    /* The area taken up by the machine central widget, so excluding all decorations: */
+    QRect centralWidgetGeo = static_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->centralWidget()->geometry();
+    /* To work out how big we can make the console window while still fitting on the desktop,
+     * we calculate workingArea() - (windowGeo - centralWidgetGeo).
+     * This works because the difference between machine window and machine central widget
+     * (or at least its width and height) is a constant. */
+    return QSize(  workingArea().width()
+                 - (windowGeo.width() - centralWidgetGeo.width()),
+                   workingArea().height()
+                 - (windowGeo.height() - centralWidgetGeo.height()));
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.h	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineViewScale.h	(revision 39023)
@@ -72,5 +72,5 @@
     void normalizeGeometry(bool /* fAdjustPosition */) {}
     QRect workingArea() const;
-    void calculateMaxGuestSize();
+    QSize calculateMaxGuestSize() const;
     void maybeRestrictMinimumSize() {}
     void updateSliders();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp	(revision 39023)
@@ -101,7 +101,4 @@
      *        I don't think that it is the GUI's job to check that
      *        the resize succeeded though. */
-
-    /* Recalculate the maximum guest size if necessary. */
-    calculateMaxGuestSize();
 }
 
@@ -227,11 +224,7 @@
 }
 
-void UIMachineViewSeamless::calculateMaxGuestSize()
-{
-    /* This method should not get called until we have initially set up the desktop geometry type: */
-    Assert((maxGuestSizePolicy() != MaxGuestSizePolicy_Invalid));
-    /* If we are not doing automatic adjustment then there is nothing to do. */
-    if (maxGuestSizePolicy() == MaxGuestSizePolicy_Automatic)
-        m_fixedMaxGuestSize = workingArea().size();
-}
-
+QSize UIMachineViewSeamless::calculateMaxGuestSize() const
+{
+    return workingArea().size();
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.h	(revision 39022)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.h	(revision 39023)
@@ -75,5 +75,5 @@
     void normalizeGeometry(bool /* fAdjustPosition */) {}
     QRect workingArea() const;
-    void calculateMaxGuestSize();
+    QSize calculateMaxGuestSize() const;
     void maybeRestrictMinimumSize() {}
 
