@@ -134,6 +134,22 @@ - (void)setOptions:(int)opt
134
134
options = opt;
135
135
}
136
136
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
+
137
153
- (void )enterFullScreen
138
154
{
139
155
ASLogDebug (@" Enter full-screen now" );
@@ -147,16 +163,7 @@ - (void)enterFullScreen
147
163
[winController setWindow: nil ];
148
164
[target setDelegate: nil ];
149
165
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 ];
160
167
161
168
// fade to black
162
169
Boolean didBlend = NO ;
@@ -376,6 +383,10 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification
376
383
- (NSEdgeInsets ) viewOffset {
377
384
NSEdgeInsets offset = NSEdgeInsetsMake (0 , 0 , 0 , 0 );
378
385
386
+ NSScreen *screen = [self screen ];
387
+ if (screen == nil )
388
+ return offset;
389
+
379
390
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults ];
380
391
const BOOL showMenu = [ud boolForKey: MMNonNativeFullScreenShowMenuKey];
381
392
@@ -390,29 +401,28 @@ - (NSEdgeInsets) viewOffset {
390
401
// In the future there may be more. E.g. we can draw tabs in the safe area.
391
402
// If menu is shown, we ignore this because this doesn't make sense.
392
403
if (safeAreaBehavior == 0 || showMenu) {
393
- offset = [ self screen ] .safeAreaInsets ;
404
+ offset = screen.safeAreaInsets ;
394
405
}
395
406
}
396
407
#endif
397
408
398
409
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 ) - 1 ;
424
+ if (menuBarHeight > offset.top ) {
425
+ offset.top = menuBarHeight;
416
426
}
417
427
}
418
428
@@ -514,14 +524,7 @@ - (BOOL)screenHasDockAndMenu
514
524
- (void )windowDidBecomeMain : (NSNotification *)notification
515
525
{
516
526
// 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 ];
525
528
}
526
529
527
530
@@ -530,9 +533,7 @@ - (void)windowDidResignMain:(NSNotification *)notification
530
533
// Un-hide menu/dock when we lose focus. This makes sure if we have multiple
531
534
// windows opened, when the non-fullscreen windows get focus they will have the
532
535
// 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;
536
537
}
537
538
538
539
- (void )windowDidMove : (NSNotification *)notification
@@ -558,6 +559,10 @@ - (void)windowDidMove:(NSNotification *)notification
558
559
// Ensure the full-screen window is still covering the entire screen and
559
560
// then resize view according to 'fuopt'.
560
561
[self setFrame: [screen frame ] display: NO ];
562
+
563
+ if ([self isMainWindow ]) {
564
+ [self updatePresentationOptions ];
565
+ }
561
566
}
562
567
563
568
@end // MMFullScreenWindow (Private)
0 commit comments