VirtualBox

Changeset 5544 in vbox


Ignore:
Timestamp:
Oct 29, 2007 9:50:13 AM (17 years ago)
Author:
vboxsync
Message:

2349: "Fullscreen loses focus" issue:

Just upgraded fullscreen/seamless mode entering mechanism from "reparenting way" to "QT inner fullscreen mode" (with region restriction for seamless).

Need to be checked on every platform for different issues.

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

Legend:

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

    r5132 r5544  
    9191    void fixModifierState (LONG *codes, uint *count);
    9292
    93     void toggleFSMode (const QSize &aFeatSize);
     93    void toggleFSMode();
    9494
    9595    void setIgnoreMainwndResize (bool aYes) { mIgnoreMainwndResize = aYes; }
     
    232232
    233233    QRegion mLastVisibleRegion;
     234    QSize mNormalSize;
    234235
    235236#if defined(Q_WS_WIN)
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h

    r5260 r5544  
    4242class QHBox;
    4343class QLabel;
     44class QSpacerItem;
    4445
    4546class VBoxConsoleView;
     
    6970    bool isTrueSeamless() const { return mIsSeamless; }
    7071
    71     bool isManualResize() const { return mManualResize; }
    72 
    7372    void setMouseIntegrationLocked (bool aDisabled);
    7473
     
    7776    void installGuestAdditionsFrom (const QString &aSource);
    7877
    79 #ifdef Q_WS_WIN
    8078    void setMask (const QRegion &aRegion);
    81 #endif
    8279
    8380public slots:
     
    8784    // events
    8885    bool event (QEvent *e);
    89     void resizeEvent (QResizeEvent *e);
    9086    void closeEvent (QCloseEvent *e);
    9187#if defined(Q_WS_X11)
     
    252248    bool statusBarChangedInside;
    253249
     250    QSpacerItem *mShiftingSpacer;
     251
    254252#ifdef VBOX_WITH_DEBUGGER_GUI
    255253    // Debugger popup menu
     
    294292    QSize normal_size;
    295293    QSize prev_min_size;
    296     QSize mPrevSize;
    297     QSize mAwaitingSize;
    298294
    299295#ifdef Q_WS_WIN32
     
    302298
    303299    // variables for dealing with true fullscreen
    304     bool mDoMaximize : 1;
    305     bool mManualResize : 1;
    306     bool mAllowOneResize : 1;
     300    QRegion mStrictedRegion;
    307301    bool mIsFullscreen : 1;
    308302    bool mIsSeamless : 1;
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r5329 r5544  
    846846    /* Make no normalizeGeometry in case we are in manual resize
    847847     * mode or main window is maximized */
    848     if (mainwnd->isManualResize() || mainwnd->isMaximized())
     848    if (mainwnd->isMaximized())
    849849        return;
    850850
     
    16511651    {
    16521652        flags |= KeyExtended;
    1653         scan = ch >> 8; 
     1653        scan = ch >> 8;
    16541654    }
    16551655    else if (scan == 0x5C && (ch & 0xFF) == '/')
     
    20542054 *  Called on enter/exit seamless/fullscreen mode.
    20552055 */
    2056 void VBoxConsoleView::toggleFSMode (const QSize &aResizeTo)
     2056void VBoxConsoleView::toggleFSMode()
    20572057{
    20582058    if (mIsAdditionsActive && mAutoresizeGuest)
    2059         doResizeHint (aResizeTo);
     2059    {
     2060        QSize newSize = QSize();
     2061        if (mainwnd->isTrueFullscreen() || mainwnd->isTrueSeamless())
     2062        {
     2063            mNormalSize = frameSize();
     2064            newSize = maximumSize();
     2065        }
     2066        else
     2067            newSize = mNormalSize;
     2068        doResizeHint (newSize);
     2069    }
    20602070    mToggleFSModeTimer->start (400, true);
    20612071}
     
    32673277         * and gives it all available space. */
    32683278        QSize sz (aToSize.isValid() ? aToSize : mainwnd->centralWidget()->size());
    3269         sz -= QSize (frameWidth() * 2, frameWidth() * 2);
     3279        if (!aToSize.isValid())
     3280            sz -= QSize (frameWidth() * 2, frameWidth() * 2);
    32703281        LogFlowFunc (("Will suggest %d x %d\n", sz.width(), sz.height()));
    32713282
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp

    r5512 r5544  
    108108    , machine_state (CEnums::InvalidMachineState)
    109109    , no_auto_close (false)
    110     , mDoMaximize (false)
    111     , mManualResize (false)
    112     , mAllowOneResize (false)
    113110    , mIsFullscreen (false)
    114111    , mIsSeamless (false)
     
    634631    {
    635632        setCentralWidget (new QWidget (this, "centralWidget"));
    636         new QBoxLayout (centralWidget(), QBoxLayout::LeftToRight);
     633        new QBoxLayout (centralWidget(), QBoxLayout::Down);
    637634    }
    638635
     
    651648    ((QBoxLayout*) centralWidget()->layout())->addWidget (
    652649        console, 0, AlignVCenter | AlignHCenter);
     650
     651    mShiftingSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding,
     652                                             QSizePolicy::Fixed);
     653    ((QBoxLayout*) centralWidget()->layout())->addItem (mShiftingSpacer);
    653654
    654655    CMachine cmachine = csession.GetMachine();
     
    10081009    vmSeamlessAction->setEnabled (mIsSeamless);
    10091010    vmFullscreenAction->setEnabled (mIsFullscreen);
    1010 
    1011     mAwaitingSize = mPrevSize;
    10121011}
    10131012
     
    10231022    vmFullscreenAction->setEnabled (true);
    10241023
    1025     mManualResize = false;
    10261024    console->setIgnoreMainwndResize (false);
    10271025    console->normalizeGeometry (true /* adjustPosition */);
     
    10781076            QResizeEvent *re = (QResizeEvent *) e;
    10791077
    1080             /* do not process event if the resize events are blocked
    1081              * and the proposed size is not the awaited one */
    1082             if (mManualResize && !mAllowOneResize &&
    1083                 re->size() != mAwaitingSize)
    1084                 return false;
    1085 
    1086             if (!mManualResize  &&
    1087                 (windowState() & WindowMaximized) == 0)
     1078            if ((windowState() & WindowMaximized) == 0)
    10881079            {
    10891080                normal_size = re->size();
     
    10921083#endif
    10931084            }
    1094             if (mManualResize && mAllowOneResize)
    1095                 mAllowOneResize = false;
    1096 
    10971085            break;
    10981086        }
    10991087        case QEvent::Move:
    11001088        {
    1101             if (!mManualResize  &&
    1102                 (windowState() & (WindowMaximized | WindowMinimized |
     1089            if ((windowState() & (WindowMaximized | WindowMinimized |
    11031090                                  WindowFullScreen)) == 0)
    11041091            {
     
    11161103            break;
    11171104        }
    1118         case QEvent::WindowStateChange:
    1119         {
    1120             if (mDoMaximize)
    1121             {
    1122                 /* this workaround is necessary due to KDE seems to be
    1123                  * thinks the seamless mode is maximized state */
    1124                 mDoMaximize = false;
    1125                 setWindowState (windowState() | WindowMaximized);
    1126             }
    1127         }
    11281105        default:
    11291106            break;
     
    11311108
    11321109    return QMainWindow::event (e);
    1133 }
    1134 
    1135 void VBoxConsoleWnd::resizeEvent (QResizeEvent *aEvent)
    1136 {
    1137     if (aEvent->size() == mAwaitingSize)
    1138     {
    1139         /* this resize was done to awaited size, so
    1140          * let the guest to be resized to this size too */
    1141         mAwaitingSize = QSize();
    1142         console->toggleFSMode (centralWidget()->size());
    1143     }
    1144 
    1145     QMainWindow::resizeEvent (aEvent);
    11461110}
    11471111
     
    19401904    if (aSeamless)
    19411905    {
    1942         /* Check if it is necessary to enter/leave seamless mode */
    1943         if (aOn && !mIsSeamlessSupported || aOn && mIsFullscreen ||
     1906        /* Check if it is necessary to enter/leave seamless mode. */
     1907        if (aOn && (!mIsSeamlessSupported || mIsFullscreen) ||
    19441908            !aOn && !mIsSeamless)
    19451909            return;
    19461910
    1947         /* Check if the Guest Video RAM enough for the seamless mode */
     1911        /* Check if the Guest Video RAM enough for the seamless mode. */
    19481912        QRect screen = QApplication::desktop()->screenGeometry (this);
    19491913        ULONG64 availBits = (csession.GetMachine().GetVRAMSize() /* vram */
     
    19561920                         * screen.height() /* display height */
    19571921                         * QColor::numBitPlanes(); /* bit per pixel */
    1958 
    19591922        if (aOn && (availBits < usedBits))
    19601923        {
     
    19751938    if (aOn)
    19761939    {
    1977         /* take the toggle hot key from the menu item */
     1940        /* Take the toggle hot key from the menu item. */
    19781941        QString hotKey = aSeamless ? vmSeamlessAction->menuText() :
    19791942                                     vmFullscreenAction->menuText();
    19801943        hotKey = QStringList::split ('\t', hotKey) [1];
    19811944        Assert (!hotKey.isEmpty());
    1982         /* get the host key name */
     1945        /* Get the host key name. */
    19831946        QString hostKey = QIHotKeyEdit::keyName (vboxGlobal().settings()
    19841947                                                             .hostKey());
    1985         /* show the info message */
     1948        /* Show the info message. */
    19861949        aSeamless ? vboxProblem().remindAboutGoingSeamless (hotKey, hostKey) :
    19871950                    vboxProblem().remindAboutGoingFullscreen (hotKey, hostKey);
     
    19901953    if (aSeamless)
    19911954    {
    1992         /* activate the auto-resize feature required for the seamless mode */
     1955        /* Activate the auto-resize feature required for the seamless mode. */
    19931956        if (!vmAutoresizeGuestAction->isOn())
    19941957            vmAutoresizeGuestAction->setOn (true);
    19951958
    1996         /* activate the mouse integration feature for the seamless mode */
     1959        /* Activate the mouse integration feature for the seamless mode. */
    19971960        if (vmDisableMouseIntegrAction->isOn())
    19981961            vmDisableMouseIntegrAction->setOn (false);
     
    20171980    if (aOn)
    20181981    {
    2019         /* Block any disallowed resize events: */
    2020         mManualResize = true;
    2021         console->setIgnoreMainwndResize (true);
    2022 
    2023         /* temporarily disable the mode-related action to make sure
    2024          * user can not leave the mode before he enter it */
     1982        /* Temporarily disable the mode-related action to make sure
     1983         * user can not leave the mode before he enter it. */
    20251984        aSeamless ? vmSeamlessAction->setEnabled (false) :
    20261985                    vmFullscreenAction->setEnabled (false);
    2027 
    2028         connect (console, SIGNAL (resizeHintDone()), this, SLOT (onEnterFullscreen()));
     1986        /* Toggle console to manual resize mode. */
     1987        console->setIgnoreMainwndResize (true);
     1988        connect (console, SIGNAL (resizeHintDone()),
     1989                 this, SLOT (onEnterFullscreen()));
     1990
     1991        /* Memorize the maximized state. */
     1992        was_max = isMaximized();
    20291993
    20301994        /* Save the previous scroll-view minimum size before entering
     
    20351999        console->setMinimumSize (0, 0);
    20362000
    2037         /* memorize the maximized state */
    2038         was_max = isMaximized();
    2039 
    2040         /* memorize previous size before entering the f/s mode */
    2041         mPrevSize = size();
    2042 
    2043         /* set the correct flags to disable unnecessary frame controls */
    2044         int flags = WType_TopLevel | WStyle_Customize | WStyle_NoBorder;
    2045         if (!aSeamless)
    2046             flags |= WStyle_StaysOnTop;
    2047 
    20482001        /* let the widget take the whole available desktop space */
    20492002        QRect scrGeo = aSeamless ?
     
    20512004            QApplication::desktop()->screenGeometry (this);
    20522005
    2053         /* let the required resize event pass */
    2054         mAwaitingSize = scrGeo.size();
     2006        /* Calculate the difference region between current mode
     2007         * (fullscreen or seamless) and the screen geometry. */
     2008        mStrictedRegion =
     2009            QRegion (QApplication::desktop()->screenGeometry (this)) - scrGeo;
     2010
     2011        /* Setup the shifting spacer to make the console to be aligned on top
     2012         * in the seamless mode. */
     2013        mShiftingSpacer->changeSize (0, mStrictedRegion.boundingRect().height(),
     2014                                     QSizePolicy::Preferred, QSizePolicy::Fixed);
    20552015
    20562016#ifdef Q_WS_WIN32
     
    20582018#endif
    20592019
    2060         /* hide early to avoid extra flicker */
    2061         hide();
    2062         /* hide all but the central widget containing the console view */
     2020        /* Hide all but the central widget containing the console view. */
    20632021        QObjectList *list = queryList (NULL, NULL, false, false);
    20642022        for (QObject *obj = list->first(); obj != NULL; obj = list->next())
     
    20762034        delete list;
    20772035
    2078         /* reparent to apply new flags and place to the top left corner of the
    2079          * current desktop */
    2080         reparent (parentWidget(), flags, QPoint (scrGeo.x(), scrGeo.y()), false);
    2081         /* reattaching application icon after window reparenting */
    2082         setIcon (QPixmap::fromMimeSource ("ico40x01.png"));
    2083 
    2084         /* adjust colors and appearance */
     2036        /* Adjust colors and appearance. */
    20852037        erase_color = centralWidget()->eraseColor();
    20862038        centralWidget()->setEraseColor (black);
    20872039        console_style = console->frameStyle();
    20882040        console->setFrameStyle (QFrame::NoFrame);
    2089         console->setMaximumSize (console->sizeHint());
     2041        console->setMaximumSize (scrGeo.size());
    20902042        console->setVScrollBarMode (QScrollView::AlwaysOff);
    20912043        console->setHScrollBarMode (QScrollView::AlwaysOff);
    20922044
    2093         /* go fullscreen */
    2094         resize (scrGeo.size());
    2095         setMinimumSize (scrGeo.size());
    2096         setMaximumSize (scrGeo.size());
     2045        /* Going fullscreen:
     2046         * "normal -> fullscreen" for normal window,
     2047         * "maximized -> normal -> fullscreen" for maximized window.
     2048         * Going "maximized -> fullscreen" wrong on KDE in both directions.
     2049         * Here it does not resize the child window correctly. */
     2050        if (was_max)
     2051            showNormal();
     2052        showFullScreen();
    20972053
    20982054#ifdef Q_WS_MAC
    20992055        if (!aSeamless)
    21002056        {
    2101             /* make the apple menu bar go away. */
     2057            /* Make the apple menu bar go away. */
    21022058            OSStatus orc = SetSystemUIMode (kUIModeAllHidden,
    21032059                                            kUIOptionDisableAppleMenu);
     
    21062062        }
    21072063#endif
     2064
     2065        qApp->processEvents();
     2066        console->toggleFSMode();
    21082067    }
    21092068    else
    21102069    {
    2111         /* temporarily disable the mode-related action to make sure
    2112          * user can not enter the mode before he leave it */
     2070        /* Temporarily disable the mode-related action to make sure
     2071         * user can not enter the mode before he leave it. */
    21132072        aSeamless ? vmSeamlessAction->setEnabled (false) :
    21142073                    vmFullscreenAction->setEnabled (false);
    2115 
     2074        /* Toggle console to manual resize mode. */
    21162075        connect (console, SIGNAL (resizeHintDone()), this, SLOT (onExitFullscreen()));
     2076
     2077        /* Reset the shifting spacer. */
     2078        mShiftingSpacer->changeSize (0, 0, QSizePolicy::Preferred,
     2079                                           QSizePolicy::Fixed);
    21172080
    21182081        /* Restore the previous scroll-view minimum size before the exiting
     
    21282091#endif
    21292092
    2130         /* hide early to avoid extra flicker */
    2131         hide();
    2132 
    2133         /* reparent to restore normal flags */
    2134         reparent (parentWidget(), normal_wflags, normal_pos, false);
    2135         /* reattaching application icon after window reparenting */
    2136         setIcon (QPixmap::fromMimeSource ("ico40x01.png"));
    2137 
    2138         /* adjust colors and appearance */
     2093        /* Adjust colors and appearance. */
     2094        clearMask();
    21392095        centralWidget()->setEraseColor (erase_color);
    21402096        console->setFrameStyle (console_style);
     
    21432099        console->setHScrollBarMode (QScrollView::Auto);
    21442100
    2145         /* show everything hidden when going fullscreen */
     2101        /* Show everything hidden when going fullscreen. */
    21462102        for (QObject *obj = hidden_children.first(); obj != NULL;
    21472103             obj = hidden_children.next())
     
    21492105        hidden_children.clear();
    21502106
    2151         /* restore normal values */
    2152         setMinimumSize (QSize(0, 0));
    2153         setMaximumSize (QSize (QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
    2154 
    2155         /* check if we are maximized: seamless on some wm == maximized */
    2156         bool is_max = isMaximized();
    2157 
    2158         /* restore previous position */
    2159         move (normal_pos);
    2160 
     2107        /* Going normal || maximized:
     2108         * "fullscreen -> normal" if was normal window,
     2109         * "fullscreen -> normal -> maximized" if was maximized window.
     2110         * Going "fullscreen -> maximized" wrong on KDE in both directions.
     2111         * Here it looses the window frame totally. */
     2112        showNormal();
    21612113        if (was_max)
    2162             /* let pass one resize event with previous size */
    2163             mAllowOneResize = true;
    2164         else
    2165             /* ensure we are waiting for the previous size */
    2166             mAwaitingSize = normal_size;
    2167 
    2168         /* restore previous size */
    2169         resize (normal_size);
     2114            showMaximized();
     2115
    21702116        qApp->processEvents();
    2171 
    2172         if (was_max)
    2173         {
    2174             if (aSeamless && is_max)
    2175                 /* if seamless == maximized do delayed maximization */
    2176                 mDoMaximize = true;
    2177             else
    2178                 /* restore maximized mode now */
    2179                 setWindowState (windowState() | WindowMaximized);
    2180             qApp->processEvents();
    2181         }
    2182     }
    2183 
    2184     /* VBoxConsoleView loses focus for some reason after reparenting,
    2185      * restore it */
    2186     console->setFocus();
    2187 
    2188     if (!wasHidden)
    2189         show();
     2117        console->toggleFSMode();
     2118    }
     2119    if (wasHidden)
     2120        hide();
    21902121}
    21912122
     
    25642495}
    25652496
     2497void VBoxConsoleWnd::setMask (const QRegion &aRegion)
     2498{
     2499    QRegion region = aRegion - mStrictedRegion;
     2500
    25662501#ifdef Q_WS_WIN
    2567 void VBoxConsoleWnd::setMask (const QRegion &aRegion)
    2568 {
    2569     QRegion difference = mPrevRegion.subtract (aRegion);
     2502    QRegion difference = mPrevRegion.subtract (region);
    25702503
    25712504    /* Region offset calculation */
     
    25792512    /* Visible region calculation */
    25802513    HRGN newReg = CreateRectRgn (0, 0, 0, 0);
    2581     CombineRgn (newReg, aRegion.handle(), 0, RGN_COPY);
     2514    CombineRgn (newReg, region.handle(), 0, RGN_COPY);
    25822515    OffsetRgn (newReg, fleft, ftop);
    25832516
     
    25922525    RedrawWindow (console->viewport()->winId(), NULL, NULL, RDW_INVALIDATE);
    25932526
    2594     mPrevRegion = aRegion;
    2595 }
    2596 #endif
     2527    mPrevRegion = region;
     2528#else
     2529    QMainWindow::setMask (region);
     2530#endif
     2531}
    25972532
    25982533/**
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