@@ -420,6 +420,7 @@ - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
420420 vimView.pendingLiveResize = NO ;
421421 if (blockRenderUntilResize) {
422422 blockRenderUntilResize = NO ;
423+ blockedRenderTextViewFrame = NSZeroRect ;
423424 [vimView.textView setDrawRectOffset: NSZeroSize ];
424425 }
425426 if (vimView.pendingLiveResizeQueued ) {
@@ -506,6 +507,9 @@ - (void)resizeVimViewBlockRender
506507 shouldResizeVimView = YES ;
507508 shouldKeepGUISize = YES ;
508509 blockRenderUntilResize = YES ;
510+ blockedRenderTextViewFrame = [self .window convertRectToScreen:
511+ [vimView convertRect: vimView.textView.frame
512+ toView: nil ]];
509513 if (!vimController.isHandlingInputQueue )
510514 [self processInputQueueDidFinish ];
511515 }
@@ -884,7 +888,6 @@ - (void)processInputQueueDidFinish
884888
885889 const int oldTextViewRows = vimView.textView .pendingMaxRows ;
886890 const int oldTextViewCols = vimView.textView .pendingMaxColumns ;
887- const NSRect oldTextViewFrame = vimView.textView .frame ;
888891 BOOL vimViewSizeChanged = NO ;
889892
890893 // NOTE: If the window has not been presented then we must avoid resizing
@@ -899,8 +902,6 @@ - (void)processInputQueueDidFinish
899902 // Setting 'guioptions+=k' will make shouldKeepGUISize true, which
900903 // means avoid resizing the window. Instead, resize the view instead
901904 // to keep the GUI window's size consistent.
902- // Note: Vim should always have requested shouldKeepGUISize to be true
903- // when in full screen, but we check for it anyway for safety.
904905 bool avoidWindowResize = shouldKeepGUISize || fullScreenEnabled;
905906
906907 if (!avoidWindowResize) {
@@ -939,16 +940,18 @@ - (void)processInputQueueDidFinish
939940
940941 if (blockRenderUntilResize) {
941942 if (vimViewSizeChanged) {
942- const NSRect newTextViewFrame = vimView.textView .frame ;
943+ const NSRect newTextViewFrame = [ self .window convertRectToScreen: [ vimView convertRect: vimView .textView.frame toView: nil ]] ;
943944
944945 // We are currently blocking all rendering to prevent flicker. If
945- // the view frame moved (this happens if the tab or left scroll bar
946- // were shown/ hidden) the user will see a temporary flicker as the
947- // text view was moved before Vim has udpated us with new draw calls
946+ // the view frame moved (this happens if say the tab bar was shown
947+ // or hidden) the user will see a temporary flicker as the text
948+ // view was moved before Vim has updated us with new draw calls
948949 // to match the new size. To alleviate this, we temporarily apply
949950 // a drawing offset in the text view to counter the offset. To the
950951 // user it would appear that the text view hasn't moved at all.
951- [vimView.textView setDrawRectOffset: NSMakeSize (NSMinX (oldTextViewFrame) - NSMinX (newTextViewFrame), NSMaxY (oldTextViewFrame) - NSMaxY (newTextViewFrame))];
952+ [vimView.textView setDrawRectOffset:
953+ NSMakeSize (NSMinX (blockedRenderTextViewFrame) - NSMinX (newTextViewFrame),
954+ NSMaxY (blockedRenderTextViewFrame) - NSMaxY (newTextViewFrame))];
952955 } else {
953956 // We were blocking all rendering until Vim has been resized. However
954957 // in situations where we turned out to not need to resize Vim to
@@ -959,6 +962,7 @@ - (void)processInputQueueDidFinish
959962 // we need to resize) but turned out we set it to the same font so
960963 // the grid size is the same and no need to resize.
961964 blockRenderUntilResize = NO ;
965+ blockedRenderTextViewFrame = NSZeroRect ;
962966 [vimView.textView setDrawRectOffset: NSZeroSize ];
963967
964968 [vimController sendMessage: RedrawMsgID data: nil ];
@@ -1139,6 +1143,22 @@ - (void)enterFullScreen:(int)fuoptions backgroundColor:(NSColor *)back
11391143 // custom full-screen can appear on any screen, as opposed to native
11401144 // full-screen which always uses the main screen.)
11411145 if (windowPresented) {
1146+ const BOOL shouldPreventFlicker = (fuoptions & FUOPT_MAXVERT) && (fuoptions & FUOPT_MAXHORZ);
1147+ if (shouldPreventFlicker) {
1148+ // Prevent visual flickering by temporarily blocking new render
1149+ // until Vim has updated/resized itself.
1150+ // We don't do the same when exiting full screen because when
1151+ // going in this direction the flickering is less noticeable
1152+ // and it looks odd when the user sees a clamped view.
1153+ // Also, don't do this if maxvert/maxhorz not set because it
1154+ // looks quite off in that situation as Vim is supposed to move
1155+ // visually.
1156+ blockRenderUntilResize = YES ;
1157+ blockedRenderTextViewFrame = [decoratedWindow convertRectToScreen:
1158+ [vimView convertRect: vimView.textView.frame
1159+ toView: nil ]];
1160+ }
1161+
11421162 [fullScreenWindow enterFullScreen ];
11431163 fullScreenEnabled = YES ;
11441164
@@ -1149,8 +1169,6 @@ - (void)enterFullScreen:(int)fuoptions backgroundColor:(NSColor *)back
11491169 if (blurRadius != 0 )
11501170 [MMWindow setBlurRadius: blurRadius onWindow: fullScreenWindow];
11511171
1152- // The resize handle disappears so the vim view needs to update the
1153- // scrollbars.
11541172 shouldResizeVimView = YES ;
11551173 }
11561174 }
@@ -1664,8 +1682,6 @@ - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard
16641682}
16651683
16661684
1667- #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
1668-
16691685// -- Full-screen delegate ---------------------------------------------------
16701686
16711687- (NSApplicationPresentationOptions )window : (NSWindow *)window
@@ -1795,8 +1811,6 @@ - (void)windowDidFailToExitFullScreen:(NSWindow *)window
17951811 [vimController addVimInput: @" <C-\\ ><C-N>:set fu<CR>" ];
17961812}
17971813
1798- #endif // (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
1799-
18001814- (void )runAfterWindowPresentedUsingBlock : (void (^)(void ))block
18011815{
18021816 if (windowPresented) { // no need to defer block, just run it now
0 commit comments