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;
- (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;
+8
View File
@@ -836,6 +836,11 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[self queueMessage:SetTextDimensionsMsgID data:data];
}
- (void)resizeView
{
[self queueMessage:ResizeViewMsgID data:nil];
}
- (void)setWindowTitle:(char *)title
{
NSMutableData *data = [NSMutableData data];
@@ -1997,6 +2002,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
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 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[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) {
+6
View File
@@ -574,6 +574,7 @@ static BOOL isUnsafeMessage(int msgid);
[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 @@ static BOOL isUnsafeMessage(int msgid);
// 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);
+1
View File
@@ -55,6 +55,7 @@
- (void)viewWillStartLiveResize;
- (void)viewDidEndLiveResize;
- (void)setFrameSize:(NSSize)size;
- (void)setFrameSizeKeepGUISize:(NSSize)size;
- (void)setFrame:(NSRect)frame;
@end
+16 -5
View File
@@ -60,7 +60,7 @@ enum {
- (NSSize)vimViewSizeForTextViewSize:(NSSize)textViewSize;
- (NSRect)textViewRectForVimViewSize:(NSSize)contentSize;
- (NSTabView *)tabView;
- (void)frameSizeMayHaveChanged;
- (void)frameSizeMayHaveChanged:(BOOL)keepGUISize;
@end
@@ -610,14 +610,25 @@ enum {
// 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 @@ enum {
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 @@ enum {
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],
+3
View File
@@ -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;
+32 -17
View File
@@ -174,7 +174,7 @@
[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)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 @@
[vimView setDesiredRows:rows columns:cols];
if (setupDone && !live) {
if (setupDone && !live && !keepGUISize) {
shouldResizeVimView = YES;
keepOnScreen = onScreen;
}
@@ -428,6 +429,15 @@
}
}
- (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 @@
- (BOOL)destroyScrollbarWithIdentifier:(int32_t)ident
{
BOOL scrollbarHidden = [vimView destroyScrollbarWithIdentifier:ident];
shouldResizeVimView = shouldResizeVimView || scrollbarHidden;
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarHidden;
return scrollbarHidden;
}
@@ -513,9 +520,6 @@
{
BOOL scrollbarToggled = [vimView showScrollbarWithIdentifier:ident
state:visible];
shouldResizeVimView = shouldResizeVimView || scrollbarToggled;
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarToggled;
return scrollbarToggled;
}
@@ -600,7 +604,18 @@
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 @@
[fullScreenWindow centerView];
}
} else {
[self resizeWindowToFitContentSize:contentSize
keepOnScreen:keepOnScreen];
if (!avoidWindowResize) {
[self resizeWindowToFitContentSize:contentSize
keepOnScreen:keepOnScreen];
}
}
}
keepOnScreen = NO;
shouldKeepGUISize = NO;
}
}
@@ -657,7 +675,6 @@
{
if (vimView && [vimView textView]) {
[[vimView textView] setLinespace:(float)linespace];
shouldMaximizeWindow = shouldResizeVimView = YES;
}
}
@@ -665,7 +682,6 @@
{
if (vimView && [vimView textView]) {
[[vimView textView] setColumnspace:(float)columnspace];
shouldMaximizeWindow = shouldResizeVimView = YES;
}
}
@@ -1177,7 +1193,7 @@
[[window animator] setAlphaValue:0];
} completionHandler:^{
[self maximizeWindow:fullScreenOptions];
// Fade in
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:0.5*duration];
@@ -1196,7 +1212,7 @@
// 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 @@
// full-screen by moving the window out from Split View.
[vimController sendMessage:BackingPropertiesChangedMsgID data:nil];
}
[self updateTablineSeparator];
}
@@ -1519,7 +1535,6 @@
// The tabline separator was toggled so the content view must change
// size.
[self updateResizeConstraints];
shouldResizeVimView = YES;
}
}
+2
View File
@@ -176,8 +176,10 @@ enum {
SetTextRowsMsgID,
SetTextColumnsMsgID,
SetTextDimensionsMsgID,
SetTextDimensionsNoResizeWindowMsgID,
LiveResizeMsgID,
SetTextDimensionsReplyMsgID,
ResizeViewMsgID,
SetWindowTitleMsgID,
ScrollWheelMsgID,
MouseDownMsgID,
+2
View File
@@ -30,8 +30,10 @@ char *MessageStrings[] =
"SetTextRowsMsgID",
"SetTextColumnsMsgID",
"SetTextDimensionsMsgID",
"SetTextDimensionsNoResizeWindowMsgID",
"LiveResizeMsgID",
"SetTextDimensionsReplyMsgID",
"ResizeViewMsgID",
"SetWindowTitleMsgID",
"ScrollWheelMsgID",
"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
* coordinates.
+10
View File
@@ -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)
+2
View File
@@ -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);