From 1333bc6c204d59ba6daf3c4cb94cd9f4f2dda3e3 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Sun, 8 Jul 2018 02:49:37 -0700 Subject: [PATCH] Support guioptions 'k' flag in MacVim, prevents unnecessary window resize Adds support for native GVim's 'k' flag. Adding/removing tabs/scrollbars and setting 'linespace'/'columnspace' would now cause the number of lines and columns in the buffer change to keep the window size constant, instead of the other way round of resizing the window to keep the view size constant. This helps prevent the window from resizing itself unncessarily, which could be especially annoying when the window is pinned/maximized. Manually setting 'lines'/'columns', going to full screen, dragging the window corner to resize would still resize the window. Also removed misc calls within MMWindowController.m that were setting shouldResizeVimView. Those calls were already handled by native Vim's gui.c's gui_set_shellsize so it's redundant. Close #617 --- src/MacVim/MMBackend.h | 1 + src/MacVim/MMBackend.m | 8 ++++++ src/MacVim/MMVimController.m | 6 ++++ src/MacVim/MMVimView.h | 1 + src/MacVim/MMVimView.m | 21 ++++++++++---- src/MacVim/MMWindowController.h | 3 ++ src/MacVim/MMWindowController.m | 49 +++++++++++++++++++++------------ src/MacVim/MacVim.h | 2 ++ src/MacVim/MacVim.m | 2 ++ src/MacVim/gui_macvim.m | 12 ++++++++ src/gui.c | 10 +++++++ src/proto/gui_macvim.pro | 2 ++ 12 files changed, 95 insertions(+), 22 deletions(-) diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index 733578af76..bbebc7e24e 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -105,6 +105,7 @@ extern NSTimeInterval MMBalloonEvalInternalDelay; - (BOOL)tabBarVisible; - (void)showTabBar:(BOOL)enable; - (void)setRows:(int)rows columns:(int)cols; +- (void)resizeView; - (void)setWindowTitle:(char *)title; - (void)setDocumentFilename:(char *)filename; - (char *)browseForFileWithAttributes:(NSDictionary *)attr; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index c56225a5f0..ce0d62f70b 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -836,6 +836,11 @@ - (void)setRows:(int)rows columns:(int)cols [self queueMessage:SetTextDimensionsMsgID data:data]; } +- (void)resizeView +{ + [self queueMessage:ResizeViewMsgID data:nil]; +} + - (void)setWindowTitle:(char *)title { NSMutableData *data = [NSMutableData data]; @@ -1997,6 +2002,7 @@ - (void)handleInputEvent:(int)msgid data:(NSData *)data tabpage_move(idx); } else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid + || SetTextDimensionsNoResizeWindowMsgID == msgid || SetTextRowsMsgID == msgid || SetTextColumnsMsgID == msgid) { if (!data) return; const void *bytes = [data bytes]; @@ -2028,6 +2034,8 @@ - (void)handleInputEvent:(int)msgid data:(NSData *)data [self queueMessage:msgid data:d]; gui_resize_shell(cols, rows); + } else if (ResizeViewMsgID == msgid) { + [self queueMessage:msgid data:data]; } else if (ExecuteMenuMsgID == msgid) { NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; if (attrs) { diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 66d4b4b556..600b55ca29 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -574,6 +574,7 @@ - (void)handleMessage:(int)msgid data:(NSData *)data [windowController showTabBar:NO]; [self sendMessage:BackingPropertiesChangedMsgID data:nil]; } else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid || + SetTextDimensionsNoResizeWindowMsgID == msgid || SetTextDimensionsReplyMsgID == msgid) { const void *bytes = [data bytes]; int rows = *((int*)bytes); bytes += sizeof(int); @@ -583,11 +584,16 @@ - (void)handleMessage:(int)msgid data:(NSData *)data // acknowledges it with a reply message. When this happens the window // should not move (the frontend would already have moved the window). BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid; + + BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid; [windowController setTextDimensionsWithRows:rows columns:cols isLive:(LiveResizeMsgID==msgid) + keepGUISize:keepGUISize keepOnScreen:onScreen]; + } else if (ResizeViewMsgID == msgid) { + [windowController resizeView]; } else if (SetWindowTitleMsgID == msgid) { const void *bytes = [data bytes]; int len = *((int*)bytes); bytes += sizeof(int); diff --git a/src/MacVim/MMVimView.h b/src/MacVim/MMVimView.h index 5a8335ed1e..8ecaa24b2c 100644 --- a/src/MacVim/MMVimView.h +++ b/src/MacVim/MMVimView.h @@ -55,6 +55,7 @@ - (void)viewWillStartLiveResize; - (void)viewDidEndLiveResize; - (void)setFrameSize:(NSSize)size; +- (void)setFrameSizeKeepGUISize:(NSSize)size; - (void)setFrame:(NSRect)frame; @end diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index fd04c47e5b..6202a186f3 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -60,7 +60,7 @@ - (MMScroller *)scrollbarForIdentifier:(int32_t)ident index:(unsigned *)idx; - (NSSize)vimViewSizeForTextViewSize:(NSSize)textViewSize; - (NSRect)textViewRectForVimViewSize:(NSSize)contentSize; - (NSTabView *)tabView; -- (void)frameSizeMayHaveChanged; +- (void)frameSizeMayHaveChanged:(BOOL)keepGUISize; @end @@ -610,14 +610,25 @@ - (void)setFrameSize:(NSSize)size // row will result in the vim view holding more rows than the can fit // inside the window.) [super setFrameSize:size]; - [self frameSizeMayHaveChanged]; + [self frameSizeMayHaveChanged:NO]; +} + +- (void)setFrameSizeKeepGUISize:(NSSize)size +{ + // NOTE: Instead of only acting when a frame was resized, we do some + // updating each time a frame may be resized. (At the moment, if we only + // respond to actual frame changes then typing ":set lines=1000" twice in a + // row will result in the vim view holding more rows than the can fit + // inside the window.) + [super setFrameSize:size]; + [self frameSizeMayHaveChanged:YES]; } - (void)setFrame:(NSRect)frame { // See comment in setFrameSize: above. [super setFrame:frame]; - [self frameSizeMayHaveChanged]; + [self frameSizeMayHaveChanged:NO]; } @end // MMVimView @@ -867,7 +878,7 @@ - (NSTabView *)tabView return tabView; } -- (void)frameSizeMayHaveChanged +- (void)frameSizeMayHaveChanged:(BOOL)keepGUISize { // NOTE: Whenever a call is made that may have changed the frame size we // take the opportunity to make sure all subviews are in place and that the @@ -903,7 +914,7 @@ - (void)frameSizeMayHaveChanged if (constrained[0] != rows || constrained[1] != cols) { NSData *data = [NSData dataWithBytes:constrained length:2*sizeof(int)]; int msgid = [self inLiveResize] ? LiveResizeMsgID - : SetTextDimensionsMsgID; + : (keepGUISize ? SetTextDimensionsNoResizeWindowMsgID : SetTextDimensionsMsgID); ASLogDebug(@"Notify Vim that text dimensions changed from %dx%d to " "%dx%d (%s)", cols, rows, constrained[1], constrained[0], diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h index 8c92ed537d..5e97478f9a 100644 --- a/src/MacVim/MMWindowController.h +++ b/src/MacVim/MMWindowController.h @@ -24,6 +24,7 @@ BOOL setupDone; BOOL windowPresented; BOOL shouldResizeVimView; + BOOL shouldKeepGUISize; BOOL shouldRestoreUserTopLeft; BOOL shouldMaximizeWindow; int updateToolbarFlag; @@ -59,7 +60,9 @@ - (void)updateTabsWithData:(NSData *)data; - (void)selectTabWithIndex:(int)idx; - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live + keepGUISize:(BOOL)keepGUISize keepOnScreen:(BOOL)onScreen; +- (void)resizeView; - (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state; - (void)setTitle:(NSString *)title; - (void)setDocumentFilename:(NSString *)filename; diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 5f7ddbf30a..c6fa99d795 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -174,7 +174,7 @@ - (id)initWithVimController:(MMVimController *)controller [win setDelegate:self]; [win setInitialFirstResponder:[vimView textView]]; - + if ([win styleMask] & NSWindowStyleMaskTexturedBackground) { // On Leopard, we want to have a textured window to have nice // looking tabs. But the textured window look implies rounded @@ -381,6 +381,7 @@ - (void)selectTabWithIndex:(int)idx } - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live + keepGUISize:(BOOL)keepGUISize keepOnScreen:(BOOL)onScreen { ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d " @@ -399,7 +400,7 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live [vimView setDesiredRows:rows columns:cols]; - if (setupDone && !live) { + if (setupDone && !live && !keepGUISize) { shouldResizeVimView = YES; keepOnScreen = onScreen; } @@ -428,6 +429,15 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live } } +- (void)resizeView +{ + if (setupDone) + { + shouldResizeVimView = YES; + shouldKeepGUISize = YES; + } +} + - (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state { [self setTextDimensionsWithRows:rows @@ -503,9 +513,6 @@ - (void)createScrollbarWithIdentifier:(int32_t)ident type:(int)type - (BOOL)destroyScrollbarWithIdentifier:(int32_t)ident { BOOL scrollbarHidden = [vimView destroyScrollbarWithIdentifier:ident]; - shouldResizeVimView = shouldResizeVimView || scrollbarHidden; - shouldMaximizeWindow = shouldMaximizeWindow || scrollbarHidden; - return scrollbarHidden; } @@ -513,9 +520,6 @@ - (BOOL)showScrollbarWithIdentifier:(int32_t)ident state:(BOOL)visible { BOOL scrollbarToggled = [vimView showScrollbarWithIdentifier:ident state:visible]; - shouldResizeVimView = shouldResizeVimView || scrollbarToggled; - shouldMaximizeWindow = shouldMaximizeWindow || scrollbarToggled; - return scrollbarToggled; } @@ -600,7 +604,18 @@ - (void)processInputQueueDidFinish fullScreenWindow ? [fullScreenWindow frame].size : fullScreenEnabled ? desiredWindowSize : [self constrainContentSizeToScreenSize:[vimView desiredSize]]]; - [vimView setFrameSize:contentSize]; + + // Setting 'guioptions+=k' will make shouldKeepGUISize true, which + // means avoid resizing the window. Instead, resize the view instead + // to keep the GUI window's size consistent. + bool avoidWindowResize = shouldKeepGUISize && !fullScreenEnabled; + + if (!avoidWindowResize) { + [vimView setFrameSize:contentSize]; + } + else { + [vimView setFrameSizeKeepGUISize:originalSize]; + } if (fullScreenWindow) { // NOTE! Don't mark the full-screen content view as needing an @@ -613,12 +628,15 @@ - (void)processInputQueueDidFinish [fullScreenWindow centerView]; } } else { - [self resizeWindowToFitContentSize:contentSize - keepOnScreen:keepOnScreen]; + if (!avoidWindowResize) { + [self resizeWindowToFitContentSize:contentSize + keepOnScreen:keepOnScreen]; + } } } keepOnScreen = NO; + shouldKeepGUISize = NO; } } @@ -657,7 +675,6 @@ - (void)adjustLinespace:(int)linespace { if (vimView && [vimView textView]) { [[vimView textView] setLinespace:(float)linespace]; - shouldMaximizeWindow = shouldResizeVimView = YES; } } @@ -665,7 +682,6 @@ - (void)adjustColumnspace:(int)columnspace { if (vimView && [vimView textView]) { [[vimView textView] setColumnspace:(float)columnspace]; - shouldMaximizeWindow = shouldResizeVimView = YES; } } @@ -1177,7 +1193,7 @@ - (void)window:(NSWindow *)window [[window animator] setAlphaValue:0]; } completionHandler:^{ [self maximizeWindow:fullScreenOptions]; - + // Fade in [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { [context setDuration:0.5*duration]; @@ -1196,7 +1212,7 @@ - (void)windowWillEnterFullScreen:(NSNotification *)notification // The separator should never be visible in fullscreen or split-screen. [decoratedWindow hideTablineSeparator:YES]; - + // ASSUMPTION: fullScreenEnabled always reflects the state of Vim's 'fu'. if (!fullScreenEnabled) { ASLogDebug(@"Full-screen out of sync, tell Vim to set 'fu'"); @@ -1298,7 +1314,7 @@ - (void)windowDidExitFullScreen:(NSNotification *)notification // full-screen by moving the window out from Split View. [vimController sendMessage:BackingPropertiesChangedMsgID data:nil]; } - + [self updateTablineSeparator]; } @@ -1519,7 +1535,6 @@ - (void)hideTablineSeparator:(BOOL)hide // The tabline separator was toggled so the content view must change // size. [self updateResizeConstraints]; - shouldResizeVimView = YES; } } diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index 2a8a53f588..ad09586ed1 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -176,8 +176,10 @@ enum { SetTextRowsMsgID, SetTextColumnsMsgID, SetTextDimensionsMsgID, + SetTextDimensionsNoResizeWindowMsgID, LiveResizeMsgID, SetTextDimensionsReplyMsgID, + ResizeViewMsgID, SetWindowTitleMsgID, ScrollWheelMsgID, MouseDownMsgID, diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index b9fdeb43c9..6390a29139 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -30,8 +30,10 @@ "SetTextRowsMsgID", "SetTextColumnsMsgID", "SetTextDimensionsMsgID", + "SetTextDimensionsNoResizeWindowMsgID", "LiveResizeMsgID", "SetTextDimensionsReplyMsgID", + "ResizeViewMsgID", "SetWindowTitleMsgID", "ScrollWheelMsgID", "MouseDownMsgID", diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index d6fa0a0929..ed1e9c4168 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -1732,6 +1732,18 @@ } +/* + * Re-calculates size of the Vim view to fit within the window without having + * to resize the window. Usually happens after UI elements have changed (e.g. + * adding / removing a toolbar) when guioptions 'k' is set. + */ + void +gui_mch_resize_view() +{ + [[MMBackend sharedInstance] resizeView]; +} + + /* * Set the position of the top left corner of the window to the given * coordinates. diff --git a/src/gui.c b/src/gui.c index 6b1ce1c968..14262ab7ee 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1621,6 +1621,16 @@ gui_set_shellsize( } #endif +#ifdef FEAT_GUI_MACVIM + if (!mustset && (vim_strchr(p_go, GO_KEEPWINSIZE) != NULL)) + { + /* We don't want to resize the window, so instruct the GUI to resize + * the view to be within the constraints of the current window's size */ + gui_mch_resize_view(); + return; + } +#endif + base_width = gui_get_base_width(); base_height = gui_get_base_height(); if (fit_to_display) diff --git a/src/proto/gui_macvim.pro b/src/proto/gui_macvim.pro index dd75a6f2b3..8fdab4ef70 100644 --- a/src/proto/gui_macvim.pro +++ b/src/proto/gui_macvim.pro @@ -174,6 +174,8 @@ gui_mch_set_shellsize( int base_height, int direction); void +gui_mch_resize_view(); + void gui_mch_set_sp_color(guicolor_T color); void gui_mch_set_text_area_pos(int x, int y, int w, int h);