VirtualBox

Changeset 64334 in vbox for trunk


Ignore:
Timestamp:
Oct 20, 2016 2:43:06 PM (8 years ago)
Author:
vboxsync
Message:

bugref:8631: FE/Qt: resizing problems with tiled window managers: when the Qt method setGeometry() resizes a window it assumes that the operation will succeed, notably resizing all sub-windows too. With top-level windows on X11 the window manager may decide to override the size requested, and tiled window managers often do. To handle this, we do the resize using X11 functionality without telling Qt and let Qt find out from the resize event like for user-triggered resizes.

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp

    r62493 r64334  
    194194    QRect geo (QPoint (0, 0), initSize);
    195195    geo.moveCenter (parentWidget()->geometry().center());
    196     setGeometry (geo);
     196    VBoxGlobal::setTopLevelGeometry(this, geo);
    197197
    198198    retranslateUi();
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIMainWindow.cpp

    r63293 r64334  
    2222/* GUI includes: */
    2323# include "QIMainWindow.h"
     24# include "VBoxGlobal.h"
    2425
    2526#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
     
    3940#else /* VBOX_WS_MAC */
    4041    /* Use the new approach for Windows/X11: */
    41     setGeometry(m_geometry);
     42    VBoxGlobal::setTopLevelGeometry(this, m_geometry);
    4243#endif /* !VBOX_WS_MAC */
    4344
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp

    r64211 r64334  
    5050# if defined(VBOX_WS_X11) && QT_VERSION >= 0x050000
    5151#  include <QScreen>
     52#  include <xcb/xcb.h>
     53#  include <xcb/xcb_icccm.h>
    5254# endif /* VBOX_WS_X11 && QT_VERSION >= 0x050000 */
    5355
     
    37033705}
    37043706
     3707/* static */
     3708void VBoxGlobal::setTopLevelGeometry(QWidget *pWidget, int x, int y, int w, int h)
     3709{
     3710#if defined(VBOX_WS_X11) && QT_VERSION >= 0x050000
     3711# define QWINDOWSIZE_MAX ((1<<24)-1)
     3712    if (pWidget->isWindow() && pWidget->isVisible())
     3713    {
     3714        /* X11 window managers are not required to accept geometry changes on
     3715         * the top-level window.  Unfortunately, current at Qt 5.6 and 5.7, Qt
     3716         * assumes that the change will succeed, and resizes all sub-windows
     3717         * unconditionally.  By calling ConfigureWindow directly, Qt will see
     3718         * our change request as an externally triggered one on success and not
     3719         * at all if it is rejected. */
     3720        uint16_t fMask =   XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
     3721                         | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
     3722        uint32_t values[] = { (uint32_t)x, (uint32_t)y, (uint32_t)w, (uint32_t)h };
     3723        xcb_configure_window(QX11Info::connection(), (xcb_window_t)pWidget->winId(),
     3724                             fMask, values);
     3725        xcb_size_hints_t hints;
     3726        hints.flags = XCB_ICCCM_SIZE_HINT_US_POSITION | XCB_ICCCM_SIZE_HINT_US_SIZE;
     3727        hints.x          = x;
     3728        hints.y          = y;
     3729        hints.width      = w;
     3730        hints.height     = h;
     3731        hints.min_width  = pWidget->minimumSize().width();
     3732        hints.min_height = pWidget->minimumSize().height();
     3733        hints.max_width  = pWidget->maximumSize().width();
     3734        hints.max_height = pWidget->maximumSize().height();
     3735        if (hints.min_width > 0 || hints.min_height > 0)
     3736            hints.flags |= XCB_ICCCM_SIZE_HINT_P_MIN_SIZE;
     3737        if (hints.max_width < QWINDOWSIZE_MAX || hints.max_height < QWINDOWSIZE_MAX)
     3738            hints.flags |= XCB_ICCCM_SIZE_HINT_P_MAX_SIZE;
     3739        xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE,
     3740                            (xcb_window_t)pWidget->winId(), XCB_ATOM_WM_NORMAL_HINTS,
     3741                            XCB_ATOM_WM_SIZE_HINTS, 32, sizeof(hints) >> 2, &hints);
     3742        xcb_flush(QX11Info::connection());
     3743    }
     3744    else
     3745        /* Call the Qt method if the window is not visible as otherwise no
     3746         * Configure event will arrive to tell Qt what geometry we want. */
     3747        pWidget->setGeometry(x, y, w, h);
     3748# else
     3749    pWidget->setGeometry(x, y, w, h);
     3750# endif
     3751}
     3752
     3753/* static */
     3754void VBoxGlobal::setTopLevelGeometry(QWidget *pWidget, const QRect &rect)
     3755{
     3756    VBoxGlobal::setTopLevelGeometry(pWidget, rect.x(), rect.y(), rect.width(), rect.height());
     3757}
     3758
    37053759// Public slots
    37063760////////////////////////////////////////////////////////////////////////////////
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h

    r64160 r64334  
    442442     * to strict the minimum width to reflect at least [n] symbols. */
    443443    static void setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount);
     444
     445    /** Assigns top-level @a pWidget geometry passed as QRect coordinates.
     446      * @note  Take into account that this request may fail on X11. */
     447    static void setTopLevelGeometry(QWidget *pWidget, int x, int y, int w, int h);
     448    /** Assigns top-level @a pWidget geometry passed as @a rect.
     449      * @note  Take into account that this request may fail on X11. */
     450    static void setTopLevelGeometry(QWidget *pWidget, const QRect &rect);
    444451
    445452signals:
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISlidingToolBar.cpp

    r62493 r64334  
    140140        case Position_Top:
    141141        {
    142             setGeometry(m_parentRect.x(), m_parentRect.y()                         + m_indentRect.height(),
    143                         qMax(m_parentRect.width(), sh.width()), sh.height());
     142            VBoxGlobal::setTopLevelGeometry(this, m_parentRect.x(), m_parentRect.y()                         + m_indentRect.height(),
     143                                                  qMax(m_parentRect.width(), sh.width()), sh.height());
    144144            m_pEmbeddedWidget->setGeometry(0, -sh.height(), qMax(width(), sh.width()), sh.height());
    145145            break;
     
    147147        case Position_Bottom:
    148148        {
    149             setGeometry(m_parentRect.x(), m_parentRect.y() + m_parentRect.height() - m_indentRect.height() - sh.height(),
    150                         qMax(m_parentRect.width(), sh.width()), sh.height());
     149            VBoxGlobal::setTopLevelGeometry(this, m_parentRect.x(), m_parentRect.y() + m_parentRect.height() - m_indentRect.height() - sh.height(),
     150                                                  qMax(m_parentRect.width(), sh.width()), sh.height());
    151151            m_pEmbeddedWidget->setGeometry(0,  sh.height(), qMax(width(), sh.width()), sh.height());
    152152            break;
     
    197197        case Position_Top:
    198198        {
    199             setGeometry(m_parentRect.x(), m_parentRect.y()                         + m_indentRect.height(),
    200                         qMax(m_parentRect.width(), sh.width()), sh.height());
     199            VBoxGlobal::setTopLevelGeometry(this, m_parentRect.x(), m_parentRect.y()                         + m_indentRect.height(),
     200                                                  qMax(m_parentRect.width(), sh.width()), sh.height());
    201201            break;
    202202        }
    203203        case Position_Bottom:
    204204        {
    205             setGeometry(m_parentRect.x(), m_parentRect.y() + m_parentRect.height() - m_indentRect.height() - sh.height(),
    206                         qMax(m_parentRect.width(), sh.width()), sh.height());
     205            VBoxGlobal::setTopLevelGeometry(this, m_parentRect.x(), m_parentRect.y() + m_parentRect.height() - m_indentRect.height() - sh.height(),
     206                                                  qMax(m_parentRect.width(), sh.width()), sh.height());
    207207            break;
    208208        }
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp

    r63054 r64334  
    351351        /* Move window to the center of working-area: */
    352352        geo.moveCenter(workingArea.center());
    353         setGeometry(geo);
     353        VBoxGlobal::setTopLevelGeometry(this, geo);
    354354    }
    355355
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp

    r63228 r64334  
    372372                /* Restore window geometry: */
    373373                m_normalGeometry = geo;
    374                 setGeometry(m_normalGeometry);
     374                VBoxGlobal::setTopLevelGeometry(this, m_normalGeometry);
    375375            }
    376376            /* If previous machine-state was NOT SAVED: */
     
    379379                /* Restore only window position: */
    380380                m_normalGeometry = QRect(geo.x(), geo.y(), width(), height());
    381                 setGeometry(m_normalGeometry);
     381                VBoxGlobal::setTopLevelGeometry(this, m_normalGeometry);
    382382                /* And normalize to the optimal-size: */
    383383                normalizeGeometry(false /* adjust position */);
     
    401401            m_normalGeometry = geometry();
    402402            m_normalGeometry.moveCenter(availableGeo.center());
    403             setGeometry(m_normalGeometry);
     403            VBoxGlobal::setTopLevelGeometry(this, m_normalGeometry);
    404404        }
    405405
     
    575575
    576576    /* Finally, set the frame geometry: */
    577     setGeometry(frGeo.left() + dl, frGeo.top() + dt,
    578                 frGeo.width() - dl - dr, frGeo.height() - dt - db);
     577    VBoxGlobal::setTopLevelGeometry(this, frGeo.left() + dl, frGeo.top() + dt,
     578                                    frGeo.width() - dl - dr, frGeo.height() - dt - db);
    579579#else /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    580580    /* Customer request: There should no be
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp

    r63230 r64334  
    102102            /* Restore window geometry: */
    103103            m_normalGeometry = geo;
    104             setGeometry(m_normalGeometry);
     104            VBoxGlobal::setTopLevelGeometry(this, m_normalGeometry);
    105105
    106106            /* Maximize (if necessary): */
     
    121121            m_normalGeometry = geometry();
    122122            m_normalGeometry.moveCenter(availableGeo.center());
    123             setGeometry(m_normalGeometry);
     123            VBoxGlobal::setTopLevelGeometry(this, m_normalGeometry);
    124124        }
    125125
     
    202202
    203203    /* Finally, set the frame geometry: */
    204     setGeometry(frGeo.left() + dl, frGeo.top() + dt,
    205                 frGeo.width() - dl - dr, frGeo.height() - dt - db);
     204    VBoxGlobal::setTopLevelGeometry(this, frGeo.left() + dl, frGeo.top() + dt,
     205                                    frGeo.width() - dl - dr, frGeo.height() - dt - db);
    206206#else /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    207207    /* Customer request: There should no be
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupStack.cpp

    r63315 r64334  
    2828
    2929/* GUI includes: */
     30# include "VBoxGlobal.h"
    3031# include "UIPopupStack.h"
    3132# include "UIPopupStackViewport.h"
     
    167168
    168169    /* Adjust geometry: */
    169     setGeometry(iX, iY, iWidth, iHeight);
     170    VBoxGlobal::setTopLevelGeometry(this, iX, iY, iWidth, iHeight);
    170171}
    171172
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette