VirtualBox

Changeset 58142 in vbox for trunk


Ignore:
Timestamp:
Oct 9, 2015 12:07:45 PM (9 years ago)
Author:
vboxsync
Message:

FE/Qt: Mac OS X: Zoom botton handling (full-screen/maximize).

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.h

    r55401 r58142  
    2424/* GUI includes: */
    2525#include "VBoxCocoaHelper.h"
     26#include "VBoxUtils-darwin.h"
    2627
    2728ADD_COCOA_NATIVE_REF(UICocoaApplicationPrivate);
     
    2930ADD_COCOA_NATIVE_REF(NSString);
    3031ADD_COCOA_NATIVE_REF(NSWindow);
     32ADD_COCOA_NATIVE_REF(NSButton);
    3133
    3234/* Forward declarations: */
     
    4648/** Native notification callback type for QWidget. */
    4749typedef void (*PfnNativeNotificationCallbackForQWidget)(const QString &strNativeNotificationName, QWidget *pWidget);
     50/** Standard window button callback type for QWidget. */
     51typedef void (*PfnStandardWindowButtonCallbackForQWidget)(StandardWindowButtonType emnButtonType, bool fWithOptionKey, QWidget *pWidget);
    4852
    4953/* C++ singleton for our private NSApplication object. */
     
    8488    void nativeNotificationProxyForWidget(NativeNSStringRef pstrNativeNotificationName, NativeNSWindowRef pWindow);
    8589
     90    /** Register callback for standard window @a buttonType of passed @a pWidget as @a pCallback. */
     91    void registerCallbackForStandardWindowButton(QWidget *pWidget, StandardWindowButtonType enmButtonType, PfnStandardWindowButtonCallbackForQWidget pCallback);
     92    /** Unregister callback for standard window @a buttonType of passed @a pWidget. */
     93    void unregisterCallbackForStandardWindowButton(QWidget *pWidget, StandardWindowButtonType enmButtonType);
     94    /** Redirects standard window button selector to registered callback. */
     95    void nativeCallbackProxyForStandardWindowButton(NativeNSButtonRef pButton, bool fWithOptionKey);
     96
    8697private:
    8798
     
    101112    /** Map of notification callbacks registered for corresponding QWidget(s). */
    102113    QMap<QWidget*, QMap<QString, PfnNativeNotificationCallbackForQWidget> > m_widgetCallbacks;
     114
     115    /** Map of callbacks registered for standard window button(s) of corresponding QWidget(s). */
     116    QMap<QWidget*, QMap<StandardWindowButtonType, PfnStandardWindowButtonCallbackForQWidget> > m_stdWindowButtonCallbacks;
    103117};
    104118
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm

    r52727 r58142  
    1818/* GUI includes: */
    1919#include "UICocoaApplication.h"
    20 #include "VBoxUtils-darwin.h"
    2120
    2221/* Global includes */
     
    2524#import <Foundation/NSArray.h>
    2625#import <AppKit/NSWindow.h>
     26#import <AppKit/NSButton.h>
    2727
    2828#include <iprt/assert.h>
     
    7777- (void)notificationCallbackOfObject :(NSNotification*)notification;
    7878- (void)notificationCallbackOfWindow :(NSNotification*)notification;
     79
     80- (void)registerSelectorForStandardWindowButton :(NSWindow*)pWindow :(StandardWindowButtonType)enmButtonType;
     81- (void)selectorForStandardWindowButton :(NSButton*)pButton;
    7982@end /* @interface UICocoaApplicationPrivate */
    8083
     
    242245    UICocoaApplication::instance()->nativeNotificationProxyForWidget(pstrName, [notification object]);
    243246}
     247
     248/** Registers selector for standard window @a enmButtonType of the passed @a pWindow. */
     249- (void)registerSelectorForStandardWindowButton :(NSWindow*)pWindow :(StandardWindowButtonType)enmButtonType
     250{
     251    /* Retrieve corresponding button: */
     252    NSButton *pButton = Nil;
     253    switch (enmButtonType)
     254    {
     255        case StandardWindowButtonType_Close:            pButton = [pWindow standardWindowButton:NSWindowCloseButton]; break;
     256        case StandardWindowButtonType_Miniaturize:      pButton = [pWindow standardWindowButton:NSWindowMiniaturizeButton]; break;
     257        case StandardWindowButtonType_Zoom:             pButton = [pWindow standardWindowButton:NSWindowZoomButton]; break;
     258        case StandardWindowButtonType_Toolbar:          pButton = [pWindow standardWindowButton:NSWindowToolbarButton]; break;
     259        case StandardWindowButtonType_DocumentIcon:     pButton = [pWindow standardWindowButton:NSWindowDocumentIconButton]; break;
     260        case StandardWindowButtonType_DocumentVersions: /*pButton = [pWindow standardWindowButton:NSWindowDocumentVersionsButton];*/ break;
     261        case StandardWindowButtonType_FullScreen:       /*pButton = [pWindow standardWindowButton:NSWindowFullScreenButton];*/ break;
     262    }
     263
     264    /* Register selector if button exists: */
     265    if (pButton != Nil)
     266    {
     267        [pButton setTarget :self];
     268        [pButton setAction :@selector(selectorForStandardWindowButton:)];
     269    }
     270}
     271
     272/** Redirects selector of the standard window @a pButton to UICocoaApplication instance callback. */
     273- (void)selectorForStandardWindowButton :(NSButton*)pButton
     274{
     275    /* Check if Option key is currently held: */
     276    const bool fWithOptionKey = [NSEvent modifierFlags] & NSAlternateKeyMask;
     277
     278    /* Redirect selector to callback: */
     279    UICocoaApplication::instance()->nativeCallbackProxyForStandardWindowButton(pButton, fWithOptionKey);
     280}
    244281@end /* @implementation UICocoaApplicationPrivate */
    245282
     
    384421}
    385422
     423void UICocoaApplication::registerCallbackForStandardWindowButton(QWidget *pWidget, StandardWindowButtonType enmButtonType,
     424                                                                 PfnStandardWindowButtonCallbackForQWidget pCallback)
     425{
     426    /* Make sure it is not registered yet: */
     427    AssertReturnVoid(!m_stdWindowButtonCallbacks.contains(pWidget) || !m_stdWindowButtonCallbacks.value(pWidget).contains(enmButtonType));
     428
     429    /* Remember callback: */
     430    m_stdWindowButtonCallbacks[pWidget][enmButtonType] = pCallback;
     431
     432    /* Register selector: */
     433    NativeNSWindowRef pWindow = darwinToNativeWindow(pWidget);
     434    [m_pNative registerSelectorForStandardWindowButton :pWindow :enmButtonType];
     435}
     436
     437void UICocoaApplication::unregisterCallbackForStandardWindowButton(QWidget *pWidget, StandardWindowButtonType enmButtonType)
     438{
     439    /* Make sure it is registered yet: */
     440    AssertReturnVoid(m_stdWindowButtonCallbacks.contains(pWidget) && m_stdWindowButtonCallbacks.value(pWidget).contains(enmButtonType));
     441
     442    /* Forget callback: */
     443    m_stdWindowButtonCallbacks[pWidget].remove(enmButtonType);
     444    if (m_stdWindowButtonCallbacks.value(pWidget).isEmpty())
     445        m_stdWindowButtonCallbacks.remove(pWidget);
     446}
     447
     448void UICocoaApplication::nativeCallbackProxyForStandardWindowButton(NativeNSButtonRef pButton, bool fWithOptionKey)
     449{
     450    // Why not using nested foreach, will you ask?
     451    // It's because Qt 4.x has shadowing issue in Q_FOREACH macro.
     452    // Bug record QTBUG-33585 opened for Qt 4.8.4 and closed as _won't fix_ by one of Qt devs.
     453
     454    /* Check if passed button is one of the buttons of the registered widget(s): */
     455    const QList<QWidget*> widgets = m_stdWindowButtonCallbacks.keys();
     456    for (int iWidgetIndex = 0; iWidgetIndex < widgets.size(); ++iWidgetIndex)
     457    {
     458        QWidget *pWidget = widgets.at(iWidgetIndex);
     459        const QMap<StandardWindowButtonType, PfnStandardWindowButtonCallbackForQWidget> callbacks = m_stdWindowButtonCallbacks.value(pWidget);
     460        const QList<StandardWindowButtonType> buttonTypes = callbacks.keys();
     461        for (int iButtonTypeIndex = 0; iButtonTypeIndex < buttonTypes.size(); ++iButtonTypeIndex)
     462        {
     463            StandardWindowButtonType enmButtonType = buttonTypes.at(iButtonTypeIndex);
     464            if (darwinNativeButtonOfWindow(pWidget, enmButtonType) == pButton)
     465                return callbacks.value(enmButtonType)(enmButtonType, fWithOptionKey, pWidget);
     466        }
     467    }
     468}
     469
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm

    r58141 r58142  
    5353
    5454    return view;
     55}
     56
     57NativeNSButtonRef darwinNativeButtonOfWindowImpl(NativeNSWindowRef pWindow, StandardWindowButtonType enmButtonType)
     58{
     59    /* Return corresponding button: */
     60    switch (enmButtonType)
     61    {
     62        case StandardWindowButtonType_Close:            return [pWindow standardWindowButton:NSWindowCloseButton];
     63        case StandardWindowButtonType_Miniaturize:      return [pWindow standardWindowButton:NSWindowMiniaturizeButton];
     64        case StandardWindowButtonType_Zoom:             return [pWindow standardWindowButton:NSWindowZoomButton];
     65        case StandardWindowButtonType_Toolbar:          return [pWindow standardWindowButton:NSWindowToolbarButton];
     66        case StandardWindowButtonType_DocumentIcon:     return [pWindow standardWindowButton:NSWindowDocumentIconButton];
     67        case StandardWindowButtonType_DocumentVersions: /*return [pWindow standardWindowButton:NSWindowDocumentVersionsButton];*/ break;
     68        case StandardWindowButtonType_FullScreen:       /*return [pWindow standardWindowButton:NSWindowFullScreenButton];*/ break;
     69    }
     70    /* Return Nul by default: */
     71    return Nil;
    5572}
    5673
     
    215232    if ([pWindow respondsToSelector: @selector(toggleFullScreen:)])
    216233        [pWindow performSelector: @selector(toggleFullScreen:) withObject: (id)nil];
     234}
     235
     236void darwinToggleWindowZoom(NativeNSWindowRef pWindow)
     237{
     238    /* Toggle native window zoom for passed pWindow. This method is available since 10.0. */
     239    if ([pWindow respondsToSelector: @selector(zoom:)])
     240        [pWindow performSelector: @selector(zoom:)];
    217241}
    218242
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp

    r58141 r58142  
    5757}
    5858
     59NativeNSWindowRef darwinNativeButtonOfWindow(QWidget *pWidget, StandardWindowButtonType enmButtonType)
     60{
     61    return ::darwinNativeButtonOfWindowImpl(::darwinToNativeWindow(pWidget), enmButtonType);
     62}
     63
    5964void darwinSetShowsToolbarButton(QToolBar *aToolBar, bool fEnabled)
    6065{
     
    157162{
    158163    return ::darwinToggleFullscreenMode(::darwinToNativeWindow(pWidget));
     164}
     165
     166void darwinToggleWindowZoom(QWidget *pWidget)
     167{
     168    return ::darwinToggleWindowZoom(::darwinToNativeWindow(pWidget));
    159169}
    160170
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.h

    r58141 r58142  
    2929ADD_COCOA_NATIVE_REF(NSView);
    3030ADD_COCOA_NATIVE_REF(NSWindow);
     31ADD_COCOA_NATIVE_REF(NSButton);
    3132ADD_COCOA_NATIVE_REF(NSString);
    3233
     
    3839class QWidget;
    3940
     41/** Mac OS X: Standard window button types. */
     42enum StandardWindowButtonType
     43{
     44    StandardWindowButtonType_Close,            // Since OS X 10.2
     45    StandardWindowButtonType_Miniaturize,      // Since OS X 10.2
     46    StandardWindowButtonType_Zoom,             // Since OS X 10.2
     47    StandardWindowButtonType_Toolbar,          // Since OS X 10.2
     48    StandardWindowButtonType_DocumentIcon,     // Since OS X 10.2
     49    StandardWindowButtonType_DocumentVersions, // Since OS X 10.7
     50    StandardWindowButtonType_FullScreen        // Since OS X 10.7
     51};
     52
    4053RT_C_DECLS_BEGIN
    4154
     
    4760NativeNSWindowRef darwinToNativeWindowImpl(NativeNSViewRef pView);
    4861NativeNSViewRef darwinToNativeViewImpl(NativeNSWindowRef pWindow);
     62NativeNSButtonRef darwinNativeButtonOfWindowImpl(NativeNSWindowRef pWindow, StandardWindowButtonType enmButtonType);
    4963NativeNSStringRef darwinToNativeString(const char* pcszString);
    5064QString darwinFromNativeString(NativeNSStringRef pString);
     
    8195void darwinEnableTransienceSupport(NativeNSWindowRef pWindow);
    8296void darwinToggleFullscreenMode(NativeNSWindowRef pWindow);
     97void darwinToggleWindowZoom(NativeNSWindowRef pWindow);
    8398bool darwinIsInFullscreenMode(NativeNSWindowRef pWindow);
    8499bool darwinIsOnActiveSpace(NativeNSWindowRef pWindow);
     
    160175 */
    161176NativeNSViewRef darwinToNativeView(NativeNSWindowRef pWindow);
     177
     178/**
     179 * Returns a reference to the native button of QWidget.
     180 *
     181 * @returns corresponding NSButton* of the QWidget.
     182 * @param   pWidget       Brings the pointer to the QWidget.
     183 * @param   enmButtonType Brings the type of the native button required.
     184 */
     185NativeNSButtonRef darwinNativeButtonOfWindow(QWidget *pWidget, StandardWindowButtonType enmButtonType);
    162186
    163187/********************************************************************************
     
    251275void darwinEnableTransienceSupport(QWidget *pWidget);
    252276void darwinToggleFullscreenMode(QWidget *pWidget);
     277void darwinToggleWindowZoom(QWidget *pWidget);
    253278bool darwinIsInFullscreenMode(QWidget *pWidget);
    254279bool darwinIsOnActiveSpace(QWidget *pWidget);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp

    r57178 r58142  
    583583
    584584#ifdef Q_WS_MAC
     585void UIMachineWindow::handleStandardWindowButtonCallback(StandardWindowButtonType enmButtonType, bool fWithOptionKey)
     586{
     587    switch (enmButtonType)
     588    {
     589        case StandardWindowButtonType_Zoom:
     590        {
     591            /* Handle 'Zoom' button for 'Normal' and 'Scaled' modes: */
     592            if (   machineLogic()->visualStateType() == UIVisualStateType_Normal
     593                || machineLogic()->visualStateType() == UIVisualStateType_Scale)
     594            {
     595                if (fWithOptionKey)
     596                {
     597                    /* Toggle window zoom: */
     598                    darwinToggleWindowZoom(this);
     599                }
     600                else
     601                {
     602                    /* Enter 'full-screen' mode: */
     603                    uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
     604                    uisession()->changeVisualState(UIVisualStateType_Fullscreen);
     605                }
     606            }
     607            break;
     608        }
     609        default:
     610            break;
     611    }
     612}
     613
     614/* static */
    585615void UIMachineWindow::handleNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget)
    586616{
     
    588618    LogRel(("GUI: UIMachineWindow::handleNativeNotification: Notification '%s' received\n",
    589619            strNativeNotificationName.toAscii().constData()));
     620    AssertPtrReturnVoid(pWidget);
    590621    if (UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(pWidget))
    591622    {
     
    596627    }
    597628}
     629
     630/* static */
     631void UIMachineWindow::handleStandardWindowButtonCallback(StandardWindowButtonType enmButtonType, bool fWithOptionKey, QWidget *pWidget)
     632{
     633    /* Handle arrived callback: */
     634    LogRel(("GUI: UIMachineWindow::handleStandardWindowButtonCallback: Callback for standard window button '%d' with option key '%d' received\n",
     635            (int)enmButtonType, (int)fWithOptionKey));
     636    AssertPtrReturnVoid(pWidget);
     637    if (UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(pWidget))
     638    {
     639        /* Redirect arrived callback: */
     640        LogRel(("UIMachineWindow::handleStandardWindowButtonCallback: Redirecting callback for standard window button '%d' with option key '%d' to corresponding machine-window...\n",
     641                (int)enmButtonType, (int)fWithOptionKey));
     642        pMachineWindow->handleStandardWindowButtonCallback(enmButtonType, fWithOptionKey);
     643    }
     644}
    598645#endif /* Q_WS_MAC */
    599646
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h

    r57129 r58142  
    2525#include "QIWithRetranslateUI.h"
    2626#include "UIExtraDataDefs.h"
     27#ifdef Q_WS_MAC
     28# include "VBoxUtils-darwin.h"
     29#endif /* Q_WS_MAC */
    2730
    2831/* COM includes: */
     
    128131      * @param  strNativeNotificationName  Native notification name. */
    129132    virtual void handleNativeNotification(const QString & /* strNativeNotificationName */) {}
     133
     134    /** Mac OS X: Handles standard window button callbacks.
     135      * @param  enmButtonType   Brings standard window button type.
     136      * @param  fWithOptionKey  Brings whether the Option key was held. */
     137    virtual void handleStandardWindowButtonCallback(StandardWindowButtonType enmButtonType, bool fWithOptionKey);
    130138#endif /* Q_WS_MAC */
    131139
     
    165173      * @param  pWidget                    Widget, notification related to. */
    166174    static void handleNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget);
     175
     176    /** Mac OS X: Handles standard window button callbacks.
     177      * @param  enmButtonType   Brings standard window button type.
     178      * @param  fWithOptionKey  Brings whether the Option key was held.
     179      * @param  pWidget         Brings widget, callback related to. */
     180    static void handleStandardWindowButtonCallback(StandardWindowButtonType enmButtonType, bool fWithOptionKey, QWidget *pWidget);
    167181#endif /* Q_WS_MAC */
    168182
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp

    r58141 r58142  
    4545#  include "VBoxUtils.h"
    4646#  include "UIImageTools.h"
     47#  include "UICocoaApplication.h"
    4748# endif /* Q_WS_MAC */
    4849
     
    303304        QPixmap betaLabel = ::betaLabel(QSize(100, 16));
    304305        ::darwinLabelWindow(this, &betaLabel, true);
     306    }
     307
     308    /* For 'Yosemite' and above: */
     309    if (vboxGlobal().osRelease() >= MacOSXRelease_Yosemite)
     310    {
     311        /* Enable fullscreen support for every screen which requires it: */
     312        if (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
     313            darwinEnableFullscreenSupport(this);
     314        /* Register 'Zoom' button to use our full-screen: */
     315        UICocoaApplication::instance()->registerCallbackForStandardWindowButton(this, StandardWindowButtonType_Zoom,
     316                                                                                UIMachineWindow::handleStandardWindowButtonCallback);
    305317    }
    306318#endif /* Q_WS_MAC */
     
    389401    /* Call to base-class: */
    390402    UIMachineWindow::saveSettings();
     403}
     404
     405void UIMachineWindowNormal::cleanupVisualState()
     406{
     407#ifdef Q_WS_MAC
     408    /* Unregister 'Zoom' button from using our full-screen since Yosemite: */
     409    if (vboxGlobal().osRelease() >= MacOSXRelease_Yosemite)
     410        UICocoaApplication::instance()->unregisterCallbackForStandardWindowButton(this, StandardWindowButtonType_Zoom);
     411#endif /* Q_WS_MAC */
    391412}
    392413
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h

    r57129 r58142  
    9797    /** Save settings routine. */
    9898    void saveSettings();
     99    /** Cleanup visual-state routine. */
     100    void cleanupVisualState();
    99101    /** Cleanup session connections routine. */
    100102    void cleanupSessionConnections();
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp

    r58141 r58142  
    3636#  include "VBoxUtils.h"
    3737#  include "UIImageTools.h"
     38#  include "UICocoaApplication.h"
    3839# endif /* Q_WS_MAC */
    3940
     
    6970        QPixmap betaLabel = ::betaLabel(QSize(100, 16));
    7071        ::darwinLabelWindow(this, &betaLabel, true);
     72    }
     73
     74    /* For 'Yosemite' and above: */
     75    if (vboxGlobal().osRelease() >= MacOSXRelease_Yosemite)
     76    {
     77        /* Enable fullscreen support for every screen which requires it: */
     78        if (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
     79            darwinEnableFullscreenSupport(this);
     80        /* Register 'Zoom' button to use our full-screen: */
     81        UICocoaApplication::instance()->registerCallbackForStandardWindowButton(this, StandardWindowButtonType_Zoom,
     82                                                                                UIMachineWindow::handleStandardWindowButtonCallback);
    7183    }
    7284}
     
    125137    UIMachineWindow::saveSettings();
    126138}
     139
     140#ifdef Q_WS_MAC
     141void UIMachineWindowScale::cleanupVisualState()
     142{
     143    /* Unregister 'Zoom' button from using our full-screen since Yosemite: */
     144    if (vboxGlobal().osRelease() >= MacOSXRelease_Yosemite)
     145        UICocoaApplication::instance()->unregisterCallbackForStandardWindowButton(this, StandardWindowButtonType_Zoom);
     146}
     147#endif /* Q_WS_MAC */
    127148
    128149void UIMachineWindowScale::showInNecessaryMode()
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.h

    r57027 r58142  
    4646    /** Save settings routine. */
    4747    void saveSettings();
     48#ifdef Q_WS_MAC
     49    /** Cleanup visual-state routine. */
     50    void cleanupVisualState();
     51#endif /* Q_WS_MAC */
    4852
    4953    /** Updates visibility according to visual-state. */
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