From 062e9661383e26bbddee450281788724b87bf017 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 10 Nov 2021 19:52:56 +0000 Subject: [PATCH] NSViewComponentPeer: Fix zoom and fullscreen behaviour --- .../native/juce_mac_NSViewComponentPeer.mm | 102 +++++++----------- 1 file changed, 38 insertions(+), 64 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index e4e225cd7d..1f30ad5a20 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -137,7 +137,7 @@ public: [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0]; [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0]; - if ((windowStyleFlags & (windowHasMaximiseButton | windowHasTitleBar)) == (windowHasMaximiseButton | windowHasTitleBar)) + if ((windowStyleFlags & windowHasMaximiseButton) == windowHasMaximiseButton) [window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; [window setRestorable: NO]; @@ -264,10 +264,8 @@ public: } } - void setBounds (const Rectangle& newBounds, bool isNowFullScreen) override + void setBounds (const Rectangle& newBounds, bool) override { - fullScreen = isNowFullScreen; - auto r = makeNSRect (newBounds); auto oldViewSize = [view frame].size; @@ -353,39 +351,29 @@ public: { if (! isSharedWindow) { - auto r = lastNonFullscreenBounds; - if (isMinimised()) setMinimised (false); - if (fullScreen != shouldBeFullScreen) + if (hasNativeTitleBar()) { - if (shouldBeFullScreen && hasNativeTitleBar()) - { - fullScreen = true; - [window performZoom: nil]; - } - else - { - if (shouldBeFullScreen) - r = component.getParentMonitorArea(); - - // (can't call the component's setBounds method because that'll reset our fullscreen flag) - if (r != component.getBounds() && ! r.isEmpty()) - setBounds (ScalingHelpers::scaledScreenPosToUnscaled (component, r), shouldBeFullScreen); - } + if (shouldBeFullScreen != isFullScreen()) + [window toggleFullScreen: nil]; + } + else + { + [window zoom: nil]; } } } bool isFullScreen() const override { - return fullScreen; + return ([window styleMask] & NSWindowStyleMaskFullScreen) != 0; } bool isKioskMode() const override { - return isWindowInKioskMode || ComponentPeer::isKioskMode(); + return isFullScreen() && ComponentPeer::isKioskMode(); } static bool isWindowAtPoint (NSWindow* w, NSPoint screenPoint) @@ -444,22 +432,6 @@ public: return b; } - void updateFullscreenStatus() - { - if (hasNativeTitleBar()) - { - isWindowInKioskMode = (([window styleMask] & NSWindowStyleMaskFullScreen) != 0); - - auto screen = getFrameSize().subtractedFrom (component.getParentMonitorArea()); - - fullScreen = component.getScreenBounds().expanded (2, 2).contains (screen); - } - else - { - isWindowInKioskMode = false; - } - } - bool hasNativeTitleBar() const { return (getStyleFlags() & windowHasTitleBar) != 0; @@ -1091,7 +1063,6 @@ public: void redirectMovedOrResized() { - updateFullscreenStatus(); handleMovedOrResized(); } @@ -1168,7 +1139,7 @@ public: NSRect constrainRect (const NSRect r) { - if (constrainer == nullptr || isKioskMode()) + if (constrainer == nullptr || isKioskMode() || isFullScreen()) return r; const auto scale = getComponent().getDesktopScaleFactor(); @@ -1501,8 +1472,7 @@ public: NSWindow* window = nil; NSView* view = nil; WeakReference safeComponent; - bool isSharedWindow = false, fullScreen = false; - bool isWindowInKioskMode = false; + bool isSharedWindow = false; #if USE_COREGRAPHICS_RENDERING bool usingCoreGraphics = true; #else @@ -1693,6 +1663,7 @@ private: const auto minSize = NSMakeSize (static_cast (c.getMinimumWidth()), 0.0f); [window setMinFullScreenContentSize: minSize]; + [window setMaxFullScreenContentSize: NSMakeSize (100000, 100000)]; } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponentPeer) @@ -2223,11 +2194,12 @@ struct JuceNSWindowClass : public NSViewComponentPeerWrappergetConstrainer()) + { + return flippedScreenRect (makeNSRect (owner->getFrameSize().addedTo (owner->getComponent().getScreenBounds() + .withWidth (constrainer->getMaximumWidth()) + .withHeight (constrainer->getMaximumHeight())))); + } + } + + return makeNSRect (Rectangle (10000, 10000)); + } + + static BOOL windowShouldZoomToFrame (id, SEL, NSWindow* window, NSRect frame) + { + return convertToRectFloat ([window frame]).withZeroOrigin() != convertToRectFloat (frame).withZeroOrigin(); + } + static BOOL canBecomeKeyWindow (id self, SEL) { auto* owner = getOwner (self); @@ -2344,19 +2335,6 @@ private: [owner->window setStyleMask: NSWindowStyleMaskBorderless]; } - static void zoom (id self, SEL, id sender) - { - if (auto* owner = getOwner (self)) - { - { - const ScopedValueSetter svs (owner->isZooming, true); - sendSuperclassMessage (self, @selector (zoom:), sender); - } - - owner->redirectMovedOrResized(); - } - } - static void windowWillStartLiveResize (id self, SEL, NSNotification*) { if (auto* owner = getOwner (self)) @@ -2471,23 +2449,19 @@ void Desktop::setKioskComponent (Component* kioskComp, bool shouldBeEnabled, boo auto* peer = dynamic_cast (kioskComp->getPeer()); jassert (peer != nullptr); // (this should have been checked by the caller) - if (peer->hasNativeTitleBar() - && [peer->window respondsToSelector: @selector (toggleFullScreen:)]) + if (peer->hasNativeTitleBar()) { if (shouldBeEnabled && ! allowMenusAndBars) [NSApp setPresentationOptions: NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar]; else if (! shouldBeEnabled) [NSApp setPresentationOptions: NSApplicationPresentationDefault]; - [peer->window performSelector: @selector (toggleFullScreen:) withObject: nil]; + [peer->window toggleFullScreen: nil]; } else { if (shouldBeEnabled) { - if (peer->hasNativeTitleBar()) - [peer->window setStyleMask: NSWindowStyleMaskBorderless]; - [NSApp setPresentationOptions: (allowMenusAndBars ? (NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar) : (NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar))];