Commit 1d3b9448 authored by Lauri Kenttä's avatar Lauri Kenttä Committed by Alexandre Julliard

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: 's avatarLauri Kenttä <lauri.kentta@gmail.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 5d6f96fd
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment