Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 16175)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 16176)
@@ -900,6 +900,9 @@
     static void setTextLabel (QToolButton *aToolButton, const QString &aTextLabel);
 
-    static QRect normalizeGeometry (const QRect &aRect, const QRect &aBoundRect,
+    static QRect normalizeGeometry (const QRect &aRectangle, const QRegion &aBoundRegion,
                                     bool aCanResize = true);
+    static QRect getNormalized (const QRect &aRectangle, const QRegion &aBoundRegion,
+                                bool aCanResize = true);
+    static QRegion flip (const QRegion &aRegion);
 
     static void centerWidget (QWidget *aWidget, QWidget *aRelative,
Index: /trunk/src/VBox/Frontends/VirtualBox/src/QIDialog.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/QIDialog.cpp	(revision 16175)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/QIDialog.cpp	(revision 16176)
@@ -58,5 +58,5 @@
     /* Explicit widget centering relatively to it's parent
      * if any or desktop if parent is missed. */
-    vboxGlobal().centerWidget (this, parentWidget(), false);
+    VBoxGlobal::centerWidget (this, parentWidget(), false);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/QIMainDialog.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/QIMainDialog.cpp	(revision 16175)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/QIMainDialog.cpp	(revision 16176)
@@ -226,5 +226,5 @@
     /* Explicit widget centering relatively to it's centering
      * widget if any or desktop if centering widget is missed. */
-    vboxGlobal().centerWidget (this, mCenterWidget, false);
+    VBoxGlobal::centerWidget (this, mCenterWidget, false);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 16175)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 16176)
@@ -973,5 +973,14 @@
     if (adjustPosition)
     {
-        QRect ar = QApplication::desktop()->availableGeometry (tlw->pos());
+        QRegion ar;
+        QDesktopWidget *dwt = QApplication::desktop();
+        if (dwt->isVirtualDesktop())
+            /* Compose complex available region */
+            for (int i = 0; i < dwt->numScreens(); ++ i)
+                ar += dwt->availableGeometry (i);
+        else
+            /* Get just a simple available rectangle */
+            ar = dwt->availableGeometry (tlw->pos());
+
         fr = VBoxGlobal::normalizeGeometry (
             fr, ar, mode != VBoxDefs::SDLMode /* canResize */);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 16175)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 16176)
@@ -793,13 +793,9 @@
             max = str.section (',', 4, 4) == VBoxDefs::GUI_LastWindowPosition_Max;
 
-        QRect ar = QApplication::desktop()->availableGeometry (QPoint (x, y));
-        if (ok)
-        {
-            /* Do some position checks */
-            if (x < ar.left() || x > ar.right())
-                x = ar.left();
-            if (y < ar.top() || y > ar.bottom())
-                y = ar.top();
-
+        QRect ar = ok ? QApplication::desktop()->availableGeometry (QPoint (x, y)) :
+                        QApplication::desktop()->availableGeometry (this);
+
+        if (ok /* previous parameters were read correctly */)
+        {
             mNormalGeo = QRect (x, y, w, h);
             setGeometry (mNormalGeo);
@@ -807,4 +803,11 @@
             /* Normalize to the optimal size */
             console->normalizeGeometry (true /* adjustPosition */);
+
+            if (max)
+            {
+                /* Maximize if needed */
+                setWindowState (windowState() | Qt::WindowMaximized);
+                was_max = max;
+            }
         }
         else
@@ -819,8 +822,4 @@
         }
 
-        /* Maximize if needed */
-        if (max)
-            setWindowState (windowState() | Qt::WindowMaximized);
-        was_max = max;
         show();
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 16175)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 16176)
@@ -48,4 +48,6 @@
 #include <QThread>
 #include <QPainter>
+
+#include <math.h>
 
 #ifdef Q_WS_X11
@@ -3815,38 +3817,148 @@
 
 /**
- *  Ensures that the given rectangle \a aRect is fully contained within the
- *  rectangle \a aBoundRect by moving \a aRect if necessary. If \a aRect is
- *  larger than \a aBoundRect, its top left corner is simply aligned with the
- *  top left corner of \a aRect and, if \a aCanResize is true, \a aRect is
- *  shrinked to become fully visible.
+ *  Performs direct and flipped search of position for \a aRectangle to make sure
+ *  it is fully contained inside \a aBoundRegion region by moving & resizing
+ *  \a aRectangle if necessary. Selects the minimum shifted result between direct
+ *  and flipped variants.
  */
 /* static */
-QRect VBoxGlobal::normalizeGeometry (const QRect &aRect, const QRect &aBoundRect,
+QRect VBoxGlobal::normalizeGeometry (const QRect &aRectangle, const QRegion &aBoundRegion,
                                      bool aCanResize /* = true */)
 {
-    QRect fr = aRect;
-
-    /* make the bottom right corner visible */
-    int rd = aBoundRect.right() - fr.right();
-    int bd = aBoundRect.bottom() - fr.bottom();
-    fr.translate (rd < 0 ? rd : 0, bd < 0 ? bd : 0);
-
-    /* ensure the top left corner is visible */
-    int ld = fr.left() - aBoundRect.left();
-    int td = fr.top() - aBoundRect.top();
-    fr.translate (ld < 0 ? -ld : 0, td < 0 ? -td : 0);
-
-    if (aCanResize)
-    {
-        /* adjust the size to make the rectangle fully contained */
-        rd = aBoundRect.right() - fr.right();
-        bd = aBoundRect.bottom() - fr.bottom();
-        if (rd < 0)
-            fr.setRight (fr.right() + rd);
-        if (bd < 0)
-            fr.setBottom (fr.bottom() + bd);
-    }
-
-    return fr;
+    /* Direct search for normalized rectangle */
+    QRect var1 (getNormalized (aRectangle, aBoundRegion, aCanResize));
+
+    /* Flipped search for normalized rectangle */
+    QRect var2 (flip (getNormalized (flip (aRectangle).boundingRect(),
+                                     flip (aBoundRegion), aCanResize)).boundingRect());
+
+    /* Calculate shift from starting position for both variants */
+    double length1 = sqrt (pow (var1.x() - aRectangle.x(), 2) +
+                           pow (var1.y() - aRectangle.y(), 2));
+    double length2 = sqrt (pow (var2.x() - aRectangle.x(), 2) +
+                           pow (var2.y() - aRectangle.y(), 2));
+
+    /* Return minimum shifted variant */
+    return length1 > length2 ? var2 : var1;
+}
+
+/**
+ *  Ensures that the given rectangle \a aRectangle is fully contained within the
+ *  region \a aBoundRegion by moving \a aRectangle if necessary. If \a aRectangle is
+ *  larger than \a aBoundRegion, top left corner of \a aRectangle is aligned with the
+ *  top left corner of maximum available rectangle and, if \a aCanResize is true,
+ *  \a aRectangle is shrinked to become fully visible.
+ */
+/* static */
+QRect VBoxGlobal::getNormalized (const QRect &aRectangle, const QRegion &aBoundRegion,
+                                 bool aCanResize /* = true */)
+{
+    /* Storing available horizontal sub-rectangles & vertical shifts */
+    int windowVertical = aRectangle.center().y();
+    QVector <QRect> rectanglesVector (aBoundRegion.rects());
+    QList <QRect> rectanglesList;
+    QList <int> shiftsList;
+    foreach (QRect currentItem, rectanglesVector)
+    {
+        int currentDelta = qAbs (windowVertical - currentItem.center().y());
+        int shift2Top = currentItem.top() - aRectangle.top();
+        int shift2Bot = currentItem.bottom() - aRectangle.bottom();
+
+        int itemPosition = 0;
+        foreach (QRect item, rectanglesList)
+        {
+            int delta = qAbs (windowVertical - item.center().y());
+            if (delta > currentDelta) break; else ++ itemPosition;
+        }
+        rectanglesList.insert (itemPosition, currentItem);
+
+        int shift2TopPos = 0;
+        foreach (int shift, shiftsList)
+            if (qAbs (shift) > qAbs (shift2Top)) break; else ++ shift2TopPos;
+        shiftsList.insert (shift2TopPos, shift2Top);
+
+        int shift2BotPos = 0;
+        foreach (int shift, shiftsList)
+            if (qAbs (shift) > qAbs (shift2Bot)) break; else ++ shift2BotPos;
+        shiftsList.insert (shift2BotPos, shift2Bot);
+    }
+
+    /* Trying to find the appropriate place for window */
+    QRect result;
+    for (int i = -1; i < shiftsList.size(); ++ i)
+    {
+        /* Move to appropriate vertical */
+        QRect rectangle (aRectangle);
+        if (i >= 0) rectangle.translate (0, shiftsList [i]);
+
+        /* Search horizontal shift */
+        int maxShift = 0;
+        foreach (QRect item, rectanglesList)
+        {
+            QRect trectangle (rectangle.translated (item.left() - rectangle.left(), 0));
+            if (!item.intersects (trectangle))
+                continue;
+
+            if (rectangle.left() < item.left())
+            {
+                int shift = item.left() - rectangle.left();
+                maxShift = qAbs (shift) > qAbs (maxShift) ? shift : maxShift;
+            }
+            else if (rectangle.right() > item.right())
+            {
+                int shift = item.right() - rectangle.right();
+                maxShift = qAbs (shift) > qAbs (maxShift) ? shift : maxShift;
+            }
+        }
+
+        /* Shift across the horizontal direction */
+        rectangle.translate (maxShift, 0);
+
+        /* Check the translated rectangle to feat the rules */
+        if (aBoundRegion.united (rectangle) == aBoundRegion)
+            result = rectangle;
+
+        if (!result.isNull()) break;
+    }
+
+    if (result.isNull())
+    {
+        /* Resize window to feat desirable size
+         * using max of available rectangles */
+        QRect maxRectangle;
+        quint64 maxSquare = 0;
+        foreach (QRect item, rectanglesList)
+        {
+            quint64 square = item.width() * item.height();
+            if (square > maxSquare)
+            {
+                maxSquare = square;
+                maxRectangle = item;
+            }
+        }
+
+        result = aRectangle;
+        result.moveTo (maxRectangle.x(), maxRectangle.y());
+        if (maxRectangle.right() < result.right())
+            result.setRight (maxRectangle.right());
+        if (maxRectangle.bottom() < result.bottom())
+            result.setBottom (maxRectangle.bottom());
+    }
+
+    return result;
+}
+
+/**
+ *  Returns the flipped (transposed) region.
+ */
+/* static */
+QRegion VBoxGlobal::flip (const QRegion &aRegion)
+{
+    QRegion result;
+    QVector <QRect> rectangles (aRegion.rects());
+    foreach (QRect rectangle, rectangles)
+        result += QRect (rectangle.y(), rectangle.x(),
+                         rectangle.height(), rectangle.width());
+    return result;
 }
 
