Skip to content

Commit d02a194

Browse files
authored
Merge pull request #731 from ychin/guioptions-k-2
Support guioptions 'k' flag in MacVim (2nd attempt)
2 parents 33c2021 + e35b0a6 commit d02a194

File tree

12 files changed

+136
-27
lines changed

12 files changed

+136
-27
lines changed

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
@@ -629,6 +629,7 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
629629
[windowController showTabBar:NO];
630630
[self sendMessage:BackingPropertiesChangedMsgID data:nil];
631631
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid ||
632+
SetTextDimensionsNoResizeWindowMsgID == msgid ||
632633
SetTextDimensionsReplyMsgID == msgid) {
633634
const void *bytes = [data bytes];
634635
int rows = *((int*)bytes); bytes += sizeof(int);
@@ -638,11 +639,16 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
638639
// acknowledges it with a reply message. When this happens the window
639640
// should not move (the frontend would already have moved the window).
640641
BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid;
642+
643+
BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid;
641644

642645
[windowController setTextDimensionsWithRows:rows
643646
columns:cols
644647
isLive:(LiveResizeMsgID==msgid)
648+
keepGUISize:keepGUISize
645649
keepOnScreen:onScreen];
650+
} else if (ResizeViewMsgID == msgid) {
651+
[windowController resizeView];
646652
} else if (SetWindowTitleMsgID == msgid) {
647653
const void *bytes = [data bytes];
648654
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: 73 additions & 22 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
@@ -363,11 +363,9 @@ - (void)moveWindowAcrossScreens:(NSPoint)topLeft
363363
// HACK! This method moves a window to a new origin and to a different
364364
// screen. This is primarily useful to avoid a scenario where such a move
365365
// will trigger a resize, even though the frame didn't actually change size.
366-
// This method should not be called unless the new origin is definitely on
367-
// a different screen, otherwise the next legitimate resize message will
368-
// be skipped.
369366
resizingDueToMove = YES;
370367
[[self window] setFrameTopLeftPoint:topLeft];
368+
resizingDueToMove = NO;
371369
}
372370

373371
- (void)updateTabsWithData:(NSData *)data
@@ -381,10 +379,12 @@ - (void)selectTabWithIndex:(int)idx
381379
}
382380

383381
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
382+
keepGUISize:(BOOL)keepGUISize
384383
keepOnScreen:(BOOL)onScreen
385384
{
386385
ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d "
387-
"keepOnScreen:%d", rows, cols, live, onScreen);
386+
"keepGUISize:%d "
387+
"keepOnScreen:%d", rows, cols, live, keepGUISize, onScreen);
388388

389389
// NOTE: The only place where the (rows,columns) of the vim view are
390390
// modified is here and when entering/leaving full-screen. Setting these
@@ -399,7 +399,7 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
399399

400400
[vimView setDesiredRows:rows columns:cols];
401401

402-
if (setupDone && !live) {
402+
if (setupDone && !live && !keepGUISize) {
403403
shouldResizeVimView = YES;
404404
keepOnScreen = onScreen;
405405
}
@@ -428,11 +428,21 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
428428
}
429429
}
430430

431+
- (void)resizeView
432+
{
433+
if (setupDone)
434+
{
435+
shouldResizeVimView = YES;
436+
shouldKeepGUISize = YES;
437+
}
438+
}
439+
431440
- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state
432441
{
433442
[self setTextDimensionsWithRows:rows
434443
columns:cols
435444
isLive:NO
445+
keepGUISize:NO
436446
keepOnScreen:YES];
437447

438448
// NOTE: If state==0 then the window should be put in the non-zoomed
@@ -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

@@ -644,6 +662,10 @@ - (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode
644662
// showing its hide animation every time a new window is opened. (See
645663
// processInputQueueDidFinish for the reason why we need to delay toggling
646664
// the toolbar when the window is visible.)
665+
//
666+
// Also, the delayed updateToolbar will have the correct shouldKeepGUISize
667+
// set when it's called, which is important for that function to respect
668+
// guioptions 'k'.
647669
if (![decoratedWindow isVisible])
648670
[self updateToolbar];
649671
}
@@ -657,15 +679,13 @@ - (void)adjustLinespace:(int)linespace
657679
{
658680
if (vimView && [vimView textView]) {
659681
[[vimView textView] setLinespace:(float)linespace];
660-
shouldMaximizeWindow = shouldResizeVimView = YES;
661682
}
662683
}
663684

664685
- (void)adjustColumnspace:(int)columnspace
665686
{
666687
if (vimView && [vimView textView]) {
667688
[[vimView textView] setColumnspace:(float)columnspace];
668-
shouldMaximizeWindow = shouldResizeVimView = YES;
669689
}
670690
}
671691

@@ -1039,7 +1059,14 @@ - (void)windowDidResize:(id)sender
10391059
// may resize automatically) we simply set the view to fill the entire
10401060
// window. The vim view takes care of notifying Vim if the number of
10411061
// (rows,columns) changed.
1042-
[vimView setFrameSize:[self contentSize]];
1062+
if (shouldKeepGUISize) {
1063+
// This happens when code manually call setFrame: when we are performing
1064+
// an operation that wants to preserve GUI size (e.g. in updateToolbar:).
1065+
// Respect the wish, and pass that along.
1066+
[vimView setFrameSizeKeepGUISize:[self contentSize]];
1067+
} else {
1068+
[vimView setFrameSize:[self contentSize]];
1069+
}
10431070
}
10441071

10451072
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
@@ -1187,7 +1214,7 @@ - (void)window:(NSWindow *)window
11871214
[[window animator] setAlphaValue:0];
11881215
} completionHandler:^{
11891216
[self maximizeWindow:fullScreenOptions];
1190-
1217+
11911218
// Fade in
11921219
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
11931220
[context setDuration:0.5*duration];
@@ -1206,7 +1233,7 @@ - (void)windowWillEnterFullScreen:(NSNotification *)notification
12061233

12071234
// The separator should never be visible in fullscreen or split-screen.
12081235
[decoratedWindow hideTablineSeparator:YES];
1209-
1236+
12101237
// ASSUMPTION: fullScreenEnabled always reflects the state of Vim's 'fu'.
12111238
if (!fullScreenEnabled) {
12121239
ASLogDebug(@"Full-screen out of sync, tell Vim to set 'fu'");
@@ -1308,7 +1335,7 @@ - (void)windowDidExitFullScreen:(NSNotification *)notification
13081335
// full-screen by moving the window out from Split View.
13091336
[vimController sendMessage:BackingPropertiesChangedMsgID data:nil];
13101337
}
1311-
1338+
13121339
[self updateTablineSeparator];
13131340
}
13141341

@@ -1536,7 +1563,6 @@ - (void)hideTablineSeparator:(BOOL)hide
15361563
// The tabline separator was toggled so the content view must change
15371564
// size.
15381565
[self updateResizeConstraints];
1539-
shouldResizeVimView = YES;
15401566
}
15411567
}
15421568

@@ -1592,7 +1618,32 @@ - (void)updateToolbar
15921618

15931619
// Positive flag shows toolbar, negative hides it.
15941620
BOOL on = updateToolbarFlag > 0 ? YES : NO;
1621+
1622+
NSRect origWindowFrame = [decoratedWindow frame];
1623+
BOOL origHasToolbar = decoratedWindow.toolbar != nil;
1624+
15951625
[decoratedWindow setToolbar:(on ? toolbar : nil)];
1626+
1627+
if (shouldKeepGUISize && !fullScreenEnabled && origHasToolbar != on) {
1628+
// "shouldKeepGUISize" means guioptions has 'k' in it, indicating that user doesn't
1629+
// want the window to resize itself. In non-fullscreen when we call setToolbar:
1630+
// Cocoa automatically resizes the window so we need to un-resize it back to
1631+
// original.
1632+
1633+
NSRect newWindowFrame = [decoratedWindow frame];
1634+
if (newWindowFrame.size.height == origWindowFrame.size.height) {
1635+
// This is an odd case here, where the window has not changed size at all.
1636+
// The addition/removal of toolbar should have changed its size. This means that
1637+
// there isn't enough space to grow the window on the screen. Usually we rely
1638+
// on windowDidResize: to call setFrameSizeKeepGUISize for us but now we have
1639+
// to do it manually in this special case.
1640+
[vimView setFrameSizeKeepGUISize:[self contentSize]];
1641+
}
1642+
else {
1643+
[decoratedWindow setFrame:origWindowFrame display:YES];
1644+
}
1645+
}
1646+
15961647
[self updateTablineSeparator];
15971648

15981649
updateToolbarFlag = 0;

src/MacVim/MacVim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,10 @@ enum {
179179
SetTextRowsMsgID,
180180
SetTextColumnsMsgID,
181181
SetTextDimensionsMsgID,
182+
SetTextDimensionsNoResizeWindowMsgID,
182183
LiveResizeMsgID,
183184
SetTextDimensionsReplyMsgID,
185+
ResizeViewMsgID,
184186
SetWindowTitleMsgID,
185187
ScrollWheelMsgID,
186188
MouseDownMsgID,

0 commit comments

Comments
 (0)