@@ -2985,6 +2985,42 @@ gui_mch_flash(int msec)
29852985 InvertRect (s_hdc , & rc );
29862986}
29872987
2988+ /*
2989+ * Check if the specified point is on-screen. (multi-monitor aware)
2990+ */
2991+ static BOOL
2992+ is_point_onscreen (int x , int y )
2993+ {
2994+ POINT pt = {x , y };
2995+
2996+ return MonitorFromPoint (pt , MONITOR_DEFAULTTONULL ) != NULL ;
2997+ }
2998+
2999+ /*
3000+ * Check if the whole area of the specified window is on-screen.
3001+ *
3002+ * Note about DirectX: Windows 10 1809 or above no longer maintains image of
3003+ * the window portion that is off-screen. Scrolling by DWriteContext_Scroll()
3004+ * only works when the whole window is on-screen.
3005+ */
3006+ static BOOL
3007+ is_window_onscreen (HWND hwnd )
3008+ {
3009+ RECT rc ;
3010+
3011+ GetWindowRect (hwnd , & rc );
3012+
3013+ if (!is_point_onscreen (rc .left , rc .top ))
3014+ return FALSE;
3015+ if (!is_point_onscreen (rc .left , rc .bottom ))
3016+ return FALSE;
3017+ if (!is_point_onscreen (rc .right , rc .top ))
3018+ return FALSE;
3019+ if (!is_point_onscreen (rc .right , rc .bottom ))
3020+ return FALSE;
3021+ return TRUE;
3022+ }
3023+
29883024/*
29893025 * Return flags used for scrolling.
29903026 * The SW_INVALIDATE is required when part of the window is covered or
@@ -2996,15 +3032,12 @@ get_scroll_flags(void)
29963032 HWND hwnd ;
29973033 RECT rcVim , rcOther , rcDest ;
29983034
2999- GetWindowRect (s_hwnd , & rcVim );
3000-
3001- // Check if the window is partly above or below the screen. We don't care
3002- // about partly left or right of the screen, it is not relevant when
3003- // scrolling up or down.
3004- if (rcVim .top < 0 || rcVim .bottom > GetSystemMetrics (SM_CYFULLSCREEN ))
3035+ // Check if the window is (partly) off-screen.
3036+ if (!is_window_onscreen (s_hwnd ))
30053037 return SW_INVALIDATE ;
30063038
30073039 // Check if there is an window (partly) on top of us.
3040+ GetWindowRect (s_hwnd , & rcVim );
30083041 for (hwnd = s_hwnd ; (hwnd = GetWindow (hwnd , GW_HWNDPREV )) != (HWND )0 ; )
30093042 if (IsWindowVisible (hwnd ))
30103043 {
@@ -3046,14 +3079,17 @@ gui_mch_delete_lines(
30463079 rc .bottom = FILL_Y (gui .scroll_region_bot + 1 );
30473080
30483081#if defined(FEAT_DIRECTX )
3049- if (IS_ENABLE_DIRECTX ())
3082+ if (IS_ENABLE_DIRECTX () && is_window_onscreen ( s_hwnd ) )
30503083 {
30513084 DWriteContext_Scroll (s_dwc , 0 , - num_lines * gui .char_height , & rc );
3052- DWriteContext_Flush (s_dwc );
30533085 }
30543086 else
30553087#endif
30563088 {
3089+ #if defined(FEAT_DIRECTX )
3090+ if (IS_ENABLE_DIRECTX ())
3091+ DWriteContext_Flush (s_dwc );
3092+ #endif
30573093 intel_gpu_workaround ();
30583094 ScrollWindowEx (s_textArea , 0 , - num_lines * gui .char_height ,
30593095 & rc , & rc , NULL , NULL , get_scroll_flags ());
@@ -3088,14 +3124,17 @@ gui_mch_insert_lines(
30883124 rc .bottom = FILL_Y (gui .scroll_region_bot + 1 );
30893125
30903126#if defined(FEAT_DIRECTX )
3091- if (IS_ENABLE_DIRECTX ())
3127+ if (IS_ENABLE_DIRECTX () && is_window_onscreen ( s_hwnd ) )
30923128 {
30933129 DWriteContext_Scroll (s_dwc , 0 , num_lines * gui .char_height , & rc );
3094- DWriteContext_Flush (s_dwc );
30953130 }
30963131 else
30973132#endif
30983133 {
3134+ #if defined(FEAT_DIRECTX )
3135+ if (IS_ENABLE_DIRECTX ())
3136+ DWriteContext_Flush (s_dwc );
3137+ #endif
30993138 intel_gpu_workaround ();
31003139 // The SW_INVALIDATE is required when part of the window is covered or
31013140 // off-screen. How do we avoid it when it's not needed?
0 commit comments