@@ -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 ;
0 commit comments