VirtualBox

Changeset 4514 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Sep 4, 2007 11:56:36 AM (17 years ago)
Author:
vboxsync
Message:

2223: Improve Visual Mode change:

  1. Definite resize mode integrated into Toggle Seamless/Fullscreen Mode Mechanism. This is resize-controlled mechanism to make sure the dialog will be resize only to awaited size (full/available-geometry during entering fullscreen/seamless and previous-geometry during exiting these modes) and not to any other.
  2. Guest resizing (if available) also performs just for the desired size, not for the size at the end of the resize-timer timeout (which could be any of incorrect value do to timing).
  3. Seamless mode exiting to maximize screen workaround for (at least) KDE (where the window manager thinks the seamless mode equal maximized window state).
Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h

    r4202 r4514  
    9191    void fixModifierState (LONG *codes, uint *count);
    9292
     93    void toggleFSMode (const QSize &aFeatSize);
     94
     95    void setIgnoreMainwndResize (bool aYes) { mIgnoreMainwndResize = aYes; }
     96
    9397signals:
    9498
     
    101105    void usbStateChange();
    102106    void sharedFoldersChanged();
     107    void resizeHintDone();
    103108
    104109protected:
     
    176181private slots:
    177182
    178     void exitFullScreen();
    179 
    180     void doResizeHint();
    181     void normalizeGeo() { normalizeGeometry (true); }
     183    void doResizeHint (const QSize &aSize = QSize());
    182184
    183185private:
     
    222224
    223225    QTimer *resize_hint_timer;
     226    QTimer *mToggleFSModeTimer;
    224227
    225228    VBoxDefs::RenderMode mode;
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h

    r4297 r4514  
    6969    bool isTrueSeamless() const { return mIsSeamless; }
    7070
     71    bool isManualResize() const { return mManualResize; }
     72
    7173    void setMouseIntegrationLocked (bool aDisabled);
    7274
     
    8587    // events
    8688    bool event (QEvent *e);
     89    void resizeEvent (QResizeEvent *e);
    8790    void closeEvent (QCloseEvent *e);
    8891#if defined(Q_WS_X11)
     
    180183    void dbgShowCommandLine();
    181184
     185    void onEnterFullscreen();
     186    void onExitFullscreen();
     187
    182188private:
    183189
     
    286292    QSize normal_size;
    287293    QSize prev_min_size;
     294    QSize mPrevSize;
     295    QSize mAwaitingSize;
    288296
    289297#ifdef Q_WS_WIN32
     
    292300
    293301    // variables for dealing with true fullscreen
     302    bool mDoMaximize : 1;
     303    bool mManualResize : 1;
     304    bool mAllowOneResize : 1;
    294305    bool mIsFullscreen : 1;
    295306    bool mIsSeamless : 1;
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r4297 r4514  
    650650             this, SLOT (doResizeHint()));
    651651
     652    mToggleFSModeTimer = new QTimer (this);
     653    connect (mToggleFSModeTimer, SIGNAL (timeout()),
     654             this, SIGNAL (resizeHintDone()));
     655
    652656    /* setup rendering */
    653657
     
    834838void VBoxConsoleView::normalizeGeometry (bool adjustPosition /* = false */)
    835839{
     840    /* Make no normalizeGeometry in case we are in manual resize
     841     * mode or main window is maximized */
     842    if (mainwnd->isManualResize() || mainwnd->isMaximized())
     843        return;
     844
    836845    QWidget *tlw = topLevelWidget();
    837846
     
    9951004                          re->width(), re->height(), re->bitsPerPixel()));
    9961005
     1006                if (mToggleFSModeTimer->isActive())
     1007                    mToggleFSModeTimer->stop();
     1008
    9971009                /* do frame buffer dependent resize */
    9981010                mFrameBuf->resizeEvent (re);
     
    10191031                QApplication::sendPostedEvents (0, QEvent::LayoutHint);
    10201032
    1021                 /* automatically normalize geometry unless maximized or
    1022                  * full screen */
    1023                 if (!mainwnd->isTrueFullscreen() &&
    1024                     !mainwnd->isTrueSeamless() &&
    1025                     !topLevelWidget()->isMaximized())
    1026                     normalizeGeometry (true /* adjustPosition */);
     1033                normalizeGeometry (true /* adjustPosition */);
    10271034
    10281035                /* report to the VM thread that we finished resizing */
     
    10301037
    10311038                mIgnoreMainwndResize = oldIgnoreMainwndResize;
     1039
     1040                /* emit a signal about guest was resized */
     1041                emit resizeHintDone();
    10321042
    10331043                return true;
     
    13871397            case QEvent::Resize:
    13881398            {
    1389                 if (!mIgnoreMainwndResize)
    1390                 {
    1391                     if (mIsAdditionsActive && mAutoresizeGuest)
    1392                         resize_hint_timer->start (300, TRUE);
    1393                     /// @todo disabled for the time being since seems to be not
    1394                     //  necessary anymore
    1395 #if 0
    1396                     /* During window maximization WindowStateChange event is
    1397                      * processed before Resize event, so the mIgnoreMainwndResize
    1398                      * variable should be set to true here in case of mainwnd is
    1399                      * maximized or in fullscreen state. */
    1400                     /* Not sure if it is really required */
    1401                     if (mainwnd->isMaximized() || mainwnd->isTrueFullscreen()
    1402                                                || mainwnd->isTrueSeamless())
    1403                         mIgnoreMainwndResize = true;
    1404 #endif
    1405                 }
     1399                if (!mIgnoreMainwndResize &&
     1400                    mIsAdditionsActive && mAutoresizeGuest)
     1401                    resize_hint_timer->start (300, TRUE);
    14061402                break;
    1407             }
    1408             case QEvent::WindowStateChange:
    1409             {
    1410                 /* The guest screen size (and therefore the contents size)
    1411                  * could have been changed while we were maximized or minimized,
    1412                  * so posting event for auto-resize and normalization. */
    1413                 if (!mainwnd->isMinimized() &&
    1414                     !mainwnd->isMaximized() &&
    1415                     !mainwnd->isTrueFullscreen() &&
    1416                     !mainwnd->isTrueSeamless())
    1417                     QTimer::singleShot (0, this, SLOT (exitFullScreen()));
    14181403            }
    14191404
     
    19661951
    19671952/**
    1968  *  Called on exit from fullscreen or from maximized mode.
     1953 *  Called on enter/exit seamless/fullscreen mode.
    19691954 */
    1970 void VBoxConsoleView::exitFullScreen()
     1955void VBoxConsoleView::toggleFSMode (const QSize &aResizeTo)
    19711956{
    19721957    if (mIsAdditionsActive && mAutoresizeGuest)
    1973     {
    1974         doResizeHint();
    1975         /* Fire a normalize event with some delay to let the guest process the
    1976          * resize hint and send resize properly, instead of normalizing to the
    1977          * current guest size right now. */
    1978         QTimer::singleShot (200, this, SLOT (normalizeGeo()));
    1979     }
    1980     else
    1981     {
    1982         normalizeGeo();
    1983     }
    1984 
    1985     mIgnoreMainwndResize = false;
     1958        doResizeHint (aResizeTo);
     1959    mToggleFSModeTimer->start (400, true);
    19861960}
    19871961
     
    27702744    // effect :), but at least it works with NT and W2k guests.
    27712745
    2772     // @TODO Sending 0xFE is responsible for the warning 
     2746    // @TODO Sending 0xFE is responsible for the warning
    27732747    //
    27742748    //         ``atkbd.c: Spurious NAK on isa0060/serio0. Some program might
     
    31623136}
    31633137
    3164 void VBoxConsoleView::doResizeHint()
     3138void VBoxConsoleView::doResizeHint (const QSize &aToSize)
    31653139{
    31663140    if (mIsAdditionsActive && mAutoresizeGuest)
    31673141    {
    3168         /* Get the available size for the guest display.
     3142        /* If this slot is invoked directly then use the passed size
     3143         * otherwise get the available size for the guest display.
    31693144         * We assume here that the centralWidget() contains this view only
    31703145         * and gives it all available space. */
    3171         QSize sz (mainwnd->centralWidget()->size());
     3146        QSize sz (aToSize.isValid() ? aToSize : mainwnd->centralWidget()->size());
    31723147        sz -= QSize (frameWidth() * 2, frameWidth() * 2);
    31733148        LogFlowFunc (("Will suggest %d x %d\n", sz.width(), sz.height()));
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp

    r4450 r4514  
    107107    , machine_state (CEnums::InvalidMachineState)
    108108    , no_auto_close (false)
     109    , mDoMaximize (false)
     110    , mManualResize (false)
     111    , mAllowOneResize (false)
    109112    , mIsFullscreen (false)
    110113    , mIsSeamless (false)
     
    975978}
    976979
     980/**
     981 *  This slot is called just after entering the fullscreen/seamless mode,
     982 *  when the console was resized to required size.
     983 */
     984void VBoxConsoleWnd::onEnterFullscreen()
     985{
     986    disconnect (console, SIGNAL (resizeHintDone()), 0, 0);
     987
     988    vmSeamlessAction->setEnabled (mIsSeamless);
     989    vmFullscreenAction->setEnabled (mIsFullscreen);
     990
     991    mAwaitingSize = mPrevSize;
     992}
     993
     994/**
     995 *  This slot is called just after leaving the fullscreen/seamless mode,
     996 *  when the console was resized to previous size.
     997 */
     998void VBoxConsoleWnd::onExitFullscreen()
     999{
     1000    disconnect (console, SIGNAL (resizeHintDone()), 0, 0);
     1001
     1002    vmSeamlessAction->setEnabled (mIsSeamlessSupported);
     1003    vmFullscreenAction->setEnabled (true);
     1004
     1005    mManualResize = false;
     1006    console->setIgnoreMainwndResize (false);
     1007    console->normalizeGeometry (true /* adjustPosition */);
     1008}
     1009
    9771010void VBoxConsoleWnd::setMouseIntegrationLocked (bool aDisabled)
    9781011{
     
    10241057        {
    10251058            QResizeEvent *re = (QResizeEvent *) e;
    1026             if (!mIsFullscreen && !mIsSeamless &&
     1059
     1060            /* do not process event if the resize events are blocked
     1061             * and the proposed size is not the awaited one */
     1062            if (mManualResize && !mAllowOneResize &&
     1063                re->size() != mAwaitingSize)
     1064                return false;
     1065
     1066            if (!mManualResize  &&
    10271067                (windowState() & (WindowMaximized | WindowMinimized |
    10281068                                  WindowFullScreen)) == 0)
     
    10331073#endif
    10341074            }
     1075            if (mManualResize && mAllowOneResize)
     1076                mAllowOneResize = false;
     1077
    10351078            break;
    10361079        }
    10371080        case QEvent::Move:
    10381081        {
    1039             if (!mIsFullscreen && !mIsSeamless &&
     1082            if (!mManualResize &&
    10401083                (windowState() & (WindowMaximized | WindowMinimized |
    10411084                                  WindowFullScreen)) == 0)
     
    10541097            break;
    10551098        }
     1099        case QEvent::WindowStateChange:
     1100        {
     1101            if (mDoMaximize)
     1102            {
     1103                /* this workaround is necessary due to KDE seems to be
     1104                 * thinks the seamless mode is maximized state */
     1105                mDoMaximize = false;
     1106                setWindowState (windowState() | WindowMaximized);
     1107            }
     1108        }
    10561109        default:
    10571110            break;
     
    10591112
    10601113    return QMainWindow::event (e);
     1114}
     1115
     1116void VBoxConsoleWnd::resizeEvent (QResizeEvent *aEvent)
     1117{
     1118    if (aEvent->size() == mAwaitingSize)
     1119    {
     1120        /* this resize was done to awaited size, so
     1121         * let the guest to be resized to this size too */
     1122        mAwaitingSize = QSize();
     1123        console->toggleFSMode (centralWidget()->size());
     1124    }
     1125
     1126    QMainWindow::resizeEvent (aEvent);
    10611127}
    10621128
     
    18181884void VBoxConsoleWnd::toggleFullscreenMode (bool aOn, bool aSeamless)
    18191885{
    1820     if (aSeamless &&
    1821         (aOn && !mIsSeamlessSupported ||
    1822          aOn && mIsFullscreen ||
    1823          !aOn && !mIsSeamless))
    1824         return;
    1825 
    1826     /* Check if the Guest Video RAM enough for the seamless mode */
    1827     QRect screen = QApplication::desktop()->screenGeometry (this);
    1828     ULONG vRamSize = csession.GetMachine().GetVRAMSize();
    1829     if (aSeamless && aOn &&
    1830         (ULONG64) vRamSize * _1M * 8 <
    1831         (ULONG64) screen.width() * screen.height() * QColor::numBitPlanes())
    1832     {
    1833         vboxProblem().cannotEnterSeamlessMode (screen.width(),
    1834             screen.height(), QColor::numBitPlanes());
    1835         vmSeamlessAction->setOn (false);
    1836         return;
     1886    if (aSeamless)
     1887    {
     1888        /* Check if it is necessary to enter/leave seamless mode */
     1889        if (aOn && !mIsSeamlessSupported || aOn && mIsFullscreen ||
     1890            !aOn && !mIsSeamless)
     1891            return;
     1892
     1893        /* Check if the Guest Video RAM enough for the seamless mode */
     1894        QRect screen = QApplication::desktop()->screenGeometry (this);
     1895        ULONG vRamSize = csession.GetMachine().GetVRAMSize();
     1896        if (aOn &&
     1897            (ULONG64) vRamSize * _1M * 8 <
     1898            (ULONG64) screen.width() * screen.height() * QColor::numBitPlanes())
     1899        {
     1900            vboxProblem().cannotEnterSeamlessMode (screen.width(),
     1901                screen.height(), QColor::numBitPlanes());
     1902            vmSeamlessAction->setOn (false);
     1903            return;
     1904        }
    18371905    }
    18381906
     
    18741942        vmDisableMouseIntegrAction->setEnabled (!aOn);
    18751943
    1876         console->console().GetDisplay().SetSeamlessMode(aOn);
     1944        console->console().GetDisplay().SetSeamlessMode (aOn);
     1945        mIsSeamless = aOn;
    18771946    }
    18781947    else
     
    18871956    if (aOn)
    18881957    {
    1889         if (aSeamless)
    1890             mIsSeamless = true;
     1958        /* Block any disallowed resize events: */
     1959        mManualResize = true;
     1960        console->setIgnoreMainwndResize (true);
     1961
     1962        /* temporarily disable the mode-related action to make sure
     1963         * user can not leave the mode before he enter it */
     1964        aSeamless ? vmSeamlessAction->setEnabled (false) :
     1965                    vmFullscreenAction->setEnabled (false);
     1966
     1967        connect (console, SIGNAL (resizeHintDone()), this, SLOT (onEnterFullscreen()));
    18911968
    18921969        /* Save the previous scroll-view minimum size before entering
     
    19001977        was_max = isMaximized();
    19011978
     1979        /* memorize previous size before entering the f/s mode */
     1980        mPrevSize = size();
     1981
    19021982        /* set the correct flags to disable unnecessary frame controls */
    19031983        int flags = WType_TopLevel | WStyle_Customize | WStyle_NoBorder;
     
    19091989            QApplication::desktop()->availableGeometry (this) :
    19101990            QApplication::desktop()->screenGeometry (this);
     1991
     1992        /* let the required resize event pass */
     1993        mAwaitingSize = scrGeo.size();
    19111994
    19121995#ifdef Q_WS_WIN32
     
    19492032        /* go fullscreen */
    19502033        resize (scrGeo.size());
    1951         setMinimumSize (size());
    1952         setMaximumSize (size());
     2034        setMinimumSize (scrGeo.size());
     2035        setMaximumSize (scrGeo.size());
    19532036
    19542037#ifdef Q_WS_MAC
     
    19652048    else
    19662049    {
     2050        /* temporarily disable the mode-related action to make sure
     2051         * user can not enter the mode before he leave it */
     2052        aSeamless ? vmSeamlessAction->setEnabled (false) :
     2053                    vmFullscreenAction->setEnabled (false);
     2054
     2055        connect (console, SIGNAL (resizeHintDone()), this, SLOT (onExitFullscreen()));
     2056
    19672057        /* Restore the previous scroll-view minimum size before the exiting
    19682058         * fullscreen. Required for correct scroll-view and guest display
     
    19812071
    19822072        /* reparent to restore normal flags */
    1983         reparent (parentWidget(), normal_wflags, QPoint (0, 0), false);
     2073        reparent (parentWidget(), normal_wflags, normal_pos, false);
    19842074        /* reattaching application icon after window reparenting */
    19852075        setIcon (QPixmap::fromMimeSource ("ico40x01.png"));
     
    20022092        setMaximumSize (QSize (QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
    20032093
    2004         if (aSeamless)
    2005         {
    2006             if (was_max)
    2007             {
    2008                 /* restore the maximized state */
     2094        /* restore previous position and size */
     2095        bool is_max = isMaximized();
     2096        move (normal_pos);
     2097        if (was_max)
     2098            mAllowOneResize = true;
     2099        resize (normal_size);
     2100        qApp->processEvents();
     2101
     2102        if (was_max)
     2103        {
     2104            if (aSeamless && is_max)
     2105                mDoMaximize = true;
     2106            else
    20092107                setWindowState (windowState() | WindowMaximized);
    2010             }
    2011             else
    2012             {
    2013                 move (normal_pos);
    2014                 resize (normal_size);
    2015                 QTimer::singleShot (200, console, SLOT (exitFullScreen()));
    2016             }
    2017         }
    2018         else
    2019         {
    2020             move (normal_pos);
    2021             resize (normal_size);
    2022             /* restore the maximized state */
    2023             if (was_max)
    2024                 setWindowState (windowState() | WindowMaximized);
    2025             else
    2026                 QTimer::singleShot (0, console, SLOT (exitFullScreen()));
    2027         }
    2028 
    2029         /* let our toplevel widget calculate its sizeHint properly */
    2030         QApplication::sendPostedEvents (0, QEvent::LayoutHint);
    2031 
    2032         if (aSeamless)
    2033             mIsSeamless = false;
     2108            qApp->processEvents();
     2109        }
    20342110    }
    20352111
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