Patch 8.2.1922
Problem:    Win32: scrolling doesn't work properly when part of window is
            off-screen.
Solution:   Fall back to GDI scrolling if part of the window is off-screen.
            Handle multi-monitor setup better. (Ken Takata, closes #7219)
Files:      src/gui_w32.c


*** ../vim-8.2.1921/src/gui_w32.c       2020-09-27 13:16:41.701465056 +0200
--- src/gui_w32.c       2020-10-29 20:06:01.178842454 +0100
***************
*** 2986,2991 ****
--- 2986,3027 ----
  }
  
  /*
+  * Check if the specified point is on-screen. (multi-monitor aware)
+  */
+     static BOOL
+ is_point_onscreen(int x, int y)
+ {
+     POINT   pt = {x, y};
+ 
+     return MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) != NULL;
+ }
+ 
+ /*
+  * Check if the whole area of the specified window is on-screen.
+  *
+  * Note about DirectX: Windows 10 1809 or above no longer maintains image of
+  * the window portion that is off-screen.  Scrolling by DWriteContext_Scroll()
+  * only works when the whole window is on-screen.
+  */
+     static BOOL
+ is_window_onscreen(HWND hwnd)
+ {
+     RECT    rc;
+ 
+     GetWindowRect(hwnd, &rc);
+ 
+     if (!is_point_onscreen(rc.left, rc.top))
+       return FALSE;
+     if (!is_point_onscreen(rc.left, rc.bottom))
+       return FALSE;
+     if (!is_point_onscreen(rc.right, rc.top))
+       return FALSE;
+     if (!is_point_onscreen(rc.right, rc.bottom))
+       return FALSE;
+     return TRUE;
+ }
+ 
+ /*
   * Return flags used for scrolling.
   * The SW_INVALIDATE is required when part of the window is covered or
   * off-screen. Refer to MS KB Q75236.
***************
*** 2996,3010 ****
      HWND      hwnd;
      RECT      rcVim, rcOther, rcDest;
  
!     GetWindowRect(s_hwnd, &rcVim);
! 
!     // Check if the window is partly above or below the screen.  We don't care
!     // about partly left or right of the screen, it is not relevant when
!     // scrolling up or down.
!     if (rcVim.top < 0 || rcVim.bottom > GetSystemMetrics(SM_CYFULLSCREEN))
        return SW_INVALIDATE;
  
      // Check if there is an window (partly) on top of us.
      for (hwnd = s_hwnd; (hwnd = GetWindow(hwnd, GW_HWNDPREV)) != (HWND)0; )
        if (IsWindowVisible(hwnd))
        {
--- 3032,3043 ----
      HWND      hwnd;
      RECT      rcVim, rcOther, rcDest;
  
!     // Check if the window is (partly) off-screen.
!     if (!is_window_onscreen(s_hwnd))
        return SW_INVALIDATE;
  
      // Check if there is an window (partly) on top of us.
+     GetWindowRect(s_hwnd, &rcVim);
      for (hwnd = s_hwnd; (hwnd = GetWindow(hwnd, GW_HWNDPREV)) != (HWND)0; )
        if (IsWindowVisible(hwnd))
        {
***************
*** 3046,3059 ****
      rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
  
  #if defined(FEAT_DIRECTX)
!     if (IS_ENABLE_DIRECTX())
      {
        DWriteContext_Scroll(s_dwc, 0, -num_lines * gui.char_height, &rc);
-       DWriteContext_Flush(s_dwc);
      }
      else
  #endif
      {
        intel_gpu_workaround();
        ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
                                    &rc, &rc, NULL, NULL, get_scroll_flags());
--- 3079,3095 ----
      rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
  
  #if defined(FEAT_DIRECTX)
!     if (IS_ENABLE_DIRECTX() && is_window_onscreen(s_hwnd))
      {
        DWriteContext_Scroll(s_dwc, 0, -num_lines * gui.char_height, &rc);
      }
      else
  #endif
      {
+ #if defined(FEAT_DIRECTX)
+       if (IS_ENABLE_DIRECTX())
+           DWriteContext_Flush(s_dwc);
+ #endif
        intel_gpu_workaround();
        ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
                                    &rc, &rc, NULL, NULL, get_scroll_flags());
***************
*** 3088,3101 ****
      rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
  
  #if defined(FEAT_DIRECTX)
!     if (IS_ENABLE_DIRECTX())
      {
        DWriteContext_Scroll(s_dwc, 0, num_lines * gui.char_height, &rc);
-       DWriteContext_Flush(s_dwc);
      }
      else
  #endif
      {
        intel_gpu_workaround();
        // The SW_INVALIDATE is required when part of the window is covered or
        // off-screen.  How do we avoid it when it's not needed?
--- 3124,3140 ----
      rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
  
  #if defined(FEAT_DIRECTX)
!     if (IS_ENABLE_DIRECTX() && is_window_onscreen(s_hwnd))
      {
        DWriteContext_Scroll(s_dwc, 0, num_lines * gui.char_height, &rc);
      }
      else
  #endif
      {
+ #if defined(FEAT_DIRECTX)
+       if (IS_ENABLE_DIRECTX())
+           DWriteContext_Flush(s_dwc);
+ #endif
        intel_gpu_workaround();
        // The SW_INVALIDATE is required when part of the window is covered or
        // off-screen.  How do we avoid it when it's not needed?
*** ../vim-8.2.1921/src/version.c       2020-10-29 18:57:57.791880416 +0100
--- src/version.c       2020-10-29 20:07:59.262546054 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     1922,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
151. You find yourself engaged to someone you've never actually met,
     except through e-mail.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202010291908.09TJ8sVq2515807%40masaka.moolenaar.net.

Raspunde prin e-mail lui