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
This commit is contained in:
Yee Cheng Chin
2018-07-08 02:49:37 -07:00
parent 351faf929e
commit 1333bc6c20
12 changed files with 95 additions and 22 deletions
+1
View File
@@ -105,6 +105,7 @@ extern NSTimeInterval MMBalloonEvalInternalDelay;
- (BOOL)tabBarVisible; - (BOOL)tabBarVisible;
- (void)showTabBar:(BOOL)enable; - (void)showTabBar:(BOOL)enable;
- (void)setRows:(int)rows columns:(int)cols; - (void)setRows:(int)rows columns:(int)cols;
- (void)resizeView;
- (void)setWindowTitle:(char *)title; - (void)setWindowTitle:(char *)title;
- (void)setDocumentFilename:(char *)filename; - (void)setDocumentFilename:(char *)filename;
- (char *)browseForFileWithAttributes:(NSDictionary *)attr; - (char *)browseForFileWithAttributes:(NSDictionary *)attr;
+8
View File
@@ -836,6 +836,11 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[self queueMessage:SetTextDimensionsMsgID data:data]; [self queueMessage:SetTextDimensionsMsgID data:data];
} }
- (void)resizeView
{
[self queueMessage:ResizeViewMsgID data:nil];
}
- (void)setWindowTitle:(char *)title - (void)setWindowTitle:(char *)title
{ {
NSMutableData *data = [NSMutableData data]; NSMutableData *data = [NSMutableData data];
@@ -1997,6 +2002,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
tabpage_move(idx); tabpage_move(idx);
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid } else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid
|| SetTextDimensionsNoResizeWindowMsgID == msgid
|| SetTextRowsMsgID == msgid || SetTextColumnsMsgID == msgid) { || SetTextRowsMsgID == msgid || SetTextColumnsMsgID == msgid) {
if (!data) return; if (!data) return;
const void *bytes = [data bytes]; const void *bytes = [data bytes];
@@ -2028,6 +2034,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[self queueMessage:msgid data:d]; [self queueMessage:msgid data:d];
gui_resize_shell(cols, rows); gui_resize_shell(cols, rows);
} else if (ResizeViewMsgID == msgid) {
[self queueMessage:msgid data:data];
} else if (ExecuteMenuMsgID == msgid) { } else if (ExecuteMenuMsgID == msgid) {
NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
if (attrs) { if (attrs) {
+6
View File
@@ -574,6 +574,7 @@ static BOOL isUnsafeMessage(int msgid);
[windowController showTabBar:NO]; [windowController showTabBar:NO];
[self sendMessage:BackingPropertiesChangedMsgID data:nil]; [self sendMessage:BackingPropertiesChangedMsgID data:nil];
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid || } else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid ||
SetTextDimensionsNoResizeWindowMsgID == msgid ||
SetTextDimensionsReplyMsgID == msgid) { SetTextDimensionsReplyMsgID == msgid) {
const void *bytes = [data bytes]; const void *bytes = [data bytes];
int rows = *((int*)bytes); bytes += sizeof(int); int rows = *((int*)bytes); bytes += sizeof(int);
@@ -583,11 +584,16 @@ static BOOL isUnsafeMessage(int msgid);
// acknowledges it with a reply message. When this happens the window // acknowledges it with a reply message. When this happens the window
// should not move (the frontend would already have moved the window). // should not move (the frontend would already have moved the window).
BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid; BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid;
BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid;
[windowController setTextDimensionsWithRows:rows [windowController setTextDimensionsWithRows:rows
columns:cols columns:cols
isLive:(LiveResizeMsgID==msgid) isLive:(LiveResizeMsgID==msgid)
keepGUISize:keepGUISize
keepOnScreen:onScreen]; keepOnScreen:onScreen];
} else if (ResizeViewMsgID == msgid) {
[windowController resizeView];
} else if (SetWindowTitleMsgID == msgid) { } else if (SetWindowTitleMsgID == msgid) {
const void *bytes = [data bytes]; const void *bytes = [data bytes];
int len = *((int*)bytes); bytes += sizeof(int); int len = *((int*)bytes); bytes += sizeof(int);
+1
View File
@@ -55,6 +55,7 @@
- (void)viewWillStartLiveResize; - (void)viewWillStartLiveResize;
- (void)viewDidEndLiveResize; - (void)viewDidEndLiveResize;
- (void)setFrameSize:(NSSize)size; - (void)setFrameSize:(NSSize)size;
- (void)setFrameSizeKeepGUISize:(NSSize)size;
- (void)setFrame:(NSRect)frame; - (void)setFrame:(NSRect)frame;
@end @end
+16 -5
View File
@@ -60,7 +60,7 @@ enum {
- (NSSize)vimViewSizeForTextViewSize:(NSSize)textViewSize; - (NSSize)vimViewSizeForTextViewSize:(NSSize)textViewSize;
- (NSRect)textViewRectForVimViewSize:(NSSize)contentSize; - (NSRect)textViewRectForVimViewSize:(NSSize)contentSize;
- (NSTabView *)tabView; - (NSTabView *)tabView;
- (void)frameSizeMayHaveChanged; - (void)frameSizeMayHaveChanged:(BOOL)keepGUISize;
@end @end
@@ -610,14 +610,25 @@ enum {
// row will result in the vim view holding more rows than the can fit // row will result in the vim view holding more rows than the can fit
// inside the window.) // inside the window.)
[super setFrameSize:size]; [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 - (void)setFrame:(NSRect)frame
{ {
// See comment in setFrameSize: above. // See comment in setFrameSize: above.
[super setFrame:frame]; [super setFrame:frame];
[self frameSizeMayHaveChanged]; [self frameSizeMayHaveChanged:NO];
} }
@end // MMVimView @end // MMVimView
@@ -867,7 +878,7 @@ enum {
return tabView; return tabView;
} }
- (void)frameSizeMayHaveChanged - (void)frameSizeMayHaveChanged:(BOOL)keepGUISize
{ {
// NOTE: Whenever a call is made that may have changed the frame size we // 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 // take the opportunity to make sure all subviews are in place and that the
@@ -903,7 +914,7 @@ enum {
if (constrained[0] != rows || constrained[1] != cols) { if (constrained[0] != rows || constrained[1] != cols) {
NSData *data = [NSData dataWithBytes:constrained length:2*sizeof(int)]; NSData *data = [NSData dataWithBytes:constrained length:2*sizeof(int)];
int msgid = [self inLiveResize] ? LiveResizeMsgID int msgid = [self inLiveResize] ? LiveResizeMsgID
: SetTextDimensionsMsgID; : (keepGUISize ? SetTextDimensionsNoResizeWindowMsgID : SetTextDimensionsMsgID);
ASLogDebug(@"Notify Vim that text dimensions changed from %dx%d to " ASLogDebug(@"Notify Vim that text dimensions changed from %dx%d to "
"%dx%d (%s)", cols, rows, constrained[1], constrained[0], "%dx%d (%s)", cols, rows, constrained[1], constrained[0],
+3
View File
@@ -24,6 +24,7 @@
BOOL setupDone; BOOL setupDone;
BOOL windowPresented; BOOL windowPresented;
BOOL shouldResizeVimView; BOOL shouldResizeVimView;
BOOL shouldKeepGUISize;
BOOL shouldRestoreUserTopLeft; BOOL shouldRestoreUserTopLeft;
BOOL shouldMaximizeWindow; BOOL shouldMaximizeWindow;
int updateToolbarFlag; int updateToolbarFlag;
@@ -59,7 +60,9 @@
- (void)updateTabsWithData:(NSData *)data; - (void)updateTabsWithData:(NSData *)data;
- (void)selectTabWithIndex:(int)idx; - (void)selectTabWithIndex:(int)idx;
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
keepGUISize:(BOOL)keepGUISize
keepOnScreen:(BOOL)onScreen; keepOnScreen:(BOOL)onScreen;
- (void)resizeView;
- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state; - (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state;
- (void)setTitle:(NSString *)title; - (void)setTitle:(NSString *)title;
- (void)setDocumentFilename:(NSString *)filename; - (void)setDocumentFilename:(NSString *)filename;
+32 -17
View File
@@ -174,7 +174,7 @@
[win setDelegate:self]; [win setDelegate:self];
[win setInitialFirstResponder:[vimView textView]]; [win setInitialFirstResponder:[vimView textView]];
if ([win styleMask] & NSWindowStyleMaskTexturedBackground) { if ([win styleMask] & NSWindowStyleMaskTexturedBackground) {
// On Leopard, we want to have a textured window to have nice // On Leopard, we want to have a textured window to have nice
// looking tabs. But the textured window look implies rounded // looking tabs. But the textured window look implies rounded
@@ -381,6 +381,7 @@
} }
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
keepGUISize:(BOOL)keepGUISize
keepOnScreen:(BOOL)onScreen keepOnScreen:(BOOL)onScreen
{ {
ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d " ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d "
@@ -399,7 +400,7 @@
[vimView setDesiredRows:rows columns:cols]; [vimView setDesiredRows:rows columns:cols];
if (setupDone && !live) { if (setupDone && !live && !keepGUISize) {
shouldResizeVimView = YES; shouldResizeVimView = YES;
keepOnScreen = onScreen; keepOnScreen = onScreen;
} }
@@ -428,6 +429,15 @@
} }
} }
- (void)resizeView
{
if (setupDone)
{
shouldResizeVimView = YES;
shouldKeepGUISize = YES;
}
}
- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state - (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state
{ {
[self setTextDimensionsWithRows:rows [self setTextDimensionsWithRows:rows
@@ -503,9 +513,6 @@
- (BOOL)destroyScrollbarWithIdentifier:(int32_t)ident - (BOOL)destroyScrollbarWithIdentifier:(int32_t)ident
{ {
BOOL scrollbarHidden = [vimView destroyScrollbarWithIdentifier:ident]; BOOL scrollbarHidden = [vimView destroyScrollbarWithIdentifier:ident];
shouldResizeVimView = shouldResizeVimView || scrollbarHidden;
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarHidden;
return scrollbarHidden; return scrollbarHidden;
} }
@@ -513,9 +520,6 @@
{ {
BOOL scrollbarToggled = [vimView showScrollbarWithIdentifier:ident BOOL scrollbarToggled = [vimView showScrollbarWithIdentifier:ident
state:visible]; state:visible];
shouldResizeVimView = shouldResizeVimView || scrollbarToggled;
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarToggled;
return scrollbarToggled; return scrollbarToggled;
} }
@@ -600,7 +604,18 @@
fullScreenWindow ? [fullScreenWindow frame].size : fullScreenWindow ? [fullScreenWindow frame].size :
fullScreenEnabled ? desiredWindowSize : fullScreenEnabled ? desiredWindowSize :
[self constrainContentSizeToScreenSize:[vimView desiredSize]]]; [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) { if (fullScreenWindow) {
// NOTE! Don't mark the full-screen content view as needing an // NOTE! Don't mark the full-screen content view as needing an
@@ -613,12 +628,15 @@
[fullScreenWindow centerView]; [fullScreenWindow centerView];
} }
} else { } else {
[self resizeWindowToFitContentSize:contentSize if (!avoidWindowResize) {
keepOnScreen:keepOnScreen]; [self resizeWindowToFitContentSize:contentSize
keepOnScreen:keepOnScreen];
}
} }
} }
keepOnScreen = NO; keepOnScreen = NO;
shouldKeepGUISize = NO;
} }
} }
@@ -657,7 +675,6 @@
{ {
if (vimView && [vimView textView]) { if (vimView && [vimView textView]) {
[[vimView textView] setLinespace:(float)linespace]; [[vimView textView] setLinespace:(float)linespace];
shouldMaximizeWindow = shouldResizeVimView = YES;
} }
} }
@@ -665,7 +682,6 @@
{ {
if (vimView && [vimView textView]) { if (vimView && [vimView textView]) {
[[vimView textView] setColumnspace:(float)columnspace]; [[vimView textView] setColumnspace:(float)columnspace];
shouldMaximizeWindow = shouldResizeVimView = YES;
} }
} }
@@ -1177,7 +1193,7 @@
[[window animator] setAlphaValue:0]; [[window animator] setAlphaValue:0];
} completionHandler:^{ } completionHandler:^{
[self maximizeWindow:fullScreenOptions]; [self maximizeWindow:fullScreenOptions];
// Fade in // Fade in
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:0.5*duration]; [context setDuration:0.5*duration];
@@ -1196,7 +1212,7 @@
// The separator should never be visible in fullscreen or split-screen. // The separator should never be visible in fullscreen or split-screen.
[decoratedWindow hideTablineSeparator:YES]; [decoratedWindow hideTablineSeparator:YES];
// ASSUMPTION: fullScreenEnabled always reflects the state of Vim's 'fu'. // ASSUMPTION: fullScreenEnabled always reflects the state of Vim's 'fu'.
if (!fullScreenEnabled) { if (!fullScreenEnabled) {
ASLogDebug(@"Full-screen out of sync, tell Vim to set 'fu'"); ASLogDebug(@"Full-screen out of sync, tell Vim to set 'fu'");
@@ -1298,7 +1314,7 @@
// full-screen by moving the window out from Split View. // full-screen by moving the window out from Split View.
[vimController sendMessage:BackingPropertiesChangedMsgID data:nil]; [vimController sendMessage:BackingPropertiesChangedMsgID data:nil];
} }
[self updateTablineSeparator]; [self updateTablineSeparator];
} }
@@ -1519,7 +1535,6 @@
// The tabline separator was toggled so the content view must change // The tabline separator was toggled so the content view must change
// size. // size.
[self updateResizeConstraints]; [self updateResizeConstraints];
shouldResizeVimView = YES;
} }
} }
+2
View File
@@ -176,8 +176,10 @@ enum {
SetTextRowsMsgID, SetTextRowsMsgID,
SetTextColumnsMsgID, SetTextColumnsMsgID,
SetTextDimensionsMsgID, SetTextDimensionsMsgID,
SetTextDimensionsNoResizeWindowMsgID,
LiveResizeMsgID, LiveResizeMsgID,
SetTextDimensionsReplyMsgID, SetTextDimensionsReplyMsgID,
ResizeViewMsgID,
SetWindowTitleMsgID, SetWindowTitleMsgID,
ScrollWheelMsgID, ScrollWheelMsgID,
MouseDownMsgID, MouseDownMsgID,
+2
View File
@@ -30,8 +30,10 @@ char *MessageStrings[] =
"SetTextRowsMsgID", "SetTextRowsMsgID",
"SetTextColumnsMsgID", "SetTextColumnsMsgID",
"SetTextDimensionsMsgID", "SetTextDimensionsMsgID",
"SetTextDimensionsNoResizeWindowMsgID",
"LiveResizeMsgID", "LiveResizeMsgID",
"SetTextDimensionsReplyMsgID", "SetTextDimensionsReplyMsgID",
"ResizeViewMsgID",
"SetWindowTitleMsgID", "SetWindowTitleMsgID",
"ScrollWheelMsgID", "ScrollWheelMsgID",
"MouseDownMsgID", "MouseDownMsgID",
+12
View File
@@ -1732,6 +1732,18 @@ gui_mch_set_shellsize(
} }
/*
* 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 * Set the position of the top left corner of the window to the given
* coordinates. * coordinates.
+10
View File
@@ -1621,6 +1621,16 @@ gui_set_shellsize(
} }
#endif #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_width = gui_get_base_width();
base_height = gui_get_base_height(); base_height = gui_get_base_height();
if (fit_to_display) if (fit_to_display)
+2
View File
@@ -174,6 +174,8 @@ gui_mch_set_shellsize(
int base_height, int base_height,
int direction); int direction);
void void
gui_mch_resize_view();
void
gui_mch_set_sp_color(guicolor_T color); gui_mch_set_sp_color(guicolor_T color);
void void
gui_mch_set_text_area_pos(int x, int y, int w, int h); gui_mch_set_text_area_pos(int x, int y, int w, int h);