From db9a083025e72ba47f472f79f9a79c786999037e Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Wed, 3 Aug 2022 21:29:31 -0700 Subject: [PATCH] Fix non-native full screen on MacBooks with notch This makes sure non-native full screen mode will not use the areas with the notch (which exists in new Apple Silicon MacBooks) when menu bar is configured to not show during non-native full screen. Previously it will use the whole screen which resulted in some texts being clipped by the sensor bar / "notch". Add a new option `MMNonNativeFullScreenSafeAreaBehavior` which allows the user to get the old behavior back by setting it to 1. This allows for maximum display area on a MacBook display, but some content will be obscured by the notch and the rounded corners. This is a command-line-only option for now as it's relatively niche. In the future we could potentially add new types of behaviors (such as showing the tab bar or toolbar in the notch area). Also, fix a manual one-pixel offset in the old menu bar size calculation which was a hack to align things to hide the first row of pixels (which arguably looks better if cursorline is on) but it was actually incorrect. Just don't do the one-pixel hack. --- runtime/doc/gui_mac.txt | 8 ++++++- runtime/doc/tags | 1 + src/MacVim/MMAppController.m | 1 + src/MacVim/MMFullScreenWindow.m | 37 ++++++++++++++++++++++++++------- src/MacVim/MacVim.h | 3 +++ src/MacVim/Miscellaneous.h | 1 + src/MacVim/Miscellaneous.m | 1 + 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt index c41093826a..9151d0f414 100644 --- a/runtime/doc/gui_mac.txt +++ b/runtime/doc/gui_mac.txt @@ -264,6 +264,9 @@ KEY VALUE ~ *MMLoginShellCommand* which shell to use to launch Vim [string] *MMNativeFullScreen* use native full screen mode [bool] *MMNonNativeFullScreenShowMenu* show menus when in non-native full screen [bool] +*MMNonNativeFullScreenSafeAreaBehavior* + behavior for non-native full sreen regarding + the safe area (aka the "notch") [int] *MMNoFontSubstitution* disable automatic font substitution [bool] (Deprecated: Non-CoreText renderer only) *MMFontPreserveLineSpacing* use the line-spacing as specified by font [bool] @@ -330,7 +333,10 @@ There are two types of full screen modes. By default, MacVim uses macOS' native full screen functionality, which creates a separate space in Mission Control. MacVim also provides a non-native full screen mode, which can be set by disabling native full screen in the preference panel, or by setting -|MMNativeFullScreen| to `NO` manually. +|MMNativeFullScreen| to `NO` manually. If you have a MacBook with a "notch" +at the top of the screen, you can set |MMNonNativeFullScreenShowMenu| to `NO` +and |MMNonNativeFullScreenSafeAreaBehavior| to 1 to utilitize the whole screen +(this will cause some of the content to be obscured by the notch). ============================================================================== 5. Special colors *macvim-colors* diff --git a/runtime/doc/tags b/runtime/doc/tags index fd56b0626b..dbfdf054d1 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -5364,6 +5364,7 @@ MMLoginShellCommand gui_mac.txt /*MMLoginShellCommand* MMNativeFullScreen gui_mac.txt /*MMNativeFullScreen* MMNoFontSubstitution gui_mac.txt /*MMNoFontSubstitution* MMNoTitleBarWindow gui_mac.txt /*MMNoTitleBarWindow* +MMNonNativeFullScreenSafeAreaBehavior gui_mac.txt /*MMNonNativeFullScreenSafeAreaBehavior* MMNonNativeFullScreenShowMenu gui_mac.txt /*MMNonNativeFullScreenShowMenu* MMShareFindPboard gui_mac.txt /*MMShareFindPboard* MMShowAddTabButton gui_mac.txt /*MMShowAddTabButton* diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 8a70dec11f..dc617087b3 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -250,6 +250,7 @@ + (void)initialize [NSNumber numberWithBool:YES], MMNativeFullScreenKey, [NSNumber numberWithDouble:0.0], MMFullScreenFadeTimeKey, [NSNumber numberWithBool:NO], MMNonNativeFullScreenShowMenuKey, + [NSNumber numberWithInt:0], MMNonNativeFullScreenSafeAreaBehaviorKey, [NSNumber numberWithBool:YES], MMShareFindPboardKey, nil]; diff --git a/src/MacVim/MMFullScreenWindow.m b/src/MacVim/MMFullScreenWindow.m index d12adddb97..e1973cfc7b 100644 --- a/src/MacVim/MMFullScreenWindow.m +++ b/src/MacVim/MMFullScreenWindow.m @@ -376,14 +376,33 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification [self setFrame:[screen frame] display:NO]; } -/// Get the view vertical offset to allow us space to show the menu bar and what not. -- (CGFloat) viewOffset { +/// Get the view offset to allow us space to show the menu bar, or account for "safe area" (a.k.a. notch) in certain MacBook Pro's. +- (NSEdgeInsets) viewOffset { + NSEdgeInsets offset = NSEdgeInsetsMake(0, 0, 0, 0); + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_12_0) + // Account for newer MacBook Pro's which have a notch, which can be queried using the safe area API. + if ([NSScreen instancesRespondToSelector:@selector(safeAreaInsets)]) { + const int safeAreaBehavior = [[NSUserDefaults standardUserDefaults] + integerForKey:MMNonNativeFullScreenSafeAreaBehaviorKey]; + + // The safe area utilization is configuration. Right now, we only have two choices. + // In the future there may be more, e.g. showing tabs in the safe area. + if (safeAreaBehavior == 0) { + offset = [[self screen] safeAreaInsets]; + } + } +#endif + if ([[NSUserDefaults standardUserDefaults] boolForKey:MMNonNativeFullScreenShowMenuKey]) { - return [[[NSApplication sharedApplication] mainMenu] menuBarHeight]-1; - } else { - return 0; + const CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + if (menuBarHeight > offset.top) { + offset.top = menuBarHeight; + } } + + return offset; } /// Returns the desired frame of the Vim view, which takes fuopts into account @@ -395,16 +414,18 @@ - (CGFloat) viewOffset { - (NSRect)getDesiredFrame; { NSRect windowFrame = [self frame]; + const NSEdgeInsets viewOffset = [self viewOffset]; + windowFrame.size.height -= (viewOffset.top + viewOffset.bottom); + windowFrame.size.width -= (viewOffset.left + viewOffset.right); NSSize desiredFrameSize = windowFrame.size; - desiredFrameSize.height -= [self viewOffset]; if (!(options & FUOPT_MAXVERT)) desiredFrameSize.height = MIN(desiredFrameSize.height, nonFuVimViewSize.height); if (!(options & FUOPT_MAXHORZ)) desiredFrameSize.width = MIN(desiredFrameSize.width, nonFuVimViewSize.width); - NSPoint origin = { floor((windowFrame.size.width - desiredFrameSize.width)/2), - floor((windowFrame.size.height - desiredFrameSize.height)/2 - [self viewOffset] / 2) }; + NSPoint origin = { floor((windowFrame.size.width - desiredFrameSize.width)/2) + viewOffset.left, + floor((windowFrame.size.height - desiredFrameSize.height)/2) + viewOffset.bottom }; return NSMakeRect(origin.x, origin.y, desiredFrameSize.width, desiredFrameSize.height); } diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index 4d0fd07435..7d0e70ca77 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -38,6 +38,9 @@ #ifndef MAC_OS_X_VERSION_10_14 # define MAC_OS_X_VERSION_10_14 101400 #endif +#ifndef MAC_OS_VERSION_12_0 +# define MAC_OS_VERSION_12_0 120000 +#endif #ifndef NSAppKitVersionNumber10_10 # define NSAppKitVersionNumber10_10 1343 diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h index f65094b8be..58f97f65d5 100644 --- a/src/MacVim/Miscellaneous.h +++ b/src/MacVim/Miscellaneous.h @@ -57,6 +57,7 @@ extern NSString *MMNativeFullScreenKey; extern NSString *MMUseMouseTimeKey; extern NSString *MMFullScreenFadeTimeKey; extern NSString *MMNonNativeFullScreenShowMenuKey; +extern NSString *MMNonNativeFullScreenSafeAreaBehaviorKey; // Enum for MMUntitledWindowKey diff --git a/src/MacVim/Miscellaneous.m b/src/MacVim/Miscellaneous.m index 9ee98ee10c..e438bdcbef 100644 --- a/src/MacVim/Miscellaneous.m +++ b/src/MacVim/Miscellaneous.m @@ -53,6 +53,7 @@ NSString *MMUseMouseTimeKey = @"MMUseMouseTime"; NSString *MMFullScreenFadeTimeKey = @"MMFullScreenFadeTime"; NSString *MMNonNativeFullScreenShowMenuKey = @"MMNonNativeFullScreenShowMenu"; +NSString *MMNonNativeFullScreenSafeAreaBehaviorKey = @"MMNonNativeFullScreenSafeAreaBehavior";