diff --git a/src/MacVim/Base.lproj/Preferences.xib b/src/MacVim/Base.lproj/Preferences.xib
index 893ae01353..6d70bccb9f 100644
--- a/src/MacVim/Base.lproj/Preferences.xib
+++ b/src/MacVim/Base.lproj/Preferences.xib
@@ -507,6 +507,7 @@
+
diff --git a/src/MacVim/MMAppController.h b/src/MacVim/MMAppController.h
index f97c028c76..a7ceeba1b5 100644
--- a/src/MacVim/MMAppController.h
+++ b/src/MacVim/MMAppController.h
@@ -83,11 +83,13 @@
- (NSArray *)filterOpenFiles:(NSArray *)filenames;
- (BOOL)openFiles:(NSArray *)filenames withArguments:(NSDictionary *)args;
+// Refresh functions are used by preference pane to push through settings changes
- (void)refreshAllAppearances;
- (void)refreshAllTabProperties;
- (void)refreshAllFonts;
- (void)refreshAllResizeConstraints;
- (void)refreshAllTextViews;
+- (void)refreshAllFullScreenPresentationOptions;
- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate extraArgs:(NSArray *)args;
- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate;
diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m
index 89d347609e..393ddd502e 100644
--- a/src/MacVim/MMAppController.m
+++ b/src/MacVim/MMAppController.m
@@ -38,6 +38,7 @@
*/
#import "MMAppController.h"
+#import "MMFullScreenWindow.h"
#import "MMPreferenceController.h"
#import "MMVimController.h"
#import "MMVimView.h"
@@ -1272,6 +1273,19 @@ - (void)refreshAllTextViews
}
}
+/// Refresh all non-native full screen windows to update their presentation
+/// options (show/hide menu and dock).
+- (void)refreshAllFullScreenPresentationOptions
+{
+ for (MMVimController *vc in vimControllers) {
+ MMFullScreenWindow *fullScreenWindow = vc.windowController.fullScreenWindow;
+ if (fullScreenWindow != nil) {
+ [fullScreenWindow updatePresentationOptions];
+ [vc.windowController resizeVimView];
+ }
+ }
+}
+
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
if ([item action] == @selector(showWhatsNew:)) {
diff --git a/src/MacVim/MMFullScreenWindow.h b/src/MacVim/MMFullScreenWindow.h
index 34519dbc7e..b432011aae 100644
--- a/src/MacVim/MMFullScreenWindow.h
+++ b/src/MacVim/MMFullScreenWindow.h
@@ -35,6 +35,7 @@
- (MMFullScreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
backgroundColor:(NSColor *)back;
- (void)setOptions:(int)opt;
+- (void)updatePresentationOptions;
- (void)enterFullScreen;
- (void)leaveFullScreen;
- (NSRect)getDesiredFrame;
diff --git a/src/MacVim/MMFullScreenWindow.m b/src/MacVim/MMFullScreenWindow.m
index 78bfeb1ec3..c4cbb23c48 100644
--- a/src/MacVim/MMFullScreenWindow.m
+++ b/src/MacVim/MMFullScreenWindow.m
@@ -134,6 +134,22 @@ - (void)setOptions:(int)opt
options = opt;
}
+- (void)updatePresentationOptions
+{
+ // 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]) {
+ const bool showMenu = [[NSUserDefaults standardUserDefaults]
+ boolForKey:MMNonNativeFullScreenShowMenuKey];
+
+ [NSApplication sharedApplication].presentationOptions = showMenu ?
+ NSApplicationPresentationAutoHideDock :
+ NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
+ } else {
+ [NSApplication sharedApplication].presentationOptions = NSApplicationPresentationDefault;
+ }
+}
+
- (void)enterFullScreen
{
ASLogDebug(@"Enter full-screen now");
@@ -147,16 +163,7 @@ - (void)enterFullScreen
[winController setWindow:nil];
[target setDelegate:nil];
- // 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]) {
- const bool showMenu = [[NSUserDefaults standardUserDefaults]
- boolForKey:MMNonNativeFullScreenShowMenuKey];
-
- [NSApplication sharedApplication].presentationOptions = showMenu ?
- NSApplicationPresentationAutoHideDock :
- NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
- }
+ [self updatePresentationOptions];
// fade to black
Boolean didBlend = NO;
@@ -376,6 +383,10 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification
- (NSEdgeInsets) viewOffset {
NSEdgeInsets offset = NSEdgeInsetsMake(0, 0, 0, 0);
+ NSScreen *screen = [self screen];
+ if (screen == nil)
+ return offset;
+
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
const BOOL showMenu = [ud boolForKey:MMNonNativeFullScreenShowMenuKey];
@@ -390,29 +401,28 @@ - (NSEdgeInsets) viewOffset {
// In the future there may be more. E.g. we can draw tabs in the safe area.
// If menu is shown, we ignore this because this doesn't make sense.
if (safeAreaBehavior == 0 || showMenu) {
- offset = [self screen].safeAreaInsets;
+ offset = screen.safeAreaInsets;
}
}
#endif
if (showMenu) {
- // Offset by menu height
- if (offset.top == 0) {
- const CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- if (menuBarHeight > offset.top) {
- offset.top = menuBarHeight;
- }
- } else {
- // Unfortunately, if there is a notch (safe area != 0), menuBarHeight does *not* return
- // the menu height shown in the main screen, so we need to calculate it otherwise.
- // visibleArea is supposed to give us this information but it's oddly off by one, leading
- // to a one-pixel black line, so we need to manually increment it by one. Yes, it sucks.
- NSRect visibleFrame = [self screen].visibleFrame;
- visibleFrame.size.height += 1;
- const CGFloat menuBarHeight = [self screen].frame.size.height - NSMaxY(visibleFrame);
- if (menuBarHeight > offset.top) {
- offset.top = menuBarHeight;
- }
+ // Offset by menu height. We use NSScreen's visibleFrame which is the
+ // most reliable way to do so, as NSApp.mainMenu.menuBarHeight could
+ // give us the wrong height if one screen is a laptop screen with
+ // notch, or the user has configured to use single Space for all
+ // screens and we're in a screen without the menu bar.
+ //
+ // Quirks of visibleFrame API:
+ // - It oddly leaves a one pixel gap between menu bar and screen,
+ // leading to a black bar. We manually adjust for it.
+ // - It will sometimes leave room for the Dock even when it's
+ // auto-hidden (depends on screen configuration and OS version). As
+ // such we just use the max Y component (where the menu is) and
+ // ignore the rest.
+ const CGFloat menuBarHeight = NSMaxY(screen.frame) - NSMaxY(screen.visibleFrame) - 1;
+ if (menuBarHeight > offset.top) {
+ offset.top = menuBarHeight;
}
}
@@ -514,14 +524,7 @@ - (BOOL)screenHasDockAndMenu
- (void)windowDidBecomeMain:(NSNotification *)notification
{
// Hide menu and dock when this window gets focus.
- if ([self screenHasDockAndMenu]) {
- const bool showMenu = [[NSUserDefaults standardUserDefaults]
- boolForKey:MMNonNativeFullScreenShowMenuKey];
-
- [NSApplication sharedApplication].presentationOptions = showMenu ?
- NSApplicationPresentationAutoHideDock :
- NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
- }
+ [self updatePresentationOptions];
}
@@ -530,9 +533,7 @@ - (void)windowDidResignMain:(NSNotification *)notification
// 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;
- }
+ [NSApplication sharedApplication].presentationOptions = NSApplicationPresentationDefault;
}
- (void)windowDidMove:(NSNotification *)notification
@@ -558,6 +559,10 @@ - (void)windowDidMove:(NSNotification *)notification
// Ensure the full-screen window is still covering the entire screen and
// then resize view according to 'fuopt'.
[self setFrame:[screen frame] display:NO];
+
+ if ([self isMainWindow]) {
+ [self updatePresentationOptions];
+ }
}
@end // MMFullScreenWindow (Private)
diff --git a/src/MacVim/MMPreferenceController.h b/src/MacVim/MMPreferenceController.h
index e705f4e3a2..5cc152616a 100644
--- a/src/MacVim/MMPreferenceController.h
+++ b/src/MacVim/MMPreferenceController.h
@@ -40,5 +40,6 @@
// Appearance pane
- (IBAction)fontPropertiesChanged:(id)sender;
- (IBAction)tabsPropertiesChanged:(id)sender;
+- (IBAction)nonNativeFullScreenShowMenuChanged:(id)sender;
@end
diff --git a/src/MacVim/MMPreferenceController.m b/src/MacVim/MMPreferenceController.m
index 4a615da45b..32f19ee84f 100644
--- a/src/MacVim/MMPreferenceController.m
+++ b/src/MacVim/MMPreferenceController.m
@@ -182,4 +182,9 @@ - (IBAction)cmdlineAlignBottomChanged:(id)sender
[[MMAppController sharedInstance] refreshAllTextViews];
}
+- (IBAction)nonNativeFullScreenShowMenuChanged:(id)sender
+{
+ [[MMAppController sharedInstance] refreshAllFullScreenPresentationOptions];
+}
+
@end
diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h
index fc35589118..3656ea22be 100644
--- a/src/MacVim/MMVimController.h
+++ b/src/MacVim/MMVimController.h
@@ -60,6 +60,8 @@
/// E.g. ".AppleSystemUIFontMonospaced-Medium" -> "-monospace-Medium"
@property (nonatomic, readonly) NSMutableDictionary* systemFontNamesToAlias;
+@property (nonatomic, readonly) BOOL isHandlingInputQueue;
+
- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
- (void)uninitialize;
- (unsigned long)vimControllerId;
diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m
index bff551ac1d..de6b9d0964 100644
--- a/src/MacVim/MMVimController.m
+++ b/src/MacVim/MMVimController.m
@@ -557,6 +557,8 @@ - (void)processInputQueue:(NSArray *)queue
{
if (!isInitialized) return;
+ _isHandlingInputQueue = YES;
+
// NOTE: This method must not raise any exceptions (see comment in the
// calling method).
@try {
@@ -566,6 +568,7 @@ - (void)processInputQueue:(NSArray *)queue
@catch (NSException *ex) {
ASLogDebug(@"Exception: pid=%d id=%lu reason=%@", pid, identifier, ex);
}
+ _isHandlingInputQueue = NO;
}
- (NSToolbarItem *)toolbar:(NSToolbar *)theToolbar
diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h
index 4b8a0a2278..4f9d324c8a 100644
--- a/src/MacVim/MMWindowController.h
+++ b/src/MacVim/MMWindowController.h
@@ -62,6 +62,7 @@
- (id)initWithVimController:(MMVimController *)controller;
- (MMVimController *)vimController;
- (MMVimView *)vimView;
+- (MMFullScreenWindow*)fullScreenWindow;
- (NSString *)windowAutosaveKey;
- (void)setWindowAutosaveKey:(NSString *)key;
- (void)cleanup;
diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m
index 05890bcedf..a3f8354e60 100644
--- a/src/MacVim/MMWindowController.m
+++ b/src/MacVim/MMWindowController.m
@@ -290,6 +290,11 @@ - (MMVimView *)vimView
return vimView;
}
+- (MMFullScreenWindow *)fullScreenWindow
+{
+ return fullScreenWindow;
+}
+
- (NSString *)windowAutosaveKey
{
return windowAutosaveKey;
@@ -468,6 +473,8 @@ - (void)resizeVimViewAndWindow
if (setupDone)
{
shouldResizeVimView = YES;
+ if (!vimController.isHandlingInputQueue)
+ [self processInputQueueDidFinish];
}
}
@@ -480,6 +487,8 @@ - (void)resizeVimView
{
shouldResizeVimView = YES;
shouldKeepGUISize = YES;
+ if (!vimController.isHandlingInputQueue)
+ [self processInputQueueDidFinish];
}
}
@@ -492,9 +501,13 @@ - (void)resizeVimView
/// or shows the tab bar.
- (void)resizeVimViewBlockRender
{
- [self resizeVimView];
- if (shouldResizeVimView) {
+ if (setupDone)
+ {
+ shouldResizeVimView = YES;
+ shouldKeepGUISize = YES;
blockRenderUntilResize = YES;
+ if (!vimController.isHandlingInputQueue)
+ [self processInputQueueDidFinish];
}
}