=?UTF-8?Q?Lauri=20Kentt=C3=A4=20?=: user32: Fix caret disappearing after scrolling.

Alexandre Julliard julliard at winehq.org
Fri Dec 2 17:00:10 CST 2016


Module: wine
Branch: master
Commit: 1d3b9448f6dccf642b015359af53e03f295a76cb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1d3b9448f6dccf642b015359af53e03f295a76cb

Author: Lauri Kenttä <lauri.kentta at gmail.com>
Date:   Sat Nov 26 18:03:43 2016 +0200

user32: Fix caret disappearing after scrolling.

The caret needs to be moved along with scrolling even if it's
outside the visible area. Otherwise, when the caret is scrolled
out from the view, the position won't get updated anymore and
the caret will never scroll back again.

The idea is based on the patch by André Hentschel.

Signed-off-by: Lauri Kenttä <lauri.kentta at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/painting.c | 76 ++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 49 deletions(-)

diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c
index 30dabfe..622dcad 100644
--- a/dlls/user32/painting.c
+++ b/dlls/user32/painting.c
@@ -837,65 +837,41 @@ static HWND fix_caret(HWND hWnd, const RECT *scroll_rect, INT dx, INT dy,
 {
     GUITHREADINFO info;
     RECT rect, mapped_rcCaret;
-    BOOL hide_caret = FALSE;
 
     info.cbSize = sizeof(info);
     if (!GetGUIThreadInfo( GetCurrentThreadId(), &info )) return 0;
     if (!info.hwndCaret) return 0;
     
+    mapped_rcCaret = info.rcCaret;
     if (info.hwndCaret == hWnd)
     {
-        /* Move the caret if it's (partially) in the source rectangle */
-        if (IntersectRect(&rect, scroll_rect, &info.rcCaret))
-        {
-            *move_caret = TRUE;
-            hide_caret = TRUE;
-            new_caret_pos->x = info.rcCaret.left + dx;
-            new_caret_pos->y = info.rcCaret.top + dy;
-        }
-        else
-        {
-            *move_caret = FALSE;
-            
-            /* Hide the caret if it's in the destination rectangle */
-            rect = *scroll_rect;
-            OffsetRect(&rect, dx, dy);
-            hide_caret = IntersectRect(&rect, &rect, &info.rcCaret);
-        }
+        /* The caret needs to be moved along with scrolling even if it's
+         * outside the visible area. Otherwise, when the caret is scrolled
+         * out from the view, the position won't get updated anymore and
+         * the caret will never scroll back again. */
+        *move_caret = TRUE;
+        new_caret_pos->x = info.rcCaret.left + dx;
+        new_caret_pos->y = info.rcCaret.top + dy;
     }
     else
     {
-        if ((flags & SW_SCROLLCHILDREN) && IsChild(hWnd, info.hwndCaret))
-        {
-            *move_caret = FALSE;
-            
-            /* Hide the caret if it's in the source or in the destination
-               rectangle */
-            mapped_rcCaret = info.rcCaret;
-            MapWindowPoints(info.hwndCaret, hWnd, (LPPOINT)&mapped_rcCaret, 2);
-            
-            if (IntersectRect(&rect, scroll_rect, &mapped_rcCaret))
-            {
-                hide_caret = TRUE;
-            }
-            else
-            {
-                rect = *scroll_rect;
-                OffsetRect(&rect, dx, dy);
-                hide_caret = IntersectRect(&rect, &rect, &mapped_rcCaret);
-            }
-        }
-        else
+        *move_caret = FALSE;
+        if (!(flags & SW_SCROLLCHILDREN) || !IsChild(hWnd, info.hwndCaret))
             return 0;
+        MapWindowPoints(info.hwndCaret, hWnd, (LPPOINT)&mapped_rcCaret, 2);
     }
 
-    if (hide_caret)
-    {    
-        HideCaret(info.hwndCaret);
-        return info.hwndCaret;
+    /* If the caret is not in the src/dest rects, all is fine done. */
+    if (!IntersectRect(&rect, scroll_rect, &mapped_rcCaret))
+    {
+        rect = *scroll_rect;
+        OffsetRect(&rect, dx, dy);
+        if (!IntersectRect(&rect, &rect, &mapped_rcCaret))
+            return 0;
     }
-    else
-        return 0;
+
+    /* Indicate that the caret needs to be updated during the scrolling. */
+    return info.hwndCaret;
 }
 
 
@@ -1456,6 +1432,8 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
         DWORD style = GetWindowLongW( hwnd, GWL_STYLE );
 
         hwndCaret = fix_caret(hwnd, &rc, dx, dy, flags, &moveCaret, &newCaretPos);
+        if (hwndCaret)
+            HideCaret(hwndCaret);
 
         if (is_ex) dcxflags |= DCX_CACHE;
         if( style & WS_CLIPSIBLINGS) dcxflags |= DCX_CLIPSIBLINGS;
@@ -1555,10 +1533,10 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
         DeleteObject( hrgnWinupd);
     }
 
-    if( hwndCaret ) {
-        if ( moveCaret ) SetCaretPos( newCaretPos.x, newCaretPos.y );
-        ShowCaret(hwndCaret);
-    }
+    if( moveCaret )
+        SetCaretPos( newCaretPos.x, newCaretPos.y );
+    if( hwndCaret )
+        ShowCaret( hwndCaret );
 
     if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
 




More information about the wine-cvs mailing list