Skip to content

Support guioptions 'k' flag in MacVim (2nd attempt) #731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/MacVim/MMBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ extern NSTimeInterval MMBalloonEvalInternalDelay;
- (BOOL)tabBarVisible;
- (void)showTabBar:(BOOL)enable;
- (void)setRows:(int)rows columns:(int)cols;
- (void)resizeView;
- (void)setWindowTitle:(char *)title;
- (void)setDocumentFilename:(char *)filename;
- (char *)browseForFileWithAttributes:(NSDictionary *)attr;
Expand Down
8 changes: 8 additions & 0 deletions src/MacVim/MMBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,11 @@ - (void)setRows:(int)rows columns:(int)cols
[self queueMessage:SetTextDimensionsMsgID data:data];
}

- (void)resizeView
{
[self queueMessage:ResizeViewMsgID data:nil];
}

- (void)setWindowTitle:(char *)title
{
NSMutableData *data = [NSMutableData data];
Expand Down Expand Up @@ -1997,6 +2002,7 @@ - (void)handleInputEvent:(int)msgid data:(NSData *)data

tabpage_move(idx);
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid
|| SetTextDimensionsNoResizeWindowMsgID == msgid
|| SetTextRowsMsgID == msgid || SetTextColumnsMsgID == msgid) {
if (!data) return;
const void *bytes = [data bytes];
Expand Down Expand Up @@ -2028,6 +2034,8 @@ - (void)handleInputEvent:(int)msgid data:(NSData *)data
[self queueMessage:msgid data:d];

gui_resize_shell(cols, rows);
} else if (ResizeViewMsgID == msgid) {
[self queueMessage:msgid data:data];
} else if (ExecuteMenuMsgID == msgid) {
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
if (attrs) {
Expand Down
6 changes: 6 additions & 0 deletions src/MacVim/MMVimController.m
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
[windowController showTabBar:NO];
[self sendMessage:BackingPropertiesChangedMsgID data:nil];
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid ||
SetTextDimensionsNoResizeWindowMsgID == msgid ||
SetTextDimensionsReplyMsgID == msgid) {
const void *bytes = [data bytes];
int rows = *((int*)bytes); bytes += sizeof(int);
Expand All @@ -638,11 +639,16 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
// acknowledges it with a reply message. When this happens the window
// should not move (the frontend would already have moved the window).
BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid;

BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid;

[windowController setTextDimensionsWithRows:rows
columns:cols
isLive:(LiveResizeMsgID==msgid)
keepGUISize:keepGUISize
keepOnScreen:onScreen];
} else if (ResizeViewMsgID == msgid) {
[windowController resizeView];
} else if (SetWindowTitleMsgID == msgid) {
const void *bytes = [data bytes];
int len = *((int*)bytes); bytes += sizeof(int);
Expand Down
1 change: 1 addition & 0 deletions src/MacVim/MMVimView.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
- (void)viewWillStartLiveResize;
- (void)viewDidEndLiveResize;
- (void)setFrameSize:(NSSize)size;
- (void)setFrameSizeKeepGUISize:(NSSize)size;
- (void)setFrame:(NSRect)frame;

@end
21 changes: 16 additions & 5 deletions src/MacVim/MMVimView.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ - (MMScroller *)scrollbarForIdentifier:(int32_t)ident index:(unsigned *)idx;
- (NSSize)vimViewSizeForTextViewSize:(NSSize)textViewSize;
- (NSRect)textViewRectForVimViewSize:(NSSize)contentSize;
- (NSTabView *)tabView;
- (void)frameSizeMayHaveChanged;
- (void)frameSizeMayHaveChanged:(BOOL)keepGUISize;
@end


Expand Down Expand Up @@ -610,14 +610,25 @@ - (void)setFrameSize:(NSSize)size
// row will result in the vim view holding more rows than the can fit
// inside the window.)
[super setFrameSize:size];
[self frameSizeMayHaveChanged];
[self frameSizeMayHaveChanged:NO];
}

- (void)setFrameSizeKeepGUISize:(NSSize)size
{
// NOTE: Instead of only acting when a frame was resized, we do some
// updating each time a frame may be resized. (At the moment, if we only
// respond to actual frame changes then typing ":set lines=1000" twice in a
// row will result in the vim view holding more rows than the can fit
// inside the window.)
[super setFrameSize:size];
[self frameSizeMayHaveChanged:YES];
}

- (void)setFrame:(NSRect)frame
{
// See comment in setFrameSize: above.
[super setFrame:frame];
[self frameSizeMayHaveChanged];
[self frameSizeMayHaveChanged:NO];
}

@end // MMVimView
Expand Down Expand Up @@ -867,7 +878,7 @@ - (NSTabView *)tabView
return tabView;
}

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

ASLogDebug(@"Notify Vim that text dimensions changed from %dx%d to "
"%dx%d (%s)", cols, rows, constrained[1], constrained[0],
Expand Down
3 changes: 3 additions & 0 deletions src/MacVim/MMWindowController.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
BOOL setupDone;
BOOL windowPresented;
BOOL shouldResizeVimView;
BOOL shouldKeepGUISize;
BOOL shouldRestoreUserTopLeft;
BOOL shouldMaximizeWindow;
int updateToolbarFlag;
Expand Down Expand Up @@ -59,7 +60,9 @@
- (void)updateTabsWithData:(NSData *)data;
- (void)selectTabWithIndex:(int)idx;
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
keepGUISize:(BOOL)keepGUISize
keepOnScreen:(BOOL)onScreen;
- (void)resizeView;
- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state;
- (void)setTitle:(NSString *)title;
- (void)setDocumentFilename:(NSString *)filename;
Expand Down
95 changes: 73 additions & 22 deletions src/MacVim/MMWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ - (id)initWithVimController:(MMVimController *)controller

[win setDelegate:self];
[win setInitialFirstResponder:[vimView textView]];

if ([win styleMask] & NSWindowStyleMaskTexturedBackground) {
// On Leopard, we want to have a textured window to have nice
// looking tabs. But the textured window look implies rounded
Expand Down Expand Up @@ -363,11 +363,9 @@ - (void)moveWindowAcrossScreens:(NSPoint)topLeft
// HACK! This method moves a window to a new origin and to a different
// screen. This is primarily useful to avoid a scenario where such a move
// will trigger a resize, even though the frame didn't actually change size.
// This method should not be called unless the new origin is definitely on
// a different screen, otherwise the next legitimate resize message will
// be skipped.
resizingDueToMove = YES;
[[self window] setFrameTopLeftPoint:topLeft];
resizingDueToMove = NO;
}

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

- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
keepGUISize:(BOOL)keepGUISize
keepOnScreen:(BOOL)onScreen
{
ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d "
"keepOnScreen:%d", rows, cols, live, onScreen);
"keepGUISize:%d "
"keepOnScreen:%d", rows, cols, live, keepGUISize, onScreen);

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

[vimView setDesiredRows:rows columns:cols];

if (setupDone && !live) {
if (setupDone && !live && !keepGUISize) {
shouldResizeVimView = YES;
keepOnScreen = onScreen;
}
Expand Down Expand Up @@ -428,11 +428,21 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
}
}

- (void)resizeView
{
if (setupDone)
{
shouldResizeVimView = YES;
shouldKeepGUISize = YES;
}
}

- (void)zoomWithRows:(int)rows columns:(int)cols state:(int)state
{
[self setTextDimensionsWithRows:rows
columns:cols
isLive:NO
keepGUISize:NO
keepOnScreen:YES];

// NOTE: If state==0 then the window should be put in the non-zoomed
Expand Down Expand Up @@ -503,19 +513,13 @@ - (void)createScrollbarWithIdentifier:(int32_t)ident type:(int)type
- (BOOL)destroyScrollbarWithIdentifier:(int32_t)ident
{
BOOL scrollbarHidden = [vimView destroyScrollbarWithIdentifier:ident];
shouldResizeVimView = shouldResizeVimView || scrollbarHidden;
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarHidden;

return scrollbarHidden;
}

- (BOOL)showScrollbarWithIdentifier:(int32_t)ident state:(BOOL)visible
{
BOOL scrollbarToggled = [vimView showScrollbarWithIdentifier:ident
state:visible];
shouldResizeVimView = shouldResizeVimView || scrollbarToggled;
shouldMaximizeWindow = shouldMaximizeWindow || scrollbarToggled;

return scrollbarToggled;
}

Expand Down Expand Up @@ -600,7 +604,18 @@ - (void)processInputQueueDidFinish
fullScreenWindow ? [fullScreenWindow frame].size :
fullScreenEnabled ? desiredWindowSize :
[self constrainContentSizeToScreenSize:[vimView desiredSize]]];
[vimView setFrameSize:contentSize];

// Setting 'guioptions+=k' will make shouldKeepGUISize true, which
// means avoid resizing the window. Instead, resize the view instead
// to keep the GUI window's size consistent.
bool avoidWindowResize = shouldKeepGUISize && !fullScreenEnabled;

if (!avoidWindowResize) {
[vimView setFrameSize:contentSize];
}
else {
[vimView setFrameSizeKeepGUISize:originalSize];
}

if (fullScreenWindow) {
// NOTE! Don't mark the full-screen content view as needing an
Expand All @@ -613,12 +628,15 @@ - (void)processInputQueueDidFinish
[fullScreenWindow centerView];
}
} else {
[self resizeWindowToFitContentSize:contentSize
keepOnScreen:keepOnScreen];
if (!avoidWindowResize) {
[self resizeWindowToFitContentSize:contentSize
keepOnScreen:keepOnScreen];
}
}
}

keepOnScreen = NO;
shouldKeepGUISize = NO;
}
}

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

- (void)adjustColumnspace:(int)columnspace
{
if (vimView && [vimView textView]) {
[[vimView textView] setColumnspace:(float)columnspace];
shouldMaximizeWindow = shouldResizeVimView = YES;
}
}

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

- (void)windowDidChangeBackingProperties:(NSNotification *)notification
Expand Down Expand Up @@ -1187,7 +1214,7 @@ - (void)window:(NSWindow *)window
[[window animator] setAlphaValue:0];
} completionHandler:^{
[self maximizeWindow:fullScreenOptions];

// Fade in
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:0.5*duration];
Expand All @@ -1206,7 +1233,7 @@ - (void)windowWillEnterFullScreen:(NSNotification *)notification

// The separator should never be visible in fullscreen or split-screen.
[decoratedWindow hideTablineSeparator:YES];

// ASSUMPTION: fullScreenEnabled always reflects the state of Vim's 'fu'.
if (!fullScreenEnabled) {
ASLogDebug(@"Full-screen out of sync, tell Vim to set 'fu'");
Expand Down Expand Up @@ -1308,7 +1335,7 @@ - (void)windowDidExitFullScreen:(NSNotification *)notification
// full-screen by moving the window out from Split View.
[vimController sendMessage:BackingPropertiesChangedMsgID data:nil];
}

[self updateTablineSeparator];
}

Expand Down Expand Up @@ -1536,7 +1563,6 @@ - (void)hideTablineSeparator:(BOOL)hide
// The tabline separator was toggled so the content view must change
// size.
[self updateResizeConstraints];
shouldResizeVimView = YES;
}
}

Expand Down Expand Up @@ -1592,7 +1618,32 @@ - (void)updateToolbar

// Positive flag shows toolbar, negative hides it.
BOOL on = updateToolbarFlag > 0 ? YES : NO;

NSRect origWindowFrame = [decoratedWindow frame];
BOOL origHasToolbar = decoratedWindow.toolbar != nil;

[decoratedWindow setToolbar:(on ? toolbar : nil)];

if (shouldKeepGUISize && !fullScreenEnabled && origHasToolbar != on) {
// "shouldKeepGUISize" means guioptions has 'k' in it, indicating that user doesn't
// want the window to resize itself. In non-fullscreen when we call setToolbar:
// Cocoa automatically resizes the window so we need to un-resize it back to
// original.

NSRect newWindowFrame = [decoratedWindow frame];
if (newWindowFrame.size.height == origWindowFrame.size.height) {
// This is an odd case here, where the window has not changed size at all.
// The addition/removal of toolbar should have changed its size. This means that
// there isn't enough space to grow the window on the screen. Usually we rely
// on windowDidResize: to call setFrameSizeKeepGUISize for us but now we have
// to do it manually in this special case.
[vimView setFrameSizeKeepGUISize:[self contentSize]];
}
else {
[decoratedWindow setFrame:origWindowFrame display:YES];
}
}

[self updateTablineSeparator];

updateToolbarFlag = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/MacVim/MacVim.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,10 @@ enum {
SetTextRowsMsgID,
SetTextColumnsMsgID,
SetTextDimensionsMsgID,
SetTextDimensionsNoResizeWindowMsgID,
LiveResizeMsgID,
SetTextDimensionsReplyMsgID,
ResizeViewMsgID,
SetWindowTitleMsgID,
ScrollWheelMsgID,
MouseDownMsgID,
Expand Down
Loading