Skip to content

Commit b3edaa4

Browse files
committed
Allows smooth resizing of MacVim's window
Adds a setting that allows for smoothly resizing the window. Previously, MacVim would only allow resizing in fixed increment of the grid size and snap to such sizes. This was a little more consistent with how terminals tend to work, and allows for optimal window sizing, and it was also an artifact of the old MacVim renderer where it didn't have a stateful renderer that could repaint the text view. The snapping could be jarring for users more used to modern text editors which allow for smoothly resizing of the window though, and it makes third party tools that could snap macOS windows to the side not work properly as there's usually a gap near the bottom. With guioption-k, MacVim already allows for decoupling the window size from the Vim's grid size anyway, so adding smooth resizing allows to work much better under those assumptions. In addition to allowing smooth resizing, this change also makes it so that the CoreText renderer will fill to the right a little bit when rendering the rightmost column when MacVim's window size isn't exactly the Vim grid size. Previously, if a color scheme has NonText color (e.g. desert), or the user has 'cursorline' set, smooth resize (or in full screen or guioption-k) would leave a gap to the right, looking a little ugly. This allows the last column's to fully fill to the right, resulting in a much more consistent look when resizing the window. Close #948
1 parent 801217e commit b3edaa4

12 files changed

+131
-28
lines changed

runtime/doc/gui_mac.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ KEY VALUE ~
273273
*MMNoTitleBarWindow* hide title bar [bool]
274274
*MMTitlebarAppearsTransparent* enable a transparent titlebar [bool]
275275
*MMAppearanceModeSelection* dark mode selection (|macvim-dark-mode|)[bool]
276+
*MMSmoothResize* allow smooth resizing of MacVim window [bool]
276277
*MMShareFindPboard* share search text to Find Pasteboard [bool]
277278
*MMShowAddTabButton* enable "add tab" button on tabline [bool]
278279
*MMTabMaxWidth* maximum width of a tab [int]

runtime/doc/tags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5418,6 +5418,7 @@ MMNonNativeFullScreenSafeAreaBehavior gui_mac.txt /*MMNonNativeFullScreenSafeAre
54185418
MMNonNativeFullScreenShowMenu gui_mac.txt /*MMNonNativeFullScreenShowMenu*
54195419
MMShareFindPboard gui_mac.txt /*MMShareFindPboard*
54205420
MMShowAddTabButton gui_mac.txt /*MMShowAddTabButton*
5421+
MMSmoothResize gui_mac.txt /*MMSmoothResize*
54215422
MMTabMaxWidth gui_mac.txt /*MMTabMaxWidth*
54225423
MMTabMinWidth gui_mac.txt /*MMTabMinWidth*
54235424
MMTabOptimumWidth gui_mac.txt /*MMTabOptimumWidth*

src/MacVim/Base.lproj/Preferences.xib

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
2121
<userDefaultsController representsSharedInstance="YES" id="58" userLabel="Shared Defaults"/>
2222
<customView id="115" userLabel="General">
23-
<rect key="frame" x="0.0" y="0.0" width="483" height="314"/>
23+
<rect key="frame" x="0.0" y="0.0" width="483" height="337"/>
2424
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
2525
<subviews>
2626
<customView id="5x5-P0-afk" userLabel="Open untitled window">
27-
<rect key="frame" x="19" y="234" width="433" height="58"/>
28-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
27+
<rect key="frame" x="20" y="259" width="433" height="58"/>
28+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
2929
<subviews>
3030
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="117">
3131
<rect key="frame" x="-2" y="41" width="187" height="17"/>
@@ -70,8 +70,8 @@
7070
</subviews>
7171
</customView>
7272
<customView id="p6o-fo-STi" userLabel="Open files from applications">
73-
<rect key="frame" x="19" y="94" width="433" height="132"/>
74-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
73+
<rect key="frame" x="20" y="119" width="433" height="132"/>
74+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
7575
<subviews>
7676
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="116">
7777
<rect key="frame" x="-2" y="115" width="187" height="17"/>
@@ -149,8 +149,8 @@
149149
</subviews>
150150
</customView>
151151
<customView id="dlz-JQ-U4e" userLabel="After last window closes">
152-
<rect key="frame" x="19" y="66" width="381" height="22"/>
153-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
152+
<rect key="frame" x="20" y="89" width="381" height="22"/>
153+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
154154
<subviews>
155155
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="126">
156156
<rect key="frame" x="-2" y="3" width="187" height="17"/>
@@ -182,9 +182,37 @@
182182
</popUpButton>
183183
</subviews>
184184
</customView>
185+
<customView id="6BL-o0-OrR" userLabel="Window Resizing">
186+
<rect key="frame" x="20" y="64" width="444" height="17"/>
187+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
188+
<subviews>
189+
<button id="f9h-8n-asD" userLabel="allow smooth resizing">
190+
<rect key="frame" x="188" y="-1" width="258" height="18"/>
191+
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
192+
<string key="toolTip">Smoothly resizes MacVim's window instead of fixing it to the grid size. It's also recommended to set "guioptions+=k" in your vimrc when this is set.</string>
193+
<buttonCell key="cell" type="check" title="Smoothly resizes window" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="4YN-AX-Vrz">
194+
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
195+
<font key="font" metaFont="system"/>
196+
</buttonCell>
197+
<connections>
198+
<action selector="smoothResizeChanged:" target="-2" id="paG-Lx-hcb"/>
199+
<binding destination="58" name="value" keyPath="values.MMSmoothResize" id="Wkt-gU-ZnK"/>
200+
</connections>
201+
</button>
202+
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="Lmi-H0-cPd" userLabel="Window resizing">
203+
<rect key="frame" x="-2" y="0.0" width="187" height="17"/>
204+
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
205+
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Resizing window:" id="ExQ-6y-pyN" userLabel="Window resizing:">
206+
<font key="font" metaFont="system"/>
207+
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
208+
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
209+
</textFieldCell>
210+
</textField>
211+
</subviews>
212+
</customView>
185213
<customView id="0hT-y8-Hge" userLabel="Updater">
186-
<rect key="frame" x="19" y="22" width="444" height="36"/>
187-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
214+
<rect key="frame" x="20" y="20" width="444" height="36"/>
215+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
188216
<subviews>
189217
<button id="122">
190218
<rect key="frame" x="188" y="18" width="258" height="18"/>
@@ -226,7 +254,7 @@
226254
</subviews>
227255
</customView>
228256
</subviews>
229-
<point key="canvasLocation" x="138" y="20"/>
257+
<point key="canvasLocation" x="137.5" y="21.5"/>
230258
</customView>
231259
<customView id="hr4-G4-3ZG" userLabel="Appearance">
232260
<rect key="frame" x="0.0" y="0.0" width="483" height="315"/>

src/MacVim/MMAppController.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060

6161
- (void)refreshAllAppearances;
6262
- (void)refreshAllFonts;
63+
- (void)refreshAllResizeConstraints;
6364

6465
- (IBAction)newWindow:(id)sender;
6566
- (IBAction)newWindowAndActivate:(id)sender;

src/MacVim/MMAppController.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ + (void)initialize
252252
[NSNumber numberWithBool:NO], MMNonNativeFullScreenShowMenuKey,
253253
[NSNumber numberWithInt:0], MMNonNativeFullScreenSafeAreaBehaviorKey,
254254
[NSNumber numberWithBool:YES], MMShareFindPboardKey,
255+
[NSNumber numberWithBool:NO], MMSmoothResizeKey,
255256
nil];
256257

257258
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
@@ -1132,6 +1133,15 @@ - (void)refreshAllFonts
11321133
}
11331134
}
11341135

1136+
- (void)refreshAllResizeConstraints
1137+
{
1138+
const unsigned count = [vimControllers count];
1139+
for (unsigned i = 0; i < count; ++i) {
1140+
MMVimController *vc = [vimControllers objectAtIndex:i];
1141+
[vc.windowController updateResizeConstraints:YES];
1142+
}
1143+
}
1144+
11351145
- (IBAction)newWindow:(id)sender
11361146
{
11371147
ASLogDebug(@"Open new window");

src/MacVim/MMCoreTextView.m

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,10 +835,26 @@ - (void)drawRect:(NSRect)rect
835835
cell.fg ^= 0xFFFFFF;
836836
cell.sp ^= 0xFFFFFF;
837837
}
838+
839+
// Fill background
838840
if (cell.bg != defaultBg && ALPHA(cell.bg) > 0) {
841+
CGRect fillCellRect = cellRect;
842+
843+
if (c == grid.cols - 1 || (c == grid.cols - 2 && (cell.textFlags & DRAW_WIDE))) {
844+
// Fill a little extra to the right if this is the last
845+
// column, and the frame size isn't exactly the same size
846+
// as the grid (due to smooth resizing, etc). This makes it
847+
// look less ugly and more consisten. See rectForRow:'s
848+
// implementation for extra comments.
849+
CGFloat extraWidth = rowRect.origin.x + rowRect.size.width - (cellRect.size.width + cellRect.origin.x);
850+
fillCellRect.size.width += extraWidth;
851+
}
852+
839853
CGContextSetFillColor(ctx, COMPONENTS(cell.bg));
840-
CGContextFillRect(ctx, cellRect);
854+
CGContextFillRect(ctx, fillCellRect);
841855
}
856+
857+
// Handle signs
842858
if (cell.sign) {
843859
CGRect signRect = cellRect;
844860
signRect.size.width *= 2;
@@ -847,6 +863,8 @@ - (void)drawRect:(NSRect)rect
847863
operation:(cell.inverted ? NSCompositingOperationDifference : NSCompositingOperationSourceOver)
848864
fraction:1.0];
849865
}
866+
867+
// Insertion point (cursor)
850868
if (cell.insertionPoint.color && cell.insertionPoint.fraction) {
851869
float frac = cell.insertionPoint.fraction / 100.0;
852870
NSRect rect = cellRect;
@@ -867,6 +885,8 @@ - (void)drawRect:(NSRect)rect
867885
NSRectFill(rect);
868886
}
869887
}
888+
889+
// Text underline styles
870890
if (cell.textFlags & DRAW_UNDERL) {
871891
CGRect rect = CGRectMake(cellRect.origin.x, cellRect.origin.y+0.4*fontDescent, cellRect.size.width, 1);
872892
CGContextSetFillColor(ctx, COMPONENTS(cell.sp));
@@ -879,6 +899,8 @@ - (void)drawRect:(NSRect)rect
879899
CGContextSetRGBStrokeColor(ctx, RED(cell.sp), GREEN(cell.sp), BLUE(cell.sp), ALPHA(cell.sp));
880900
CGContextStrokePath(ctx);
881901
}
902+
903+
// Draw the actual text
882904
if (cell.string) {
883905
if (!ligatures || lastStringCell.fg != cell.fg || lastStringCell.textFlags != cell.textFlags)
884906
flushLineString();
@@ -894,6 +916,7 @@ - (void)drawRect:(NSRect)rect
894916
} else {
895917
flushLineString();
896918
}
919+
897920
if (cell.textFlags & DRAW_WIDE)
898921
c++;
899922
}
@@ -1067,6 +1090,19 @@ - (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
10671090
rect.size.width = nc*cellSize.width;
10681091
rect.size.height = nr*cellSize.height;
10691092

1093+
// Under smooth resizing, full screen, or guioption-k; we frequently have a frame size that's not
1094+
// aligned with the exact grid size. If the user has 'cursorline' set, or the color scheme uses
1095+
// the NonText highlight group, this will leave a small gap on the right filled with bg color looking
1096+
// a little weird. Just fill a little extra to the right for the last column to make it look less weird.
1097+
//
1098+
// Note that we don't do this for filling the bottom since it's used only for cmdline which isn't usually
1099+
// colored anyway.
1100+
if (col + nc == grid.cols) {
1101+
const int insetRight = [[NSUserDefaults standardUserDefaults] integerForKey:MMTextInsetRightKey];
1102+
CGFloat extraWidth = frame.size.width - insetRight - (rect.size.width + rect.origin.x);
1103+
rect.size.width += extraWidth;
1104+
}
1105+
10701106
return rect;
10711107
}
10721108

src/MacVim/MMPreferenceController.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@
2727
- (IBAction)openInCurrentWindowSelectionChanged:(id)sender;
2828
- (IBAction)checkForUpdatesChanged:(id)sender;
2929
- (IBAction)appearanceChanged:(id)sender;
30+
- (IBAction)lastWindowClosedChanged:(id)sender;
31+
- (IBAction)openUntitledWindowChanged:(id)sender;
32+
- (IBAction)smoothResizeChanged:(id)sender;
33+
34+
// Appearance pane
35+
- (IBAction)fontPropertiesChanged:(id)sender;
36+
3037
@end

src/MacVim/MMPreferenceController.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,9 @@ -(IBAction)openUntitledWindowChanged:(id)sender
163163
}
164164
}
165165

166+
- (IBAction)smoothResizeChanged:(id)sender
167+
{
168+
[[MMAppController sharedInstance] refreshAllResizeConstraints];
169+
}
170+
166171
@end

src/MacVim/MMWindowController.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777

7878
- (void)setBackgroundOption:(int)dark;
7979
- (void)refreshApperanceMode;
80+
- (void)updateResizeConstraints:(BOOL)resizeWindow;
8081

8182
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore;
8283
- (void)setFont:(NSFont *)font;

src/MacVim/MMWindowController.m

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ - (void)resizeWindowToFitContentSize:(NSSize)contentSize
8686
keepOnScreen:(BOOL)onScreen;
8787
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize;
8888
- (NSRect)constrainFrame:(NSRect)frame;
89-
- (void)updateResizeConstraints;
9089
- (NSTabViewItem *)addNewTabViewItem;
9190
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
9291
- (void)updateTablineSeparator;
@@ -332,7 +331,7 @@ - (BOOL)presentWindow:(id)unused
332331
// code that is executed before this point must not depend on the screen!
333332

334333
[[MMAppController sharedInstance] windowControllerWillOpen:self];
335-
[self updateResizeConstraints];
334+
[self updateResizeConstraints:NO];
336335
[self resizeWindowToFitContentSize:[vimView desiredSize]
337336
keepOnScreen:YES];
338337

@@ -707,7 +706,7 @@ - (void)setFont:(NSFont *)font
707706
}
708707

709708
[[vimView textView] setFont:font];
710-
[self updateResizeConstraints];
709+
[self updateResizeConstraints:NO];
711710
shouldMaximizeWindow = YES;
712711
}
713712

@@ -1519,6 +1518,31 @@ - (NSTouchBar *)makeTouchBar
15191518
}
15201519
#endif
15211520

1521+
/// This will update the window's resizing constraints to either be smooth or rounded to whole cells.
1522+
///
1523+
/// @param resizeWindow If specified, will also resize the window itself down to match the Vim view's desired size.
1524+
- (void)updateResizeConstraints:(BOOL)resizeWindow
1525+
{
1526+
if (!setupDone) return;
1527+
1528+
// If smooth resizing is not set, set the resize increments to exactly
1529+
// match the font size; this way the window will always hold an integer
1530+
// number of (rows,columns). Otherwise, just allow arbitrary resizing.
1531+
const BOOL smoothResize = [[NSUserDefaults standardUserDefaults] boolForKey:MMSmoothResizeKey];
1532+
const NSSize desiredResizeConstraints = smoothResize ?
1533+
NSMakeSize(1, 1) :
1534+
[[vimView textView] cellSize];
1535+
[decoratedWindow setContentResizeIncrements:desiredResizeConstraints];
1536+
1537+
const NSSize minSize = [vimView minSize];
1538+
[decoratedWindow setContentMinSize:minSize];
1539+
1540+
if (resizeWindow) {
1541+
if (!smoothResize)
1542+
shouldResizeVimView = YES;
1543+
}
1544+
}
1545+
15221546
@end // MMWindowController
15231547

15241548

@@ -1645,19 +1669,6 @@ - (NSRect)constrainFrame:(NSRect)frame
16451669
return [decoratedWindow frameRectForContentRect:contentRect];
16461670
}
16471671

1648-
- (void)updateResizeConstraints
1649-
{
1650-
if (!setupDone) return;
1651-
1652-
// Set the resize increments to exactly match the font size; this way the
1653-
// window will always hold an integer number of (rows,columns).
1654-
NSSize cellSize = [[vimView textView] cellSize];
1655-
[decoratedWindow setContentResizeIncrements:cellSize];
1656-
1657-
NSSize minSize = [vimView minSize];
1658-
[decoratedWindow setContentMinSize:minSize];
1659-
}
1660-
16611672
- (NSTabViewItem *)addNewTabViewItem
16621673
{
16631674
return [vimView addNewTabViewItem];
@@ -1711,7 +1722,7 @@ - (void)hideTablineSeparator:(BOOL)hide
17111722
if ([decoratedWindow hideTablineSeparator:hide]) {
17121723
// The tabline separator was toggled so the content view must change
17131724
// size.
1714-
[self updateResizeConstraints];
1725+
[self updateResizeConstraints:NO];
17151726
}
17161727
}
17171728

src/MacVim/Miscellaneous.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ extern NSString *MMUseMouseTimeKey;
5858
extern NSString *MMFullScreenFadeTimeKey;
5959
extern NSString *MMNonNativeFullScreenShowMenuKey;
6060
extern NSString *MMNonNativeFullScreenSafeAreaBehaviorKey;
61+
extern NSString *MMSmoothResizeKey;
6162

6263

6364
// Enum for MMUntitledWindowKey

src/MacVim/Miscellaneous.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
NSString *MMFullScreenFadeTimeKey = @"MMFullScreenFadeTime";
5555
NSString *MMNonNativeFullScreenShowMenuKey = @"MMNonNativeFullScreenShowMenu";
5656
NSString *MMNonNativeFullScreenSafeAreaBehaviorKey = @"MMNonNativeFullScreenSafeAreaBehavior";
57+
NSString *MMSmoothResizeKey = @"MMSmoothResize";
5758

5859

5960

0 commit comments

Comments
 (0)