From 7f9c11f94a8d3304ccf1babd2fbaa785f1aee280 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Tue, 8 Oct 2019 21:03:30 +0000 Subject: [PATCH] Bug 1581433 - Maximize or minimize the window when double clicking the titlebar. r=spohl This was already working for toolbars, but it wasn't working for the titlebar in windows that actually have a real separate titlebar. All our windows use NSFullSizeContentViewWindowMask, so we no longer get this behavior for free. In windows with titlebars, the titlebar area is covered with a TitlebarGradientView, so that's where we need to handle the double clicks. Differential Revision: https://phabricator.services.mozilla.com/D48593 --HG-- extra : moz-landing-system : lando --- widget/cocoa/nsChildView.mm | 38 +++------------------------------- widget/cocoa/nsCocoaUtils.h | 12 +++++++++++ widget/cocoa/nsCocoaUtils.mm | 39 +++++++++++++++++++++++++++++++++++ widget/cocoa/nsCocoaWindow.mm | 13 ++++++++++-- 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 73b53a844c9b..30d22dd46841 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -226,10 +226,6 @@ static NSMutableDictionary* sNativeKeyEventsMap = [NSMutableDictionary dictionar - (float)roundedCornerRadius; @end -@interface NSWindow (NSWindowShouldZoomOnDoubleClick) -+ (BOOL)_shouldZoomOnDoubleClick; // present on 10.7 and above -@end - // Starting with 10.7 the bottom corners of all windows are rounded. // Unfortunately, the standard rounding that OS X applies to OpenGL views // does not use anti-aliasing and looks very crude. Since we want a smooth, @@ -4320,11 +4316,10 @@ NSEvent* gLastDragMouseDownEvent = nil; // [strong] // Check to see if we are double-clicking in draggable parts of the window. if (!defaultPrevented && [theEvent clickCount] == 2 && !mGeckoChild->GetNonDraggableRegion().Contains(pos.x, pos.y)) { - if ([self shouldZoomOnDoubleClick]) { + if (nsCocoaUtils::ShouldZoomOnTitlebarDoubleClick()) { [[self window] performZoom:nil]; - } else if ([self shouldMinimizeOnTitlebarDoubleClick]) { - NSButton* minimizeButton = [[self window] standardWindowButton:NSWindowMiniaturizeButton]; - [minimizeButton performClick:self]; + } else if (nsCocoaUtils::ShouldMinimizeOnTitlebarDoubleClick()) { + [[self window] performMiniaturize:nil]; } } @@ -4864,33 +4859,6 @@ static gfx::IntPoint GetIntegerDeltaForEvent(NSEvent* aEvent) { NS_OBJC_END_TRY_ABORT_BLOCK } -- (BOOL)shouldZoomOnDoubleClick { - if ([NSWindow respondsToSelector:@selector(_shouldZoomOnDoubleClick)]) { - return [NSWindow _shouldZoomOnDoubleClick]; - } - return nsCocoaFeatures::OnYosemiteOrLater(); -} - -- (BOOL)shouldMinimizeOnTitlebarDoubleClick { - // Check the system preferences. - // We could also check -[NSWindow _shouldMiniaturizeOnDoubleClick]. It's not clear to me which - // approach would be preferable; neither is public API. - NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; - - // Pre-10.11: - NSString* kAppleMiniaturizeOnDoubleClickKey = @"AppleMiniaturizeOnDoubleClick"; - id value1 = [userDefaults objectForKey:kAppleMiniaturizeOnDoubleClickKey]; - if ([value1 isKindOfClass:[NSValue class]] && [value1 boolValue]) { - return YES; - } - - // 10.11+: - NSString* kAppleActionOnDoubleClickKey = @"AppleActionOnDoubleClick"; - NSString* kMinimizeValue = @"Minimize"; - id value2 = [userDefaults objectForKey:kAppleActionOnDoubleClickKey]; - return ([value2 isKindOfClass:[NSString class]] && [value2 isEqualToString:kMinimizeValue]); -} - #pragma mark - // NSTextInputClient implementation diff --git a/widget/cocoa/nsCocoaUtils.h b/widget/cocoa/nsCocoaUtils.h index ed22e27cbebc..473b1787d9aa 100644 --- a/widget/cocoa/nsCocoaUtils.h +++ b/widget/cocoa/nsCocoaUtils.h @@ -388,6 +388,18 @@ class nsCocoaUtils { */ static mozilla::TimeStamp GetEventTimeStamp(NSTimeInterval aEventTime); + /** + * Check whether double clicking on the titlebar should cause the window to + * zoom (maximize). + */ + static bool ShouldZoomOnTitlebarDoubleClick(); + + /** + * Check whether double clicking on the titlebar should cause the window to + * minimize. + */ + static bool ShouldMinimizeOnTitlebarDoubleClick(); + /** * Get the current video capture permission status. * Returns NS_ERROR_NOT_IMPLEMENTED on 10.13 and earlier macOS versions. diff --git a/widget/cocoa/nsCocoaUtils.mm b/widget/cocoa/nsCocoaUtils.mm index f07547246a79..4f4a15a7f09d 100644 --- a/widget/cocoa/nsCocoaUtils.mm +++ b/widget/cocoa/nsCocoaUtils.mm @@ -1088,6 +1088,45 @@ TimeStamp nsCocoaUtils::GetEventTimeStamp(NSTimeInterval aEventTime) { return TimeStamp::FromSystemTime(tick); } +static NSString* ActionOnDoubleClickSystemPref() { + NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; + NSString* kAppleActionOnDoubleClickKey = @"AppleActionOnDoubleClick"; + id value = [userDefaults objectForKey:kAppleActionOnDoubleClickKey]; + if ([value isKindOfClass:[NSString class]]) { + return value; + } + return nil; +} + +@interface NSWindow (NSWindowShouldZoomOnDoubleClick) ++ (BOOL)_shouldZoomOnDoubleClick; // present on 10.7 and above +@end + +bool nsCocoaUtils::ShouldZoomOnTitlebarDoubleClick() { + if ([NSWindow respondsToSelector:@selector(_shouldZoomOnDoubleClick)]) { + return [NSWindow _shouldZoomOnDoubleClick]; + } + if (nsCocoaFeatures::OnElCapitanOrLater()) { + return [ActionOnDoubleClickSystemPref() isEqualToString:@"Maximize"]; + } + return false; +} + +bool nsCocoaUtils::ShouldMinimizeOnTitlebarDoubleClick() { + // Check the system preferences. + // We could also check -[NSWindow _shouldMiniaturizeOnDoubleClick]. It's not clear to me which + // approach would be preferable; neither is public API. + if (nsCocoaFeatures::OnElCapitanOrLater()) { + return [ActionOnDoubleClickSystemPref() isEqualToString:@"Minimize"]; + } + + // Pre-10.11: + NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; + NSString* kAppleMiniaturizeOnDoubleClickKey = @"AppleMiniaturizeOnDoubleClick"; + id value1 = [userDefaults objectForKey:kAppleMiniaturizeOnDoubleClickKey]; + return [value1 isKindOfClass:[NSValue class]] && [value1 boolValue]; +} + // AVAuthorizationStatus is not needed unless we are running on 10.14. // However, on pre-10.14 SDK's, AVAuthorizationStatus and its enum values // are both defined and prohibited from use by compile-time checks. We diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 7a63e2eee9e9..0fa6a53c0e5f 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -3206,8 +3206,17 @@ static const NSString* kStateWantsTitleDrawn = @"wantsTitleDrawn"; return YES; } -- (NSView*)hitTest:(NSPoint)aPoint { - return nil; +- (void)mouseUp:(NSEvent*)event { + if ([event clickCount] == 2) { + // Handle titlebar double click. We don't get the window's default behavior here because the + // window uses NSFullSizeContentViewWindowMask, and this view (the titlebar gradient view) is + // technically part of the window "contents" (it's a subview of the content view). + if (nsCocoaUtils::ShouldZoomOnTitlebarDoubleClick()) { + [[self window] performZoom:nil]; + } else if (nsCocoaUtils::ShouldMinimizeOnTitlebarDoubleClick()) { + [[self window] performMiniaturize:nil]; + } + } } @end