@@ -134,6 +134,22 @@ - (void)setOptions:(int)opt
134134 options = opt;
135135}
136136
137+ - (void )updatePresentationOptions
138+ {
139+ // Hide Dock and menu bar when going to full screen. Only do so if the current screen
140+ // has a menu bar and dock.
141+ if ([self screenHasDockAndMenu ]) {
142+ const bool showMenu = [[NSUserDefaults standardUserDefaults ]
143+ boolForKey: MMNonNativeFullScreenShowMenuKey];
144+
145+ [NSApplication sharedApplication ].presentationOptions = showMenu ?
146+ NSApplicationPresentationAutoHideDock :
147+ NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
148+ } else {
149+ [NSApplication sharedApplication ].presentationOptions = NSApplicationPresentationDefault;
150+ }
151+ }
152+
137153- (void )enterFullScreen
138154{
139155 ASLogDebug (@" Enter full-screen now" );
@@ -147,16 +163,7 @@ - (void)enterFullScreen
147163 [winController setWindow: nil ];
148164 [target setDelegate: nil ];
149165
150- // Hide Dock and menu bar when going to full screen. Only do so if the current screen
151- // has a menu bar and dock.
152- if ([self screenHasDockAndMenu ]) {
153- const bool showMenu = [[NSUserDefaults standardUserDefaults ]
154- boolForKey: MMNonNativeFullScreenShowMenuKey];
155-
156- [NSApplication sharedApplication ].presentationOptions = showMenu ?
157- NSApplicationPresentationAutoHideDock :
158- NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
159- }
166+ [self updatePresentationOptions ];
160167
161168 // fade to black
162169 Boolean didBlend = NO ;
@@ -376,6 +383,10 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification
376383- (NSEdgeInsets ) viewOffset {
377384 NSEdgeInsets offset = NSEdgeInsetsMake (0 , 0 , 0 , 0 );
378385
386+ NSScreen *screen = [self screen ];
387+ if (screen == nil )
388+ return offset;
389+
379390 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults ];
380391 const BOOL showMenu = [ud boolForKey: MMNonNativeFullScreenShowMenuKey];
381392
@@ -390,29 +401,28 @@ - (NSEdgeInsets) viewOffset {
390401 // In the future there may be more. E.g. we can draw tabs in the safe area.
391402 // If menu is shown, we ignore this because this doesn't make sense.
392403 if (safeAreaBehavior == 0 || showMenu) {
393- offset = [ self screen ] .safeAreaInsets ;
404+ offset = screen.safeAreaInsets ;
394405 }
395406 }
396407#endif
397408
398409 if (showMenu) {
399- // Offset by menu height
400- if (offset.top == 0 ) {
401- const CGFloat menuBarHeight = [[[NSApplication sharedApplication ] mainMenu ] menuBarHeight ];
402- if (menuBarHeight > offset.top ) {
403- offset.top = menuBarHeight;
404- }
405- } else {
406- // Unfortunately, if there is a notch (safe area != 0), menuBarHeight does *not* return
407- // the menu height shown in the main screen, so we need to calculate it otherwise.
408- // visibleArea is supposed to give us this information but it's oddly off by one, leading
409- // to a one-pixel black line, so we need to manually increment it by one. Yes, it sucks.
410- NSRect visibleFrame = [self screen ].visibleFrame ;
411- visibleFrame.size .height += 1 ;
412- const CGFloat menuBarHeight = [self screen ].frame .size .height - NSMaxY (visibleFrame);
413- if (menuBarHeight > offset.top ) {
414- offset.top = menuBarHeight;
415- }
410+ // Offset by menu height. We use NSScreen's visibleFrame which is the
411+ // most reliable way to do so, as NSApp.mainMenu.menuBarHeight could
412+ // give us the wrong height if one screen is a laptop screen with
413+ // notch, or the user has configured to use single Space for all
414+ // screens and we're in a screen without the menu bar.
415+ //
416+ // Quirks of visibleFrame API:
417+ // - It oddly leaves a one pixel gap between menu bar and screen,
418+ // leading to a black bar. We manually adjust for it.
419+ // - It will sometimes leave room for the Dock even when it's
420+ // auto-hidden (depends on screen configuration and OS version). As
421+ // such we just use the max Y component (where the menu is) and
422+ // ignore the rest.
423+ const CGFloat menuBarHeight = NSMaxY (screen.frame ) - NSMaxY (screen.visibleFrame );
424+ if (menuBarHeight > offset.top ) {
425+ offset.top = menuBarHeight - 1 ;
416426 }
417427 }
418428
@@ -514,14 +524,7 @@ - (BOOL)screenHasDockAndMenu
514524- (void )windowDidBecomeMain : (NSNotification *)notification
515525{
516526 // Hide menu and dock when this window gets focus.
517- if ([self screenHasDockAndMenu ]) {
518- const bool showMenu = [[NSUserDefaults standardUserDefaults ]
519- boolForKey: MMNonNativeFullScreenShowMenuKey];
520-
521- [NSApplication sharedApplication ].presentationOptions = showMenu ?
522- NSApplicationPresentationAutoHideDock :
523- NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
524- }
527+ [self updatePresentationOptions ];
525528}
526529
527530
@@ -530,9 +533,7 @@ - (void)windowDidResignMain:(NSNotification *)notification
530533 // Un-hide menu/dock when we lose focus. This makes sure if we have multiple
531534 // windows opened, when the non-fullscreen windows get focus they will have the
532535 // dock and menu showing (since presentationOptions is per-app, not per-window).
533- if ([self screenHasDockAndMenu ]) {
534- [NSApplication sharedApplication ].presentationOptions = NSApplicationPresentationDefault;
535- }
536+ [NSApplication sharedApplication ].presentationOptions = NSApplicationPresentationDefault;
536537}
537538
538539- (void )windowDidMove : (NSNotification *)notification
@@ -558,6 +559,10 @@ - (void)windowDidMove:(NSNotification *)notification
558559 // Ensure the full-screen window is still covering the entire screen and
559560 // then resize view according to 'fuopt'.
560561 [self setFrame: [screen frame ] display: NO ];
562+
563+ if ([self isMainWindow ]) {
564+ [self updatePresentationOptions ];
565+ }
561566}
562567
563568@end // MMFullScreenWindow (Private)
0 commit comments