Skip to content

Commit a3a185c

Browse files
authored
Merge pull request macvim-dev#1548 from ychin/non-native-fullscreen-menubar-height-calc
Fix non-native full screen menu sizing / make resize option updates immediate
2 parents dc49d72 + 0247066 commit a3a185c

11 files changed

+89
-41
lines changed

src/MacVim/Base.lproj/Preferences.xib

+1
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@
507507
</connections>
508508
</buttonCell>
509509
<connections>
510+
<action selector="nonNativeFullScreenShowMenuChanged:" target="-1" id="7gA-SN-OaM"/>
510511
<binding destination="58" name="value" keyPath="values.MMNonNativeFullScreenShowMenu" id="5wX-jg-QPo"/>
511512
</connections>
512513
</button>

src/MacVim/MMAppController.h

+2
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@
8383
- (NSArray *)filterOpenFiles:(NSArray *)filenames;
8484
- (BOOL)openFiles:(NSArray *)filenames withArguments:(NSDictionary *)args;
8585

86+
// Refresh functions are used by preference pane to push through settings changes
8687
- (void)refreshAllAppearances;
8788
- (void)refreshAllTabProperties;
8889
- (void)refreshAllFonts;
8990
- (void)refreshAllResizeConstraints;
9091
- (void)refreshAllTextViews;
92+
- (void)refreshAllFullScreenPresentationOptions;
9193

9294
- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate extraArgs:(NSArray *)args;
9395
- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate;

src/MacVim/MMAppController.m

+14
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
*/
3939

4040
#import "MMAppController.h"
41+
#import "MMFullScreenWindow.h"
4142
#import "MMPreferenceController.h"
4243
#import "MMVimController.h"
4344
#import "MMVimView.h"
@@ -1272,6 +1273,19 @@ - (void)refreshAllTextViews
12721273
}
12731274
}
12741275

1276+
/// Refresh all non-native full screen windows to update their presentation
1277+
/// options (show/hide menu and dock).
1278+
- (void)refreshAllFullScreenPresentationOptions
1279+
{
1280+
for (MMVimController *vc in vimControllers) {
1281+
MMFullScreenWindow *fullScreenWindow = vc.windowController.fullScreenWindow;
1282+
if (fullScreenWindow != nil) {
1283+
[fullScreenWindow updatePresentationOptions];
1284+
[vc.windowController resizeVimView];
1285+
}
1286+
}
1287+
}
1288+
12751289
- (BOOL)validateMenuItem:(NSMenuItem *)item
12761290
{
12771291
if ([item action] == @selector(showWhatsNew:)) {

src/MacVim/MMFullScreenWindow.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- (MMFullScreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
3636
backgroundColor:(NSColor *)back;
3737
- (void)setOptions:(int)opt;
38+
- (void)updatePresentationOptions;
3839
- (void)enterFullScreen;
3940
- (void)leaveFullScreen;
4041
- (NSRect)getDesiredFrame;

src/MacVim/MMFullScreenWindow.m

+44-39
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ - (void)setOptions:(int)opt
134134
options = opt;
135135
}
136136

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+
137153
- (void)enterFullScreen
138154
{
139155
ASLogDebug(@"Enter full-screen now");
@@ -147,16 +163,7 @@ - (void)enterFullScreen
147163
[winController setWindow:nil];
148164
[target setDelegate:nil];
149165

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];
160167

161168
// fade to black
162169
Boolean didBlend = NO;
@@ -376,6 +383,10 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification
376383
- (NSEdgeInsets) viewOffset {
377384
NSEdgeInsets offset = NSEdgeInsetsMake(0, 0, 0, 0);
378385

386+
NSScreen *screen = [self screen];
387+
if (screen == nil)
388+
return offset;
389+
379390
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
380391
const BOOL showMenu = [ud boolForKey:MMNonNativeFullScreenShowMenuKey];
381392

@@ -390,29 +401,28 @@ - (NSEdgeInsets) viewOffset {
390401
// In the future there may be more. E.g. we can draw tabs in the safe area.
391402
// If menu is shown, we ignore this because this doesn't make sense.
392403
if (safeAreaBehavior == 0 || showMenu) {
393-
offset = [self screen].safeAreaInsets;
404+
offset = screen.safeAreaInsets;
394405
}
395406
}
396407
#endif
397408

398409
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;
416426
}
417427
}
418428

@@ -514,14 +524,7 @@ - (BOOL)screenHasDockAndMenu
514524
- (void)windowDidBecomeMain:(NSNotification *)notification
515525
{
516526
// 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];
525528
}
526529

527530

@@ -530,9 +533,7 @@ - (void)windowDidResignMain:(NSNotification *)notification
530533
// Un-hide menu/dock when we lose focus. This makes sure if we have multiple
531534
// windows opened, when the non-fullscreen windows get focus they will have the
532535
// 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;
536537
}
537538

538539
- (void)windowDidMove:(NSNotification *)notification
@@ -558,6 +559,10 @@ - (void)windowDidMove:(NSNotification *)notification
558559
// Ensure the full-screen window is still covering the entire screen and
559560
// then resize view according to 'fuopt'.
560561
[self setFrame:[screen frame] display:NO];
562+
563+
if ([self isMainWindow]) {
564+
[self updatePresentationOptions];
565+
}
561566
}
562567

563568
@end // MMFullScreenWindow (Private)

src/MacVim/MMPreferenceController.h

+1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,6 @@
4040
// Appearance pane
4141
- (IBAction)fontPropertiesChanged:(id)sender;
4242
- (IBAction)tabsPropertiesChanged:(id)sender;
43+
- (IBAction)nonNativeFullScreenShowMenuChanged:(id)sender;
4344

4445
@end

src/MacVim/MMPreferenceController.m

+5
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,9 @@ - (IBAction)cmdlineAlignBottomChanged:(id)sender
182182
[[MMAppController sharedInstance] refreshAllTextViews];
183183
}
184184

185+
- (IBAction)nonNativeFullScreenShowMenuChanged:(id)sender
186+
{
187+
[[MMAppController sharedInstance] refreshAllFullScreenPresentationOptions];
188+
}
189+
185190
@end

src/MacVim/MMVimController.h

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
/// E.g. ".AppleSystemUIFontMonospaced-Medium" -> "-monospace-Medium"
6161
@property (nonatomic, readonly) NSMutableDictionary<NSString*, NSString*>* systemFontNamesToAlias;
6262

63+
@property (nonatomic, readonly) BOOL isHandlingInputQueue;
64+
6365
- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
6466
- (void)uninitialize;
6567
- (unsigned long)vimControllerId;

src/MacVim/MMVimController.m

+3
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,8 @@ - (void)processInputQueue:(NSArray *)queue
557557
{
558558
if (!isInitialized) return;
559559

560+
_isHandlingInputQueue = YES;
561+
560562
// NOTE: This method must not raise any exceptions (see comment in the
561563
// calling method).
562564
@try {
@@ -566,6 +568,7 @@ - (void)processInputQueue:(NSArray *)queue
566568
@catch (NSException *ex) {
567569
ASLogDebug(@"Exception: pid=%d id=%lu reason=%@", pid, identifier, ex);
568570
}
571+
_isHandlingInputQueue = NO;
569572
}
570573

571574
- (NSToolbarItem *)toolbar:(NSToolbar *)theToolbar

src/MacVim/MMWindowController.h

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
- (id)initWithVimController:(MMVimController *)controller;
6363
- (MMVimController *)vimController;
6464
- (MMVimView *)vimView;
65+
- (MMFullScreenWindow*)fullScreenWindow;
6566
- (NSString *)windowAutosaveKey;
6667
- (void)setWindowAutosaveKey:(NSString *)key;
6768
- (void)cleanup;

src/MacVim/MMWindowController.m

+15-2
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ - (MMVimView *)vimView
290290
return vimView;
291291
}
292292

293+
- (MMFullScreenWindow *)fullScreenWindow
294+
{
295+
return fullScreenWindow;
296+
}
297+
293298
- (NSString *)windowAutosaveKey
294299
{
295300
return windowAutosaveKey;
@@ -468,6 +473,8 @@ - (void)resizeVimViewAndWindow
468473
if (setupDone)
469474
{
470475
shouldResizeVimView = YES;
476+
if (!vimController.isHandlingInputQueue)
477+
[self processInputQueueDidFinish];
471478
}
472479
}
473480

@@ -480,6 +487,8 @@ - (void)resizeVimView
480487
{
481488
shouldResizeVimView = YES;
482489
shouldKeepGUISize = YES;
490+
if (!vimController.isHandlingInputQueue)
491+
[self processInputQueueDidFinish];
483492
}
484493
}
485494

@@ -492,9 +501,13 @@ - (void)resizeVimView
492501
/// or shows the tab bar.
493502
- (void)resizeVimViewBlockRender
494503
{
495-
[self resizeVimView];
496-
if (shouldResizeVimView) {
504+
if (setupDone)
505+
{
506+
shouldResizeVimView = YES;
507+
shouldKeepGUISize = YES;
497508
blockRenderUntilResize = YES;
509+
if (!vimController.isHandlingInputQueue)
510+
[self processInputQueueDidFinish];
498511
}
499512
}
500513

0 commit comments

Comments
 (0)