Skip to content

Commit 91aa372

Browse files
authored
Merge pull request #745 from ychin/rendering_fixes
Fix native fullscreen rendering and resizing bugs
2 parents 8400c53 + fa0fad6 commit 91aa372

3 files changed

Lines changed: 39 additions & 33 deletions

File tree

src/MacVim/MMVimView.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
NSMutableArray *scrollbars;
2828
}
2929

30+
@property BOOL pendingLiveResize;
31+
3032
- (MMVimView *)initWithFrame:(NSRect)frame vimController:(MMVimController *)c;
3133

3234
- (MMTextView *)textView;

src/MacVim/MMVimView.m

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,19 @@ - (void)frameSizeMayHaveChanged:(BOOL)keepGUISize
920920
"%dx%d (%s)", cols, rows, constrained[1], constrained[0],
921921
MessageStrings[msgid]);
922922

923-
[vimController sendMessageNow:msgid data:data timeout:1];
923+
if (msgid != LiveResizeMsgID || !self.pendingLiveResize) {
924+
// Live resize messages can be sent really rapidly, especailly if
925+
// it's from double clicking the window border (to indicate filling
926+
// all the way to that side to the window manager). We want to rate
927+
// limit sending live resize one at a time, or the IPC will get
928+
// swamped which causes slowdowns and some messages will also be dropped.
929+
// As a result we basically discard all live resize messages if one
930+
// is already going on. liveResizeDidEnd: will perform a final clean
931+
// up resizing.
932+
self.pendingLiveResize = (msgid == LiveResizeMsgID);
933+
934+
[vimController sendMessageNow:msgid data:data timeout:1];
935+
}
924936

925937
// We only want to set the window title if this resize came from
926938
// a live-resize, not (for example) setting 'columns' or 'lines'.

src/MacVim/MMWindowController.m

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
398398
// user drags to resize the window.
399399

400400
[vimView setDesiredRows:rows columns:cols];
401+
vimView.pendingLiveResize = NO;
401402

402403
if (setupDone && !live && !keepGUISize) {
403404
shouldResizeVimView = YES;
@@ -599,39 +600,27 @@ - (void)processInputQueueDidFinish
599600
if (!didMaximize) {
600601
NSSize originalSize = [vimView frame].size;
601602
int rows = 0, cols = 0;
602-
NSSize contentSize = [vimView constrainRows:&rows columns:&cols
603-
toSize:
604-
fullScreenWindow ? [fullScreenWindow frame].size :
605-
fullScreenEnabled ? desiredWindowSize :
606-
[self constrainContentSizeToScreenSize:[vimView desiredSize]]];
607603

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

613609
if (!avoidWindowResize) {
610+
NSSize contentSize = [vimView constrainRows:&rows columns:&cols
611+
toSize:
612+
fullScreenWindow ? [fullScreenWindow frame].size :
613+
fullScreenEnabled ? desiredWindowSize :
614+
[self constrainContentSizeToScreenSize:[vimView desiredSize]]];
615+
614616
[vimView setFrameSize:contentSize];
617+
618+
[self resizeWindowToFitContentSize:contentSize
619+
keepOnScreen:keepOnScreen];
615620
}
616621
else {
617-
[vimView setFrameSizeKeepGUISize:originalSize];
618-
}
619-
620-
if (fullScreenWindow) {
621-
// NOTE! Don't mark the full-screen content view as needing an
622-
// update unless absolutely necessary since when it is updated
623-
// the entire screen is cleared. This may cause some parts of
624-
// the Vim view to be cleared but not redrawn since Vim does
625-
// not realize that we've erased part of the view.
626-
if (!NSEqualSizes(originalSize, contentSize)) {
627-
[[fullScreenWindow contentView] setNeedsDisplay:YES];
628-
[fullScreenWindow centerView];
629-
}
630-
} else {
631-
if (!avoidWindowResize) {
632-
[self resizeWindowToFitContentSize:contentSize
633-
keepOnScreen:keepOnScreen];
634-
}
622+
NSSize frameSize = fullScreenWindow ? [fullScreenWindow frame].size : (fullScreenEnabled ? desiredWindowSize : originalSize);
623+
[vimView setFrameSizeKeepGUISize:frameSize];
635624
}
636625
}
637626

@@ -724,6 +713,13 @@ - (void)liveResizeDidEnd
724713
[lastSetTitle release];
725714
lastSetTitle = nil;
726715
}
716+
717+
// If we are in the middle of rapid resize (e.g. double-clicking on the border/corner
718+
// of window), we would fire off a lot of LiveResizeMsgID messages where some will be
719+
// intentionally omitted to avoid swamping IPC. If that happens this will perform a
720+
// final clean up that makes sure the Vim view is sized correctly within the window.
721+
// See frameSizeMayHaveChanged: for where the omission/rate limiting happens.
722+
[self resizeView];
727723
}
728724

729725
- (void)setBlurRadius:(int)radius
@@ -1059,14 +1055,10 @@ - (void)windowDidResize:(id)sender
10591055
// may resize automatically) we simply set the view to fill the entire
10601056
// window. The vim view takes care of notifying Vim if the number of
10611057
// (rows,columns) changed.
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-
}
1058+
// Calling setFrameSizeKeepGUISize: instead of setFrameSize: prevents a
1059+
// degenerate case where frameSizeMayHaveChanged: ends up resizing the window
1060+
// *again* causing windowDidResize: to be called.
1061+
[vimView setFrameSizeKeepGUISize:[self contentSize]];
10701062
}
10711063

10721064
- (void)windowDidChangeBackingProperties:(NSNotification *)notification

0 commit comments

Comments
 (0)