server: Improve handling of cursor position clipping for empty rectangle.

Based on a patch by Kevin Buhr.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38791
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sebastian Lackner 2019-02-18 08:26:11 -06:00 committed by Alexandre Julliard
parent d2d52717af
commit 5ff6a11697
2 changed files with 73 additions and 4 deletions

View File

@ -1269,6 +1269,19 @@ static LRESULT CALLBACK hook_proc2( int code, WPARAM wparam, LPARAM lparam )
return CallNextHookEx( 0, code, wparam, lparam );
}
static LRESULT CALLBACK hook_proc3( int code, WPARAM wparam, LPARAM lparam )
{
POINT pt;
if (code == HC_ACTION)
{
/* MSLLHOOKSTRUCT does not seem to be reliable and contains different data on each run. */
GetCursorPos(&pt);
ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
}
return CallNextHookEx( 0, code, wparam, lparam );
}
static void test_mouse_ll_hook(void)
{
HWND hwnd;
@ -1342,6 +1355,62 @@ static void test_mouse_ll_hook(void)
ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
UnhookWindowsHookEx(hook2);
hook1 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc3, GetModuleHandleA(0), 0);
SetRect(&rc, 150, 150, 150, 150);
ClipCursor(&rc);
clipped = TRUE;
SetCursorPos(140, 140);
GetCursorPos(&pt_old);
ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
SetCursorPos(160, 160);
GetCursorPos(&pt_old);
todo_wine
ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
mouse_event(MOUSEEVENTF_MOVE, -STEP, -STEP, 0, 0);
GetCursorPos(&pt_old);
ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
mouse_event(MOUSEEVENTF_MOVE, +STEP, +STEP, 0, 0);
GetCursorPos(&pt_old);
todo_wine
ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
GetCursorPos(&pt_old);
ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
GetCursorPos(&pt_old);
todo_wine
ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
clipped = FALSE;
ClipCursor(NULL);
SetCursorPos(140, 140);
SetRect(&rc, 150, 150, 150, 150);
ClipCursor(&rc);
GetCursorPos(&pt_old);
ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
ClipCursor(NULL);
SetCursorPos(160, 160);
SetRect(&rc, 150, 150, 150, 150);
ClipCursor(&rc);
GetCursorPos(&pt_old);
todo_wine
ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
ClipCursor(NULL);
SetCursorPos(150, 150);
SetRect(&rc, 150, 150, 150, 150);
ClipCursor(&rc);
GetCursorPos(&pt_old);
todo_wine
ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
ClipCursor(NULL);
UnhookWindowsHookEx(hook1);
done:
DestroyWindow(hwnd);
SetCursorPos(pt_org.x, pt_org.y);

View File

@ -411,8 +411,8 @@ static void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect
post_desktop_message( desktop, desktop->cursor.clip_msg, rect != NULL, 0 );
/* warp the mouse to be inside the clip rect */
x = min( max( desktop->cursor.x, desktop->cursor.clip.left ), desktop->cursor.clip.right-1 );
y = min( max( desktop->cursor.y, desktop->cursor.clip.top ), desktop->cursor.clip.bottom-1 );
x = max( min( desktop->cursor.x, desktop->cursor.clip.right - 1 ), desktop->cursor.clip.left );
y = max( min( desktop->cursor.y, desktop->cursor.clip.bottom - 1 ), desktop->cursor.clip.top );
if (x != desktop->cursor.x || y != desktop->cursor.y) set_cursor_pos( desktop, x, y );
}
@ -1500,8 +1500,8 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
{
if (msg->msg == WM_MOUSEMOVE)
{
int x = min( max( msg->x, desktop->cursor.clip.left ), desktop->cursor.clip.right-1 );
int y = min( max( msg->y, desktop->cursor.clip.top ), desktop->cursor.clip.bottom-1 );
int x = max( min( msg->x, desktop->cursor.clip.right - 1 ), desktop->cursor.clip.left );
int y = max( min( msg->y, desktop->cursor.clip.bottom - 1 ), desktop->cursor.clip.top );
if (desktop->cursor.x != x || desktop->cursor.y != y) always_queue = 1;
desktop->cursor.x = x;
desktop->cursor.y = y;