From 479629e4601ceb2ac5c8d1c5e172ff7e082653f0 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Sat, 26 Dec 2020 23:39:37 -0800 Subject: [PATCH] Fix non-native fullscreen not hiding menu/dock in secondary screens Previously non-native full scrren mode would only hide the menu bar and dock when used in the primary screen. This made sense in 10.7 Lion because only the primary screen would have the menu/dock. However, 10.9 Mavericks introduced a new default where each screen would now have its own space, and therefore menu bar and dock. Make non-native full screen mode aware of this and make sure to hide the menu bar and dock when it needs to. Fix #7. --- src/MacVim/MMFullScreenWindow.m | 52 +++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/MacVim/MMFullScreenWindow.m b/src/MacVim/MMFullScreenWindow.m index 74e07b6524..c18f4ab983 100644 --- a/src/MacVim/MMFullScreenWindow.m +++ b/src/MacVim/MMFullScreenWindow.m @@ -29,7 +29,6 @@ #import "MMVimView.h" #import "MMWindowController.h" #import "Miscellaneous.h" -#import #import // These have to be the same as in option.h @@ -47,6 +46,7 @@ @interface MMFullScreenWindow (Private) - (BOOL)isOnPrimaryScreen; +- (BOOL)screenHasDockAndMenu; - (void)windowDidBecomeMain:(NSNotification *)notification; - (void)windowDidResignMain:(NSNotification *)notification; - (void)windowDidMove:(NSNotification *)notification; @@ -137,10 +137,12 @@ - (void)enterFullScreen { ASLogDebug(@"Enter full-screen now"); - // Hide Dock and menu bar now to avoid the hide animation from playing - // after the fade to black (see also windowDidBecomeMain:). - if ([self isOnPrimaryScreen]) - SetSystemUIMode(kUIModeAllSuppressed, 0); + // Hide Dock and menu bar when going to full screen. Only do so if the current screen + // has a menu bar and dock. + if ([self screenHasDockAndMenu]) { + [NSApplication sharedApplication].presentationOptions = + NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar; + } // fade to black Boolean didBlend = NO; @@ -441,32 +443,38 @@ - (BOOL)isOnPrimaryScreen if (screens == nil || [screens count] < 1) return NO; - return [self screen] == [screens objectAtIndex:0]; + NSScreen* primaryScreen = [screens objectAtIndex:0]; + + // We cannot compare the NSScreen pointers directly because they are not + // guaranteed to match. Instead use the screen number as a more canonical + // way to compare them. + NSNumber* primaryScreenNum = primaryScreen.deviceDescription[@"NSScreenNumber"]; + NSNumber* selfScreenNum = [self screen].deviceDescription[@"NSScreenNumber"]; + return selfScreenNum == primaryScreenNum; } -- (void)windowDidBecomeMain:(NSNotification *)notification +- (BOOL)screenHasDockAndMenu { - // Hide menu and dock, both appear on demand. - // - // Another way to deal with several full-screen windows would be to hide/ - // reveal the dock only when the first full-screen window is created and - // show it again after the last one has been closed, but toggling on each - // focus gain/loss works better with Spaces. The downside is that the - // menu bar flashes shortly when switching between two full-screen windows. - - // XXX: If you have a full-screen window on a secondary monitor and unplug - // the monitor, this will probably not work right. + return NSScreen.screensHaveSeparateSpaces || [self isOnPrimaryScreen]; +} - if ([self isOnPrimaryScreen]) { - SetSystemUIMode(kUIModeAllSuppressed, 0); //requires 10.3 +- (void)windowDidBecomeMain:(NSNotification *)notification +{ + // Hide menu and dock when this window gets focus. + if ([self screenHasDockAndMenu]) { + [NSApplication sharedApplication].presentationOptions = + NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar; } } + - (void)windowDidResignMain:(NSNotification *)notification { - // order menu and dock back in - if ([self isOnPrimaryScreen]) { - SetSystemUIMode(kUIModeNormal, 0); + // Un-hide menu/dock when we lose focus. This makes sure if we have multiple + // windows opened, when the non-fullscreen windows get focus they will have the + // dock and menu showing (since presentationOptions is per-app, not per-window). + if ([self screenHasDockAndMenu]) { + [NSApplication sharedApplication].presentationOptions = NSApplicationPresentationDefault; } }