Skip to content

Commit 1333bc6

Browse files
committed
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
1 parent 351faf9 commit 1333bc6

12 files changed

Lines changed: 95 additions & 22 deletions

src/MacVim/MMBackend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ extern NSTimeInterval MMBalloonEvalInternalDelay;
105105
- (BOOL)tabBarVisible;
106106
- (void)showTabBar:(BOOL)enable;
107107
- (void)setRows:(int)rows columns:(int)cols;
108+
- (void)resizeView;
108109
- (void)setWindowTitle:(char *)title;
109110
- (void)setDocumentFilename:(char *)filename;
110111
- (char *)browseForFileWithAttributes:(NSDictionary *)attr;

src/MacVim/MMBackend.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,11 @@ - (void)setRows:(int)rows columns:(int)cols
836836
[self queueMessage:SetTextDimensionsMsgID data:data];
837837
}
838838

839+
- (void)resizeView
840+
{
841+
[self queueMessage:ResizeViewMsgID data:nil];
842+
}
843+
839844
- (void)setWindowTitle:(char *)title
840845
{
841846
NSMutableData *data = [NSMutableData data];
@@ -1997,6 +2002,7 @@ - (void)handleInputEvent:(int)msgid data:(NSData *)data
19972002

19982003
tabpage_move(idx);
19992004
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid
2005+
|| SetTextDimensionsNoResizeWindowMsgID == msgid
20002006
|| SetTextRowsMsgID == msgid || SetTextColumnsMsgID == msgid) {
20012007
if (!data) return;
20022008
const void *bytes = [data bytes];
@@ -2028,6 +2034,8 @@ - (void)handleInputEvent:(int)msgid data:(NSData *)data
20282034
[self queueMessage:msgid data:d];
20292035

20302036
gui_resize_shell(cols, rows);
2037+
} else if (ResizeViewMsgID == msgid) {
2038+
[self queueMessage:msgid data:data];
20312039
} else if (ExecuteMenuMsgID == msgid) {
20322040
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
20332041
if (attrs) {

src/MacVim/MMVimController.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
574574
[windowController showTabBar:NO];
575575
[self sendMessage:BackingPropertiesChangedMsgID data:nil];
576576
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid ||
577+
SetTextDimensionsNoResizeWindowMsgID == msgid ||
577578
SetTextDimensionsReplyMsgID == msgid) {
578579
const void *bytes = [data bytes];
579580
int rows = *((int*)bytes); bytes += sizeof(int);
@@ -583,11 +584,16 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
583584
// acknowledges it with a reply message. When this happens the window
584585
// should not move (the frontend would already have moved the window).
585586
BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid;
587+
588+
BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid;
586589

587590
[windowController setTextDimensionsWithRows:rows
588591
columns:cols
589592
isLive:(LiveResizeMsgID==msgid)
593+
keepGUISize:keepGUISize
590594
keepOnScreen:onScreen];
595+
} else if (ResizeViewMsgID == msgid) {
596+
[windowController resizeView];
591597
} else if (SetWindowTitleMsgID == msgid) {
592598
const void *bytes = [data bytes];
593599
int len = *((int*)bytes); bytes += sizeof(int);

src/MacVim/MMVimView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
- (void)viewWillStartLiveResize;
5656
- (void)viewDidEndLiveResize;
5757
- (void)setFrameSize:(NSSize)size;
58+
- (void)setFrameSizeKeepGUISize:(NSSize)size;
5859
- (void)setFrame:(NSRect)frame;
5960

6061
@end

src/MacVim/MMVimView.m

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ - (MMScroller *)scrollbarForIdentifier:(int32_t)ident index:(unsigned *)idx;
6060
- (NSSize)vimViewSizeForTextViewSize:(NSSize)textViewSize;
6161
- (NSRect)textViewRectForVimViewSize:(NSSize)contentSize;
6262
- (NSTabView *)tabView;
63-
- (void)frameSizeMayHaveChanged;
63+
- (void)frameSizeMayHaveChanged:(BOOL)keepGUISize;
6464
@end
6565

6666

@@ -610,14 +610,25 @@ - (void)setFrameSize:(NSSize)size
610610
// row will result in the vim view holding more rows than the can fit
611611
// inside the window.)
612612
[super setFrameSize:size];
613-
[self frameSizeMayHaveChanged];
613+
[self frameSizeMayHaveChanged:NO];
614+
}
615+
616+
- (void)setFrameSizeKeepGUISize:(NSSize)size
617+
{
618+
// NOTE: Instead of only acting when a frame was resized, we do some
619+
// updating each time a frame may be resized. (At the moment, if we only
620+
// respond to actual frame changes then typing ":set lines=1000" twice in a
621+
// row will result in the vim view holding more rows than the can fit
622+
// inside the window.)
623+
[super setFrameSize:size];
624+
[self frameSizeMayHaveChanged:YES];
614625
}
615626

616627
- (void)setFrame:(NSRect)frame
617628
{
618629
// See comment in setFrameSize: above.
619630
[super setFrame:frame];
620-
[self frameSizeMayHaveChanged];
631+
[self frameSizeMayHaveChanged:NO];
621632
}
622633

623634
@end // MMVimView
@@ -867,7 +878,7 @@ - (NSTabView *)tabView
867878
return tabView;
868879
}
869880

870-
- (void)frameSizeMayHaveChanged
881+
- (void)frameSizeMayHaveChanged:(BOOL)keepGUISize
871882
{
872883
// NOTE: Whenever a call is made that may have changed the frame size we
873884
// take the opportunity to make sure all subviews are in place and that the
@@ -903,7 +914,7 @@ - (void)frameSizeMayHaveChanged
903914
if (constrained[0] != rows || constrained[1] != cols) {
904915
NSData *data = [NSData dataWithBytes:constrained length:2*sizeof(int)];
905916
int msgid = [self inLiveResize] ? LiveResizeMsgID
906-
: SetTextDimensionsMsgID;
917+
: (keepGUISize ? SetTextDimensionsNoResizeWindowMsgID : SetTextDimensionsMsgID);
907918

908919
ASLogDebug(@"Notify Vim that text dimensions changed from %dx%d to "
909920
"%dx%d (%s)", cols, rows, constrained[1], constrained[0],

src/MacVim/MMWindowController.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
BOOL setupDone;
2525
BOOL windowPresented;
2626
BOOL shouldResizeVimView;
27+
BOOL shouldKeepGUISize;
2728
BOOL shouldRestoreUserTopLeft;
2829
BOOL shouldMaximizeWindow;
2930
int updateToolbarFlag;
@@ -59,7 +60,9 @@
5960
- (void)updateTabsWithData:(NSData *)data;
6061
- (void)selectTabWithIndex:(int)idx;
6162
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
63+
keepGUISize:(BOOL)keepGUISize
6264
keepOnScreen:(BOOL)onScreen;
65+
- (void)resizeView;
6366
- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state;
6467
- (void)setTitle:(NSString *)title;
6568
- (void)setDocumentFilename:(NSString *)filename;

src/MacVim/MMWindowController.m

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ - (id)initWithVimController:(MMVimController *)controller
174174

175175
[win setDelegate:self];
176176
[win setInitialFirstResponder:[vimView textView]];
177-
177+
178178
if ([win styleMask] & NSWindowStyleMaskTexturedBackground) {
179179
// On Leopard, we want to have a textured window to have nice
180180
// looking tabs. But the textured window look implies rounded
@@ -381,6 +381,7 @@ - (void)selectTabWithIndex:(int)idx
381381
}
382382

383383
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
384+
keepGUISize:(BOOL)keepGUISize
384385
keepOnScreen:(BOOL)onScreen
385386
{
386387
ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d "
@@ -399,7 +400,7 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
399400

400401
[vimView setDesiredRows:rows columns:cols];
401402

402-
if (setupDone && !live) {
403+
if (setupDone && !live && !keepGUISize) {
403404
shouldResizeVimView = YES;
404405
keepOnScreen = onScreen;
405406
}
@@ -428,6 +429,15 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
428429
}
429430
}
430431

432+
- (void)resizeView
433+
{
434+
if (setupDone)
435+
{
436+
shouldResizeVimView = YES;
437+
shouldKeepGUISize = YES;
438+
}
439+
}
440+
431441
- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state
432442
{
433443
[self setTextDimensionsWithRows:rows
@@ -503,19 +513,13 @@ - (void)createScrollbarWithIdentifier:(int32_t)ident type:(int)type
503513
- (BOOL)destroyScrollbarWithIdentifier:(int32_t)ident
504514
{
505515
BOOL scrollbarHidden = [vimView destroyScrollbarWithIdentifier:ident];
506-
shouldResizeVimView = shouldResizeVimView || scrollbarHidden;
507-
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarHidden;
508-
509516
return scrollbarHidden;
510517
}
511518

512519
- (BOOL)showScrollbarWithIdentifier:(int32_t)ident state:(BOOL)visible
513520
{
514521
BOOL scrollbarToggled = [vimView showScrollbarWithIdentifier:ident
515522
state:visible];
516-
shouldResizeVimView = shouldResizeVimView || scrollbarToggled;
517-
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarToggled;
518-
519523
return scrollbarToggled;
520524
}
521525

@@ -600,7 +604,18 @@ - (void)processInputQueueDidFinish
600604
fullScreenWindow ? [fullScreenWindow frame].size :
601605
fullScreenEnabled ? desiredWindowSize :
602606
[self constrainContentSizeToScreenSize:[vimView desiredSize]]];
603-
[vimView setFrameSize:contentSize];
607+
608+
// Setting 'guioptions+=k' will make shouldKeepGUISize true, which
609+
// means avoid resizing the window. Instead, resize the view instead
610+
// to keep the GUI window's size consistent.
611+
bool avoidWindowResize = shouldKeepGUISize && !fullScreenEnabled;
612+
613+
if (!avoidWindowResize) {
614+
[vimView setFrameSize:contentSize];
615+
}
616+
else {
617+
[vimView setFrameSizeKeepGUISize:originalSize];
618+
}
604619

605620
if (fullScreenWindow) {
606621
// NOTE! Don't mark the full-screen content view as needing an
@@ -613,12 +628,15 @@ - (void)processInputQueueDidFinish
613628
[fullScreenWindow centerView];
614629
}
615630
} else {
616-
[self resizeWindowToFitContentSize:contentSize
617-
keepOnScreen:keepOnScreen];
631+
if (!avoidWindowResize) {
632+
[self resizeWindowToFitContentSize:contentSize
633+
keepOnScreen:keepOnScreen];
634+
}
618635
}
619636
}
620637

621638
keepOnScreen = NO;
639+
shouldKeepGUISize = NO;
622640
}
623641
}
624642

@@ -657,15 +675,13 @@ - (void)adjustLinespace:(int)linespace
657675
{
658676
if (vimView && [vimView textView]) {
659677
[[vimView textView] setLinespace:(float)linespace];
660-
shouldMaximizeWindow = shouldResizeVimView = YES;
661678
}
662679
}
663680

664681
- (void)adjustColumnspace:(int)columnspace
665682
{
666683
if (vimView && [vimView textView]) {
667684
[[vimView textView] setColumnspace:(float)columnspace];
668-
shouldMaximizeWindow = shouldResizeVimView = YES;
669685
}
670686
}
671687

@@ -1177,7 +1193,7 @@ - (void)window:(NSWindow *)window
11771193
[[window animator] setAlphaValue:0];
11781194
} completionHandler:^{
11791195
[self maximizeWindow:fullScreenOptions];
1180-
1196+
11811197
// Fade in
11821198
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
11831199
[context setDuration:0.5*duration];
@@ -1196,7 +1212,7 @@ - (void)windowWillEnterFullScreen:(NSNotification *)notification
11961212

11971213
// The separator should never be visible in fullscreen or split-screen.
11981214
[decoratedWindow hideTablineSeparator:YES];
1199-
1215+
12001216
// ASSUMPTION: fullScreenEnabled always reflects the state of Vim's 'fu'.
12011217
if (!fullScreenEnabled) {
12021218
ASLogDebug(@"Full-screen out of sync, tell Vim to set 'fu'");
@@ -1298,7 +1314,7 @@ - (void)windowDidExitFullScreen:(NSNotification *)notification
12981314
// full-screen by moving the window out from Split View.
12991315
[vimController sendMessage:BackingPropertiesChangedMsgID data:nil];
13001316
}
1301-
1317+
13021318
[self updateTablineSeparator];
13031319
}
13041320

@@ -1519,7 +1535,6 @@ - (void)hideTablineSeparator:(BOOL)hide
15191535
// The tabline separator was toggled so the content view must change
15201536
// size.
15211537
[self updateResizeConstraints];
1522-
shouldResizeVimView = YES;
15231538
}
15241539
}
15251540

src/MacVim/MacVim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,10 @@ enum {
176176
SetTextRowsMsgID,
177177
SetTextColumnsMsgID,
178178
SetTextDimensionsMsgID,
179+
SetTextDimensionsNoResizeWindowMsgID,
179180
LiveResizeMsgID,
180181
SetTextDimensionsReplyMsgID,
182+
ResizeViewMsgID,
181183
SetWindowTitleMsgID,
182184
ScrollWheelMsgID,
183185
MouseDownMsgID,

src/MacVim/MacVim.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
"SetTextRowsMsgID",
3131
"SetTextColumnsMsgID",
3232
"SetTextDimensionsMsgID",
33+
"SetTextDimensionsNoResizeWindowMsgID",
3334
"LiveResizeMsgID",
3435
"SetTextDimensionsReplyMsgID",
36+
"ResizeViewMsgID",
3537
"SetWindowTitleMsgID",
3638
"ScrollWheelMsgID",
3739
"MouseDownMsgID",

src/MacVim/gui_macvim.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,6 +1732,18 @@
17321732
}
17331733

17341734

1735+
/*
1736+
* Re-calculates size of the Vim view to fit within the window without having
1737+
* to resize the window. Usually happens after UI elements have changed (e.g.
1738+
* adding / removing a toolbar) when guioptions 'k' is set.
1739+
*/
1740+
void
1741+
gui_mch_resize_view()
1742+
{
1743+
[[MMBackend sharedInstance] resizeView];
1744+
}
1745+
1746+
17351747
/*
17361748
* Set the position of the top left corner of the window to the given
17371749
* coordinates.

0 commit comments

Comments
 (0)