diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt
index 9151d0f414..5404cd3267 100644
--- a/runtime/doc/gui_mac.txt
+++ b/runtime/doc/gui_mac.txt
@@ -273,6 +273,7 @@ KEY VALUE ~
*MMNoTitleBarWindow* hide title bar [bool]
*MMTitlebarAppearsTransparent* enable a transparent titlebar [bool]
*MMAppearanceModeSelection* dark mode selection (|macvim-dark-mode|)[bool]
+*MMSmoothResize* allow smooth resizing of MacVim window [bool]
*MMShareFindPboard* share search text to Find Pasteboard [bool]
*MMShowAddTabButton* enable "add tab" button on tabline [bool]
*MMTabMaxWidth* maximum width of a tab [int]
diff --git a/runtime/doc/tags b/runtime/doc/tags
index b814dc448b..1e44be0000 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -5418,6 +5418,7 @@ MMNonNativeFullScreenSafeAreaBehavior gui_mac.txt /*MMNonNativeFullScreenSafeAre
MMNonNativeFullScreenShowMenu gui_mac.txt /*MMNonNativeFullScreenShowMenu*
MMShareFindPboard gui_mac.txt /*MMShareFindPboard*
MMShowAddTabButton gui_mac.txt /*MMShowAddTabButton*
+MMSmoothResize gui_mac.txt /*MMSmoothResize*
MMTabMaxWidth gui_mac.txt /*MMTabMaxWidth*
MMTabMinWidth gui_mac.txt /*MMTabMinWidth*
MMTabOptimumWidth gui_mac.txt /*MMTabOptimumWidth*
diff --git a/src/MacVim/Base.lproj/Preferences.xib b/src/MacVim/Base.lproj/Preferences.xib
index 84216c9283..3fa5badc61 100644
--- a/src/MacVim/Base.lproj/Preferences.xib
+++ b/src/MacVim/Base.lproj/Preferences.xib
@@ -20,12 +20,12 @@
-
+
-
-
+
+
@@ -70,8 +70,8 @@
-
-
+
+
@@ -149,8 +149,8 @@
-
-
+
+
@@ -182,9 +182,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
diff --git a/src/MacVim/MMAppController.h b/src/MacVim/MMAppController.h
index 45a32968af..b776bdc20d 100644
--- a/src/MacVim/MMAppController.h
+++ b/src/MacVim/MMAppController.h
@@ -60,6 +60,7 @@
- (void)refreshAllAppearances;
- (void)refreshAllFonts;
+- (void)refreshAllResizeConstraints;
- (IBAction)newWindow:(id)sender;
- (IBAction)newWindowAndActivate:(id)sender;
diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m
index ff5d01238f..95d89867c0 100644
--- a/src/MacVim/MMAppController.m
+++ b/src/MacVim/MMAppController.m
@@ -252,6 +252,7 @@ + (void)initialize
[NSNumber numberWithBool:NO], MMNonNativeFullScreenShowMenuKey,
[NSNumber numberWithInt:0], MMNonNativeFullScreenSafeAreaBehaviorKey,
[NSNumber numberWithBool:YES], MMShareFindPboardKey,
+ [NSNumber numberWithBool:NO], MMSmoothResizeKey,
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
@@ -1132,6 +1133,15 @@ - (void)refreshAllFonts
}
}
+- (void)refreshAllResizeConstraints
+{
+ const unsigned count = [vimControllers count];
+ for (unsigned i = 0; i < count; ++i) {
+ MMVimController *vc = [vimControllers objectAtIndex:i];
+ [vc.windowController updateResizeConstraints:YES];
+ }
+}
+
- (IBAction)newWindow:(id)sender
{
ASLogDebug(@"Open new window");
diff --git a/src/MacVim/MMCoreTextView.m b/src/MacVim/MMCoreTextView.m
index f4c0120a2f..441044415c 100644
--- a/src/MacVim/MMCoreTextView.m
+++ b/src/MacVim/MMCoreTextView.m
@@ -835,10 +835,26 @@ - (void)drawRect:(NSRect)rect
cell.fg ^= 0xFFFFFF;
cell.sp ^= 0xFFFFFF;
}
+
+ // Fill background
if (cell.bg != defaultBg && ALPHA(cell.bg) > 0) {
+ CGRect fillCellRect = cellRect;
+
+ if (c == grid.cols - 1 || (c == grid.cols - 2 && (cell.textFlags & DRAW_WIDE))) {
+ // Fill a little extra to the right if this is the last
+ // column, and the frame size isn't exactly the same size
+ // as the grid (due to smooth resizing, etc). This makes it
+ // look less ugly and more consisten. See rectForRow:'s
+ // implementation for extra comments.
+ CGFloat extraWidth = rowRect.origin.x + rowRect.size.width - (cellRect.size.width + cellRect.origin.x);
+ fillCellRect.size.width += extraWidth;
+ }
+
CGContextSetFillColor(ctx, COMPONENTS(cell.bg));
- CGContextFillRect(ctx, cellRect);
+ CGContextFillRect(ctx, fillCellRect);
}
+
+ // Handle signs
if (cell.sign) {
CGRect signRect = cellRect;
signRect.size.width *= 2;
@@ -847,6 +863,8 @@ - (void)drawRect:(NSRect)rect
operation:(cell.inverted ? NSCompositingOperationDifference : NSCompositingOperationSourceOver)
fraction:1.0];
}
+
+ // Insertion point (cursor)
if (cell.insertionPoint.color && cell.insertionPoint.fraction) {
float frac = cell.insertionPoint.fraction / 100.0;
NSRect rect = cellRect;
@@ -867,6 +885,8 @@ - (void)drawRect:(NSRect)rect
NSRectFill(rect);
}
}
+
+ // Text underline styles
if (cell.textFlags & DRAW_UNDERL) {
CGRect rect = CGRectMake(cellRect.origin.x, cellRect.origin.y+0.4*fontDescent, cellRect.size.width, 1);
CGContextSetFillColor(ctx, COMPONENTS(cell.sp));
@@ -879,6 +899,8 @@ - (void)drawRect:(NSRect)rect
CGContextSetRGBStrokeColor(ctx, RED(cell.sp), GREEN(cell.sp), BLUE(cell.sp), ALPHA(cell.sp));
CGContextStrokePath(ctx);
}
+
+ // Draw the actual text
if (cell.string) {
if (!ligatures || lastStringCell.fg != cell.fg || lastStringCell.textFlags != cell.textFlags)
flushLineString();
@@ -894,6 +916,7 @@ - (void)drawRect:(NSRect)rect
} else {
flushLineString();
}
+
if (cell.textFlags & DRAW_WIDE)
c++;
}
@@ -1067,6 +1090,19 @@ - (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
rect.size.width = nc*cellSize.width;
rect.size.height = nr*cellSize.height;
+ // Under smooth resizing, full screen, or guioption-k; we frequently have a frame size that's not
+ // aligned with the exact grid size. If the user has 'cursorline' set, or the color scheme uses
+ // the NonText highlight group, this will leave a small gap on the right filled with bg color looking
+ // a little weird. Just fill a little extra to the right for the last column to make it look less weird.
+ //
+ // Note that we don't do this for filling the bottom since it's used only for cmdline which isn't usually
+ // colored anyway.
+ if (col + nc == grid.cols) {
+ const int insetRight = [[NSUserDefaults standardUserDefaults] integerForKey:MMTextInsetRightKey];
+ CGFloat extraWidth = frame.size.width - insetRight - (rect.size.width + rect.origin.x);
+ rect.size.width += extraWidth;
+ }
+
return rect;
}
diff --git a/src/MacVim/MMPreferenceController.h b/src/MacVim/MMPreferenceController.h
index 2ef4f9a431..4eed8df52a 100644
--- a/src/MacVim/MMPreferenceController.h
+++ b/src/MacVim/MMPreferenceController.h
@@ -27,4 +27,11 @@
- (IBAction)openInCurrentWindowSelectionChanged:(id)sender;
- (IBAction)checkForUpdatesChanged:(id)sender;
- (IBAction)appearanceChanged:(id)sender;
+- (IBAction)lastWindowClosedChanged:(id)sender;
+- (IBAction)openUntitledWindowChanged:(id)sender;
+- (IBAction)smoothResizeChanged:(id)sender;
+
+// Appearance pane
+- (IBAction)fontPropertiesChanged:(id)sender;
+
@end
diff --git a/src/MacVim/MMPreferenceController.m b/src/MacVim/MMPreferenceController.m
index a5078987fa..eb1ceb90a3 100644
--- a/src/MacVim/MMPreferenceController.m
+++ b/src/MacVim/MMPreferenceController.m
@@ -163,4 +163,9 @@ -(IBAction)openUntitledWindowChanged:(id)sender
}
}
+- (IBAction)smoothResizeChanged:(id)sender
+{
+ [[MMAppController sharedInstance] refreshAllResizeConstraints];
+}
+
@end
diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h
index b5c10beb29..ce39161a4d 100644
--- a/src/MacVim/MMWindowController.h
+++ b/src/MacVim/MMWindowController.h
@@ -77,6 +77,7 @@
- (void)setBackgroundOption:(int)dark;
- (void)refreshApperanceMode;
+- (void)updateResizeConstraints:(BOOL)resizeWindow;
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore;
- (void)setFont:(NSFont *)font;
diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m
index 1ecb4f8973..0ba41998e8 100644
--- a/src/MacVim/MMWindowController.m
+++ b/src/MacVim/MMWindowController.m
@@ -86,7 +86,6 @@ - (void)resizeWindowToFitContentSize:(NSSize)contentSize
keepOnScreen:(BOOL)onScreen;
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize;
- (NSRect)constrainFrame:(NSRect)frame;
-- (void)updateResizeConstraints;
- (NSTabViewItem *)addNewTabViewItem;
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
- (void)updateTablineSeparator;
@@ -332,7 +331,7 @@ - (BOOL)presentWindow:(id)unused
// code that is executed before this point must not depend on the screen!
[[MMAppController sharedInstance] windowControllerWillOpen:self];
- [self updateResizeConstraints];
+ [self updateResizeConstraints:NO];
[self resizeWindowToFitContentSize:[vimView desiredSize]
keepOnScreen:YES];
@@ -707,7 +706,7 @@ - (void)setFont:(NSFont *)font
}
[[vimView textView] setFont:font];
- [self updateResizeConstraints];
+ [self updateResizeConstraints:NO];
shouldMaximizeWindow = YES;
}
@@ -1519,6 +1518,35 @@ - (NSTouchBar *)makeTouchBar
}
#endif
+/// This will update the window's resizing constraints to either be smooth or rounded to whole cells.
+///
+/// @param resizeWindow If specified, will also resize the window itself down to match the Vim view's desired size.
+- (void)updateResizeConstraints:(BOOL)resizeWindow
+{
+ if (!setupDone) return;
+
+ // If smooth resizing is not set, set the resize increments to exactly
+ // match the font size; this way the window will always hold an integer
+ // number of (rows,columns). Otherwise, just allow arbitrary resizing.
+ const BOOL smoothResize = [[NSUserDefaults standardUserDefaults] boolForKey:MMSmoothResizeKey];
+ const NSSize desiredResizeConstraints = smoothResize ?
+ NSMakeSize(1, 1) :
+ [[vimView textView] cellSize];
+ [decoratedWindow setContentResizeIncrements:desiredResizeConstraints];
+
+ const NSSize minSize = [vimView minSize];
+ [decoratedWindow setContentMinSize:minSize];
+
+ if (resizeWindow) {
+ if (!smoothResize) {
+ // We only want to resize the window down to match the Vim size if not using smooth resizing.
+ // This resizing is going to re-snap the Window size to multiples of grid size. Otherwise
+ // the resize constraint is always going to be at an offset to the desired size.
+ shouldResizeVimView = YES;
+ }
+ }
+}
+
@end // MMWindowController
@@ -1645,19 +1673,6 @@ - (NSRect)constrainFrame:(NSRect)frame
return [decoratedWindow frameRectForContentRect:contentRect];
}
-- (void)updateResizeConstraints
-{
- if (!setupDone) return;
-
- // Set the resize increments to exactly match the font size; this way the
- // window will always hold an integer number of (rows,columns).
- NSSize cellSize = [[vimView textView] cellSize];
- [decoratedWindow setContentResizeIncrements:cellSize];
-
- NSSize minSize = [vimView minSize];
- [decoratedWindow setContentMinSize:minSize];
-}
-
- (NSTabViewItem *)addNewTabViewItem
{
return [vimView addNewTabViewItem];
@@ -1711,7 +1726,7 @@ - (void)hideTablineSeparator:(BOOL)hide
if ([decoratedWindow hideTablineSeparator:hide]) {
// The tabline separator was toggled so the content view must change
// size.
- [self updateResizeConstraints];
+ [self updateResizeConstraints:NO];
}
}
diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h
index 58f97f65d5..635e46bebd 100644
--- a/src/MacVim/Miscellaneous.h
+++ b/src/MacVim/Miscellaneous.h
@@ -58,6 +58,7 @@ extern NSString *MMUseMouseTimeKey;
extern NSString *MMFullScreenFadeTimeKey;
extern NSString *MMNonNativeFullScreenShowMenuKey;
extern NSString *MMNonNativeFullScreenSafeAreaBehaviorKey;
+extern NSString *MMSmoothResizeKey;
// Enum for MMUntitledWindowKey
diff --git a/src/MacVim/Miscellaneous.m b/src/MacVim/Miscellaneous.m
index ee195c78c7..b2f52edede 100644
--- a/src/MacVim/Miscellaneous.m
+++ b/src/MacVim/Miscellaneous.m
@@ -54,6 +54,7 @@
NSString *MMFullScreenFadeTimeKey = @"MMFullScreenFadeTime";
NSString *MMNonNativeFullScreenShowMenuKey = @"MMNonNativeFullScreenShowMenu";
NSString *MMNonNativeFullScreenSafeAreaBehaviorKey = @"MMNonNativeFullScreenSafeAreaBehavior";
+NSString *MMSmoothResizeKey = @"MMSmoothResize";