@@ -376,29 +376,48 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification
376
376
[self setFrame: [screen frame ] display: NO ];
377
377
}
378
378
379
- // / 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.
379
+ // / Get the view offset to allow us space to show the menu bar, or account for "safe area" (a.k.a.
380
+ // / notch) in certain MacBook Pro's.
380
381
- (NSEdgeInsets ) viewOffset {
381
382
NSEdgeInsets offset = NSEdgeInsetsMake (0 , 0 , 0 , 0 );
382
383
384
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults ];
385
+ const BOOL showMenu = [ud boolForKey: MMNonNativeFullScreenShowMenuKey];
386
+
383
387
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_12_0)
384
388
// Account for newer MacBook Pro's which have a notch, which can be queried using the safe area API.
385
389
if (@available (macos 12.0 , *)) {
386
- const int safeAreaBehavior = [[NSUserDefaults standardUserDefaults ]
387
- integerForKey: MMNonNativeFullScreenSafeAreaBehaviorKey];
388
-
389
- // The safe area utilization is configuration. Right now, we only have two choices.
390
- // In the future there may be more, e.g. showing tabs in the safe area.
391
- if (safeAreaBehavior == 0 ) {
392
- offset = [[self screen ] safeAreaInsets ];
390
+ const int safeAreaBehavior = [ud integerForKey: MMNonNativeFullScreenSafeAreaBehaviorKey];
391
+
392
+ // The safe area utilization is configuration. Right now, we only have two choices:
393
+ // - 0: avoid the safe area (default)
394
+ // - 1: draw into the safe area, which would cause some contents to be obscured.
395
+ // In the future there may be more. E.g. we can draw tabs in the safe area.
396
+ // If menu is shown, we ignore this because this doesn't make sense.
397
+ if (safeAreaBehavior == 0 || showMenu) {
398
+ offset = [self screen ].safeAreaInsets ;
393
399
}
394
400
}
395
401
#endif
396
402
397
- if ([[NSUserDefaults standardUserDefaults ]
398
- boolForKey: MMNonNativeFullScreenShowMenuKey]) {
399
- const CGFloat menuBarHeight = [[[NSApplication sharedApplication ] mainMenu ] menuBarHeight ];
400
- if (menuBarHeight > offset.top ) {
401
- offset.top = menuBarHeight;
403
+ if (showMenu) {
404
+ // Offset by menu height
405
+ if (offset.top == 0 ) {
406
+ const CGFloat menuBarHeight = [[[NSApplication sharedApplication ] mainMenu ] menuBarHeight ];
407
+ if (menuBarHeight > offset.top ) {
408
+ offset.top = menuBarHeight;
409
+ }
410
+ } else {
411
+ // Unfortunately, if there is a notch (safe area != 0), menuBarHeight does *not* return
412
+ // the menu height shown in the main screen, so we need to calculate it otherwise.
413
+ // visibleArea is supposed to give us this information but it's oddly off by one, leading
414
+ // to a one-pixel black line, so we need to manually increment it by one. Yes, it sucks.
415
+ NSRect visibleFrame = [self screen ].visibleFrame ;
416
+ visibleFrame.size .height += 1 ;
417
+ const CGFloat menuBarHeight = [self screen ].frame .size .height - NSMaxY (visibleFrame);
418
+ if (menuBarHeight > offset.top ) {
419
+ offset.top = menuBarHeight;
420
+ }
402
421
}
403
422
}
404
423
@@ -482,6 +501,16 @@ - (BOOL)isOnPrimaryScreen
482
501
return selfScreenNum == primaryScreenNum;
483
502
}
484
503
504
+ // / Returns true when this screen has a dock and menu shown.
505
+ // /
506
+ // / @note
507
+ // / This does not reliably detect whether the dock is on the current screen or
508
+ // / not as there is no API to reliably detect this. We are mostly guessing here
509
+ // / but if the user sets the dock to display on left/right on a horizontal
510
+ // / layout, it may be on the other screen.
511
+ // / Also, technically when not using separate spaces, it's possible for the
512
+ // / menu to be on one screen and dock on the other.
513
+ // / This should be revisited in the future.
485
514
- (BOOL )screenHasDockAndMenu
486
515
{
487
516
return NSScreen .screensHaveSeparateSpaces || [self isOnPrimaryScreen ];
0 commit comments