VirtualBox

Changeset 9072 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 23, 2008 12:02:58 PM (17 years ago)
Author:
vboxsync
Message:

FE/Qt4: Backported:

  • r31128 (2800: "FE/Qt: Switch to fullscreen does not work reliably": ...)
  • r31135 (Fixing seamless/fullscreen mode entering/exiting event-order for windows.)
  • r31143 (FE/Qt-OSX: Fix for r31128 which broke seamless mode on Mac OS X.)
Location:
trunk/src/VBox/Frontends/VirtualBox4
Files:
4 edited

Legend:

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

    r9067 r9072  
    9595    void fixModifierState (LONG *codes, uint *count);
    9696
    97     void toggleFSMode();
     97    void toggleFSMode (const QSize &aSize = QSize());
    9898
    9999    void setIgnoreMainwndResize (bool aYes) { mIgnoreMainwndResize = aYes; }
     
    273273    long muCapsLockAdaptionCnt;
    274274
    275     QTimer *mToggleFSModeTimer;
    276275
    277276    VBoxDefs::RenderMode mode;
  • trunk/src/VBox/Frontends/VirtualBox4/include/VBoxConsoleWnd.h

    r9056 r9072  
    190190    void dbgShowCommandLine();
    191191
    192     void onEnterFullscreen();
    193192    void onExitFullscreen();
    194     void exitFullscreen();
    195     void exitSeamless();
     193    void unlockActionsSwitch();
    196194
    197195    void switchToFullscreen (bool aOn, bool aSeamless);
     
    317315    bool mIsSeamlessSupported : 1;
    318316    bool mIsGraphicsSupported : 1;
     317    bool mIsWaitingModeResize : 1;
    319318    bool was_max : 1;
    320319    QObjectList hidden_children;
  • trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleView.cpp

    r9070 r9072  
    705705    ::memset (mPressedKeys, 0, SIZEOF_ARRAY (mPressedKeys));
    706706
    707     /* This timer is used as 'last resort' which toggles f/s mode
    708        in case of guest additions are not responding. */
    709     mToggleFSModeTimer = new QTimer (this);
    710     mToggleFSModeTimer->setSingleShot (true);
    711     connect (mToggleFSModeTimer, SIGNAL (timeout()),
    712              this, SIGNAL (resizeHintDone()));
    713 
    714707    /* setup rendering */
    715708
     
    813806        setDesktopGeometry (DesktopGeo_Fixed, width, height);
    814807    }
    815     connect (QApplication::desktop(), SIGNAL (workAreaResized (int)),
     808    connect (QApplication::desktop(), SIGNAL (resized (int)),
    816809             this, SLOT (doResizeDesktop (int)));
    817810
     
    11011094                LogFlow (("VBoxDefs::ResizeEventType: %d x %d x %d bpp\n",
    11021095                          re->width(), re->height(), re->bitsPerPixel()));
    1103 
    1104                 if (mToggleFSModeTimer->isActive())
    1105                     mToggleFSModeTimer->stop();
    11061096
    11071097                /* do frame buffer dependent resize */
     
    22852275 *  Called on enter/exit seamless/fullscreen mode.
    22862276 */
    2287 void VBoxConsoleView::toggleFSMode()
     2277void VBoxConsoleView::toggleFSMode (const QSize &aSize)
    22882278{
    22892279    if (mAutoresizeGuest || mMainWnd->isTrueFullscreen())
    22902280    {
    2291         QSize newSize = QSize();
    2292         if (mMainWnd->isTrueFullscreen() || mMainWnd->isTrueSeamless())
    2293         {
    2294             mNormalSize = frameSize();
     2281        QSize newSize;
     2282        if (aSize.isValid())
     2283        {
     2284            mNormalSize = aSize;
    22952285            newSize = maximumSize();
    22962286        }
     
    22992289        doResizeHint (newSize);
    23002290    }
    2301     /* Currently there is a 2000 msec pause before timer transfers
    2302      * console into desired mode if the auto-resize feature is enabled
    2303      * and a 100 msec pause before it transfers console into this mode
    2304      * if it is not enabled. 100 msec pause required for resizing
    2305      * before normalizing geometry. */
    2306     mToggleFSModeTimer->start (mAutoresizeGuest ? 2000 : 100);
    2307 
    2308     /// @todo (r=dsen) perform roll-back after 'entering' mode in case
    2309     //                 we got no resizing response from the guest.
    23102291}
    23112292
  • trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleWnd.cpp

    r9056 r9072  
    126126    , mIsSeamlessSupported (false)
    127127    , mIsGraphicsSupported (false)
     128    , mIsWaitingModeResize (false)
    128129    , was_max (false)
    129130    , console_style (0)
     
    10311032
    10321033/**
    1033  *  This slot is called just after entering the fullscreen/seamless mode,
    1034  *  when the console was resized to required size.
    1035  */
    1036 void VBoxConsoleWnd::onEnterFullscreen()
    1037 {
    1038     disconnect (console, SIGNAL (resizeHintDone()), 0, 0);
    1039     /* It isn't guaranteed that the guest os set the video mode that
    1040      * we requested. So after all the resizing stuff set the clipping
    1041      * mask and the spacing shifter to the corresponding values. */
    1042     setViewInSeamlessMode (QRect (console->mapToGlobal (QPoint (0, 0)), console->size()));
    1043 #ifdef Q_WS_MAC
    1044     if (!mIsSeamless)
    1045     {
    1046         /* Fade back to the normal gamma */
    1047         CGDisplayFade (mFadeToken, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false);
    1048         CGReleaseDisplayFadeReservation (mFadeToken);
    1049     }
    1050 #endif
    1051 
    1052     vmSeamlessAction->setEnabled (mIsSeamless);
    1053     vmFullscreenAction->setEnabled (mIsFullscreen);
    1054     if (mIsSeamless)
    1055         connect (console, SIGNAL (resizeHintDone()),
    1056                  this, SLOT (exitSeamless()));
    1057     /* disabled for now */
    1058     //else if (mIsFullscreen)
    1059     //    connect (console, SIGNAL (resizeHintDone()),
    1060     //             this, SLOT (exitFullscreen()));
    1061 }
    1062 
    1063 /**
    10641034 *  This slot is called just after leaving the fullscreen/seamless mode,
    10651035 *  when the console was resized to previous size.
     
    10671037void VBoxConsoleWnd::onExitFullscreen()
    10681038{
    1069     disconnect (console, SIGNAL (resizeHintDone()), 0, 0);
     1039    console->setIgnoreMainwndResize (false);
     1040}
     1041
     1042void VBoxConsoleWnd::unlockActionsSwitch()
     1043{
     1044    if (mIsSeamless)
     1045        vmSeamlessAction->setEnabled (true);
     1046    else if (mIsFullscreen)
     1047        vmFullscreenAction->setEnabled (true);
     1048    else
     1049    {
     1050        vmSeamlessAction->setEnabled (mIsSeamlessSupported && mIsGraphicsSupported);
     1051        vmFullscreenAction->setEnabled (true);
     1052    }
     1053
    10701054#ifdef Q_WS_MAC
    10711055    if (!mIsSeamless)
     
    10761060    }
    10771061#endif
    1078 
    1079     vmSeamlessAction->setEnabled (mIsSeamlessSupported && mIsGraphicsSupported);
    1080     vmFullscreenAction->setEnabled (true);
    1081 
    1082     console->setIgnoreMainwndResize (false);
    1083     console->normalizeGeometry (true /* adjustPosition */);
    1084 }
    1085 
    1086 /**
    1087  *  This slot is called if the guest changes resolution while in fullscreen
    1088  *  mode.
    1089  */
    1090 void VBoxConsoleWnd::exitFullscreen()
    1091 {
    1092     Assert (0); /* disabled for now */
    1093     if (mIsFullscreen && vmFullscreenAction->isEnabled())
    1094         vmFullscreenAction->toggle();
    1095 }
    1096 
    1097 /**
    1098  *  This slot is called if the guest changes resolution while in seamless
    1099  *  mode.
    1100  */
    1101 void VBoxConsoleWnd::exitSeamless()
    1102 {
    1103     if (mIsSeamless && vmSeamlessAction->isEnabled())
    1104         vmSeamlessAction->toggle();
    11051062}
    11061063
     
    11551112            QResizeEvent *re = (QResizeEvent *) e;
    11561113
    1157             if (!isMaximized() && !isTrueFullscreen() && !isTrueSeamless())
     1114            if (!mIsWaitingModeResize && !isMaximized() &&
     1115                !isTrueFullscreen() && !isTrueSeamless())
    11581116            {
    11591117                normal_size = re->size();
     
    11611119                dbgAdjustRelativePos();
    11621120#endif
     1121            }
     1122
     1123            if (mIsWaitingModeResize)
     1124            {
     1125                if (!mIsFullscreen && !mIsSeamless)
     1126                {
     1127                    mIsWaitingModeResize = false;
     1128                    QTimer::singleShot (0, this, SLOT (onExitFullscreen()));
     1129                }
    11631130            }
    11641131            break;
     
    19781945bool VBoxConsoleWnd::toggleFullscreenMode (bool aOn, bool aSeamless)
    19791946{
    1980     disconnect (console, SIGNAL (resizeHintDone()), 0, 0);
    1981     /* Check if the Guest Video RAM enough for the fullscreen/seamless mode. */
     1947    /* Please note: For some platforms like the Mac, the calling order of the
     1948     * functions in this methods is vital. So please be carefull on changing
     1949     * this. */
     1950
     1951    QSize initialSize = size();
    19821952    if (aSeamless || console->isAutoresizeGuestActive())
    19831953    {
     
    20752045    bool wasHidden = isHidden();
    20762046
     2047    /* Temporarily disable the mode-related action to make sure
     2048     * user can not leave the mode before he enter it and inside out. */
     2049    aSeamless ? vmSeamlessAction->setEnabled (false) :
     2050                vmFullscreenAction->setEnabled (false);
     2051
     2052    /* Calculate initial console size */
     2053    QSize consoleSize;
     2054
    20772055    if (aOn)
    20782056    {
    2079         /* Temporarily disable the mode-related action to make sure
    2080          * user can not leave the mode before he enter it. */
    2081         aSeamless ? vmSeamlessAction->setEnabled (false) :
    2082                     vmFullscreenAction->setEnabled (false);
     2057        consoleSize = console->frameSize();
     2058        consoleSize -= QSize (console->frameWidth() * 2, console->frameWidth() * 2);
     2059
    20832060        /* Toggle console to manual resize mode. */
    20842061        console->setIgnoreMainwndResize (true);
    2085         connect (console, SIGNAL (resizeHintDone()),
    2086                  this, SLOT (onEnterFullscreen()));
    20872062
    20882063        /* Memorize the maximized state. */
     
    21062081         * we requested. So after all the resizing stuff set the clipping
    21072082         * mask and the spacing shifter to the corresponding values. */
    2108         setViewInSeamlessMode (dtw->availableGeometry (this));
     2083        if (aSeamless)
     2084            setViewInSeamlessMode (scrGeo);
    21092085
    21102086#ifdef Q_WS_WIN32
     
    21412117        console->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    21422118        console->setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    2143 
    2144         /* Going fullscreen */
    2145         switchToFullscreen (aOn, aSeamless);
    2146 #ifdef Q_WS_MAC /* setMask seems to not include the far border pixels. */
    2147 //        QRect maskRect = dtw->screenGeometry (this);
    2148 //        maskRect.setRight (maskRect.right() + 1);
    2149 //        maskRect.setBottom (maskRect.bottom() + 1);
    2150 //        setMask (maskRect);
    2151         if (aSeamless)
    2152         {
    2153             OSStatus status;
    2154             HIViewRef viewRef = ::darwinToHIViewRef (console->viewport());
    2155             Assert (VALID_PTR (viewRef));
    2156             WindowRef windowRef = ::darwinToWindowRef (viewRef);
    2157             Assert (VALID_PTR (windowRef));
    2158             /* @todo=poetzsch: Currently this isn't necessary. I should
    2159              * investigate if we can/should use this. */
    2160             /*
    2161             EventTypeSpec wCompositingEvent = { kEventClassWindow, kEventWindowGetRegion };
    2162             status = InstallWindowEventHandler ((WindowPtr)winId(), DarwinRegionHandler, GetEventTypeCount (wCompositingEvent), &wCompositingEvent, &mCurrRegion, &mDarwinRegionEventHandlerRef);
    2163             AssertCarbonOSStatus (status);
    2164             HIViewRef contentView = 0;
    2165             status = HIViewFindByID(HIViewGetRoot(windowRef), kHIViewWindowContentID, &contentView);
    2166             AssertCarbonOSStatus (status);
    2167             EventTypeSpec drawEvent = { kEventClassControl, kEventControlDraw };
    2168             status = InstallControlEventHandler (contentView, DarwinRegionHandler, GetEventTypeCount (drawEvent), &drawEvent, &contentView, NULL);
    2169             AssertCarbonOSStatus (status);
    2170             */
    2171             UInt32 features;
    2172             status = GetWindowFeatures (windowRef, &features);
    2173             AssertCarbonOSStatus (status);
    2174             if (( features & kWindowIsOpaque ) != 0)
    2175             {
    2176                 status = HIWindowChangeFeatures (windowRef, 0, kWindowIsOpaque);
    2177                 AssertCarbonOSStatus (status);
    2178             }
    2179             status = HIViewReshapeStructure (viewRef);
    2180             AssertCarbonOSStatus (status);
    2181             status = SetWindowAlpha(windowRef, 0.999);
    2182             AssertCarbonOSStatus (status);
    2183             /* For now disable the shadow of the window. This feature cause errors
    2184              * if a window in vbox looses focus, is reselected and than moved. */
    2185             /** @todo Search for an option to enable this again. A shadow on every
    2186              * window has a big coolness factor. */
    2187             status = ChangeWindowAttributes (windowRef, kWindowNoShadowAttribute, 0);
    2188             AssertCarbonOSStatus (status);
    2189         }
    2190 #else
    2191 //        setMask (dtw->screenGeometry (this));
    2192 #endif
    2193 
    2194         qApp->processEvents();
    2195         console->toggleFSMode();
    21962119    }
    21972120    else
    21982121    {
    2199         /* Temporarily disable the mode-related action to make sure
    2200          * user can not enter the mode before he leave it. */
    2201         aSeamless ? vmSeamlessAction->setEnabled (false) :
    2202                     vmFullscreenAction->setEnabled (false);
    2203         /* Toggle console to manual resize mode. */
    2204         connect (console, SIGNAL (resizeHintDone()), this, SLOT (onExitFullscreen()));
    2205 
    2206         /* Reset the shifting spacer. */
     2122        /* Reset the shifting spacers. */
    22072123        mShiftingSpacerLeft->changeSize (0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    22082124        mShiftingSpacerTop->changeSize (0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
     
    22182134        if (aSeamless)
    22192135        {
     2136            /* Please note: All the stuff below has to be done before the
     2137             * window switch back to normal size. Qt changes the winId on the
     2138             * fullscreen switch and make this stuff useless with the old
     2139             * winId. So please be carefull on rearrangement of the method
     2140             * calls. */
    22202141            /* Undo all mac specific installations */
    22212142            OSStatus status;
     
    22462167            ((QWidget *) obj)->show();
    22472168        hidden_children.clear();
    2248 
    2249         /* Going normal || maximized */
    2250         switchToFullscreen (aOn, aSeamless);
    2251 
    2252         qApp->processEvents();
    2253         console->toggleFSMode();
    2254     }
     2169    }
     2170
     2171    /* Set flag for waiting host resize if it awaited during mode entering */
     2172    if ((mIsFullscreen || mIsSeamless) && (consoleSize != initialSize))
     2173        mIsWaitingModeResize = true;
     2174
     2175    /* Toggle qt full-screen mode */
     2176    switchToFullscreen (aOn, aSeamless);
     2177
     2178#ifdef Q_WS_MAC
     2179    if (aOn && aSeamless)
     2180    {
     2181        /* Please note: All the stuff below has to be done after the window has
     2182         * switched to fullscreen. Qt changes the winId on the fullscreen
     2183         * switch and make this stuff useless with the old winId. So please be
     2184         * carefull on rearrangement of the method calls. */
     2185        OSStatus status;
     2186        HIViewRef viewRef = ::darwinToHIViewRef (console->viewport());
     2187        Assert (VALID_PTR (viewRef));
     2188        WindowRef windowRef = ::darwinToWindowRef (viewRef);
     2189        Assert (VALID_PTR (windowRef));
     2190        /* @todo=poetzsch: Currently this isn't necessary. I should
     2191         * investigate if we can/should use this. */
     2192        /*
     2193           EventTypeSpec wCompositingEvent = { kEventClassWindow, kEventWindowGetRegion };
     2194           status = InstallWindowEventHandler ((WindowPtr)winId(), DarwinRegionHandler, GetEventTypeCount (wCompositingEvent), &wCompositingEvent, &mCurrRegion, &mDarwinRegionEventHandlerRef);
     2195           AssertCarbonOSStatus (status);
     2196           HIViewRef contentView = 0;
     2197           status = HIViewFindByID(HIViewGetRoot(windowRef), kHIViewWindowContentID, &contentView);
     2198           AssertCarbonOSStatus (status);
     2199           EventTypeSpec drawEvent = { kEventClassControl, kEventControlDraw };
     2200           status = InstallControlEventHandler (contentView, DarwinRegionHandler, GetEventTypeCount (drawEvent), &drawEvent, &contentView, NULL);
     2201           AssertCarbonOSStatus (status);
     2202           */
     2203        UInt32 features;
     2204        status = GetWindowFeatures (windowRef, &features);
     2205        AssertCarbonOSStatus (status);
     2206        if (( features & kWindowIsOpaque ) != 0)
     2207        {
     2208            status = HIWindowChangeFeatures (windowRef, 0, kWindowIsOpaque);
     2209            AssertCarbonOSStatus (status);
     2210        }
     2211        status = HIViewReshapeStructure (viewRef);
     2212        AssertCarbonOSStatus (status);
     2213        status = SetWindowAlpha(windowRef, 0.999);
     2214        AssertCarbonOSStatus (status);
     2215        /* For now disable the shadow of the window. This feature cause errors
     2216         * if a window in vbox looses focus, is reselected and than moved. */
     2217        /** @todo Search for an option to enable this again. A shadow on every
     2218         * window has a big coolness factor. */
     2219        status = ChangeWindowAttributes (windowRef, kWindowNoShadowAttribute, 0);
     2220        AssertCarbonOSStatus (status);
     2221    }
     2222#endif
     2223
     2224    /* Process all console attributes changes and sub-widget hidings */
     2225    qApp->processEvents();
     2226
     2227    /* Send guest size hint */
     2228    console->toggleFSMode (consoleSize);
     2229
     2230    if (!mIsWaitingModeResize)
     2231        onExitFullscreen();
     2232
     2233    /* Unlock FS actions locked during modes toggling */
     2234    QTimer::singleShot (300, this, SLOT (unlockActionsSwitch()));
    22552235
    22562236#ifdef Q_WS_MAC /* wasHidden is wrong on the mac it seems. */
     
    23172297{
    23182298#ifndef Q_WS_MAC
    2319     if (mIsSeamless)
    2320     {
    2321         /* It isn't guaranteed that the guest os set the video mode that
    2322          * we requested. So after all the resizing stuff set the clipping
    2323          * mask and the spacing shifter to the corresponding values. */
    2324         QDesktopWidget *dtw = QApplication::desktop();
    2325         QRect sRect = dtw->screenGeometry (this);
    2326         QRect aRect (aTargetRect);
    2327         mMaskShift.scale (aTargetRect.left(), aTargetRect.top(), Qt::IgnoreAspectRatio);
    2328         /* Set the clipping mask */
    2329         mStrictedRegion = aRect;
    2330         /* Set the shifting spacer */
    2331         mShiftingSpacerLeft->changeSize (RT_ABS (sRect.left() - aRect.left()), 0,
    2332                                          QSizePolicy::Fixed, QSizePolicy::Preferred);
    2333         mShiftingSpacerTop->changeSize (0, RT_ABS (sRect.top() - aRect.top()),
    2334                                         QSizePolicy::Preferred, QSizePolicy::Fixed);
    2335         mShiftingSpacerRight->changeSize (RT_ABS (sRect.right() - aRect.right()), 0,
    2336                                           QSizePolicy::Fixed, QSizePolicy::Preferred);
    2337         mShiftingSpacerBottom->changeSize (0, RT_ABS (sRect.bottom() - aRect.bottom()),
     2299    /* It isn't guaranteed that the guest os set the video mode that
     2300     * we requested. So after all the resizing stuff set the clipping
     2301     * mask and the spacing shifter to the corresponding values. */
     2302    QDesktopWidget *dtw = QApplication::desktop();
     2303    QRect sRect = dtw->screenGeometry (this);
     2304    QRect aRect (aTargetRect);
     2305    mMaskShift.scale (aTargetRect.left(), aTargetRect.top(), Qt::IgnoreAspectRatio);
     2306    /* Set the clipping mask */
     2307    mStrictedRegion = aRect;
     2308    /* Set the shifting spacer */
     2309    mShiftingSpacerLeft->changeSize (RT_ABS (sRect.left() - aRect.left()), 0,
     2310                                     QSizePolicy::Fixed, QSizePolicy::Preferred);
     2311    mShiftingSpacerTop->changeSize (0, RT_ABS (sRect.top() - aRect.top()),
     2312                                    QSizePolicy::Preferred, QSizePolicy::Fixed);
     2313    mShiftingSpacerRight->changeSize (RT_ABS (sRect.right() - aRect.right()), 0,
     2314                                      QSizePolicy::Fixed, QSizePolicy::Preferred);
     2315    mShiftingSpacerBottom->changeSize (0, RT_ABS (sRect.bottom() - aRect.bottom()),
    23382316                                           QSizePolicy::Preferred, QSizePolicy::Fixed);
    2339     }
    23402317#else // !Q_WS_MAC
    23412318    NOREF (aTargetRect);
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