Skip to content

Fix non-native full screen menu sizing / make resize option updates immediate #1548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/MacVim/Base.lproj/Preferences.xib
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@
</connections>
</buttonCell>
<connections>
<action selector="nonNativeFullScreenShowMenuChanged:" target="-1" id="7gA-SN-OaM"/>
<binding destination="58" name="value" keyPath="values.MMNonNativeFullScreenShowMenu" id="5wX-jg-QPo"/>
</connections>
</button>
Expand Down
2 changes: 2 additions & 0 deletions src/MacVim/MMAppController.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions src/MacVim/MMAppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
*/

#import "MMAppController.h"
#import "MMFullScreenWindow.h"
#import "MMPreferenceController.h"
#import "MMVimController.h"
#import "MMVimView.h"
Expand Down Expand Up @@ -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:)) {
Expand Down
1 change: 1 addition & 0 deletions src/MacVim/MMFullScreenWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
83 changes: 44 additions & 39 deletions src/MacVim/MMFullScreenWindow.m
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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;
Expand Down Expand Up @@ -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];

Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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];
}


Expand All @@ -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
Expand All @@ -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)
1 change: 1 addition & 0 deletions src/MacVim/MMPreferenceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
// Appearance pane
- (IBAction)fontPropertiesChanged:(id)sender;
- (IBAction)tabsPropertiesChanged:(id)sender;
- (IBAction)nonNativeFullScreenShowMenuChanged:(id)sender;

@end
5 changes: 5 additions & 0 deletions src/MacVim/MMPreferenceController.m
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,9 @@ - (IBAction)cmdlineAlignBottomChanged:(id)sender
[[MMAppController sharedInstance] refreshAllTextViews];
}

- (IBAction)nonNativeFullScreenShowMenuChanged:(id)sender
{
[[MMAppController sharedInstance] refreshAllFullScreenPresentationOptions];
}

@end
2 changes: 2 additions & 0 deletions src/MacVim/MMVimController.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
/// E.g. ".AppleSystemUIFontMonospaced-Medium" -> "-monospace-Medium"
@property (nonatomic, readonly) NSMutableDictionary<NSString*, NSString*>* systemFontNamesToAlias;

@property (nonatomic, readonly) BOOL isHandlingInputQueue;

- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
- (void)uninitialize;
- (unsigned long)vimControllerId;
Expand Down
3 changes: 3 additions & 0 deletions src/MacVim/MMVimController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/MacVim/MMWindowController.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
- (id)initWithVimController:(MMVimController *)controller;
- (MMVimController *)vimController;
- (MMVimView *)vimView;
- (MMFullScreenWindow*)fullScreenWindow;
- (NSString *)windowAutosaveKey;
- (void)setWindowAutosaveKey:(NSString *)key;
- (void)cleanup;
Expand Down
17 changes: 15 additions & 2 deletions src/MacVim/MMWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ - (MMVimView *)vimView
return vimView;
}

- (MMFullScreenWindow *)fullScreenWindow
{
return fullScreenWindow;
}

- (NSString *)windowAutosaveKey
{
return windowAutosaveKey;
Expand Down Expand Up @@ -468,6 +473,8 @@ - (void)resizeVimViewAndWindow
if (setupDone)
{
shouldResizeVimView = YES;
if (!vimController.isHandlingInputQueue)
[self processInputQueueDidFinish];
}
}

Expand All @@ -480,6 +487,8 @@ - (void)resizeVimView
{
shouldResizeVimView = YES;
shouldKeepGUISize = YES;
if (!vimController.isHandlingInputQueue)
[self processInputQueueDidFinish];
}
}

Expand All @@ -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];
}
}

Expand Down