From f9ada51f8c2c89d450868db790bbe93bc2cd5a25 Mon Sep 17 00:00:00 2001 From: fvogel Date: Tue, 20 Aug 2019 14:42:37 +0000 Subject: Fix [69b48f427e]: Test 'textTag-18.1' fails since Win10 Creator Falls Update --- win/tkWinInt.h | 6 ++++++ win/tkWinPointer.c | 35 +++++++++++++++++++++++++++++------ win/tkWinWindow.c | 4 ++-- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/win/tkWinInt.h b/win/tkWinInt.h index 0e2c844..9cd49cd 100644 --- a/win/tkWinInt.h +++ b/win/tkWinInt.h @@ -201,6 +201,12 @@ MODULE_SCOPE void TkpWinToplevelDetachWindow(TkWindow *winPtr); MODULE_SCOPE int TkpWmGetState(TkWindow *winPtr); /* + * The following is implemented in tkWinPointer.c and also used in tkWinWindow.c + */ + +MODULE_SCOPE void TkSetCursorPos(int x, int y); + +/* * Common routines used in Windows implementation */ MODULE_SCOPE Tcl_Obj * TkWin32ErrorObj(HRESULT hrError); diff --git a/win/tkWinPointer.c b/win/tkWinPointer.c index 251b5b9..55fa35e 100644 --- a/win/tkWinPointer.c +++ b/win/tkWinPointer.c @@ -336,10 +336,10 @@ XQueryPointer( /* *---------------------------------------------------------------------- * - * XWarpPointer -- + * XWarpPointer, TkpWarpPointer -- * - * Move pointer to new location. This is not a complete implementation of - * this function. + * Move pointer to new location. Note that implementation of XWarpPointer + * is incomplete. * * Results: * None. @@ -350,6 +350,29 @@ XQueryPointer( *---------------------------------------------------------------------- */ +/* + * TkSetCursorPos is a helper function replacing SetCursorPos since this + * latter Windows function appears the have been broken by Microsoft + * since Win10 Falls Creator Update - See ticket [69b48f427e] along with + * several other Internet reports about this breakage. + */ + +void TkSetCursorPos( + int x, + int y) +{ + INPUT input; + + input.type = INPUT_MOUSE; + input.mi.dx = x * (65536.0 / GetSystemMetrics(SM_CXSCREEN)); + input.mi.dy = y * (65536.0 / GetSystemMetrics(SM_CYSCREEN)); + input.mi.mouseData = 0; + input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + input.mi.time = 0; + input.mi.dwExtraInfo = 0; + SendInput(1, &input, sizeof(input)); +} + int XWarpPointer( Display *display, @@ -365,7 +388,7 @@ XWarpPointer( RECT r; GetWindowRect(Tk_GetHWND(dest_w), &r); - SetCursorPos(r.left+dest_x, r.top+dest_y); + TkSetCursorPos(r.left+dest_x, r.top+dest_y); return Success; } @@ -377,9 +400,9 @@ TkpWarpPointer( RECT r; GetWindowRect(Tk_GetHWND(Tk_WindowId(dispPtr->warpWindow)), &r); - SetCursorPos(r.left + dispPtr->warpX, r.top + dispPtr->warpY); + TkSetCursorPos(r.left + dispPtr->warpX, r.top + dispPtr->warpY); } else { - SetCursorPos(dispPtr->warpX, dispPtr->warpY); + TkSetCursorPos(dispPtr->warpX, dispPtr->warpY); } } diff --git a/win/tkWinWindow.c b/win/tkWinWindow.c index 445ff9c..57c948e 100644 --- a/win/tkWinWindow.c +++ b/win/tkWinWindow.c @@ -882,7 +882,7 @@ TkpShowBusyWindow( */ GetCursorPos(&point); - SetCursorPos(point.x, point.y); + TkSetCursorPos(point.x, point.y); } /* @@ -924,7 +924,7 @@ TkpHideBusyWindow( */ GetCursorPos(&point); - SetCursorPos(point.x, point.y); + TkSetCursorPos(point.x, point.y); } /* -- cgit v0.12 From 56f9690a29e9307a87d15b93cee4f09ce3111407 Mon Sep 17 00:00:00 2001 From: fvogel Date: Thu, 22 Aug 2019 15:36:08 +0000 Subject: Since we're here dealing with pointer warping, add tests checking that the mouse really moves when event generating with -wrap true --- tests/bind.test | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/bind.test b/tests/bind.test index 9cbc15b..25e7652 100644 --- a/tests/bind.test +++ b/tests/bind.test @@ -6126,7 +6126,7 @@ test bind-31.7 {virtual event user_data field - unshared, asynch} -setup { destroy .t.f } -result {{} {} {TestUserData >b<}} -test bind-32 {-warp, window was destroyed before the idle callback DoWarp} -setup { +test bind-32.1 {-warp, window was destroyed before the idle callback DoWarp} -setup { frame .t.f pack .t.f focus -force .t.f @@ -6138,6 +6138,46 @@ test bind-32 {-warp, window was destroyed before the idle callback DoWarp} -setu update ; # shall simply not crash } -cleanup { } -result {} +test bind-32.2 {-warp works relatively to a window} -setup { + toplevel .top +} -body { + # In order to avoid platform-dependent coordinate results due to + # decorations and borders, this test warps the pointer twice + # relatively to a window that moved in the meantime, and checks + # how much the pointer moved + wm geometry .top +200+200 + update + event generate .top -x 20 -y 20 -warp 1 + update idletasks ; # DoWarp is an idle callback + set pointerPos1 [winfo pointerxy .t] + wm geometry .top +600+600 + update + event generate .top -x 20 -y 20 -warp 1 + update idletasks ; # DoWarp is an idle callback + set pointerPos2 [winfo pointerxy .t] + # from the first warped position to the second one, the mouse + # pointer should have moved the same amount as the window moved + set res 1 + foreach pos1 $pointerPos1 pos2 $pointerPos2 { + if {$pos1 != [expr {$pos2 - 400}]} { + set res 0 + } + } + set res +} -cleanup { + destroy .top +} -result {1} +test bind-32.3 {-warp works relatively to the screen} -setup { +} -body { + # Contrary to bind-32.2, we're directly checking screen coordinates + event generate {} -x 20 -y 20 -warp 1 + update idletasks ; # DoWarp is an idle callback + set res [winfo pointerxy .] + event generate {} -x 200 -y 200 -warp 1 + update idletasks ; # DoWarp is an idle callback + lappend res {*}[winfo pointerxy .] +} -cleanup { +} -result {20 20 200 200} # cleanup -- cgit v0.12 From cdc9ded607b1d18a5901761fc49385932471605d Mon Sep 17 00:00:00 2001 From: fvogel Date: Thu, 22 Aug 2019 15:38:34 +0000 Subject: Fix maths in TkSetCursorPos(). I have checked that this implementation provides the same results as SetCursorPos (that we don't use anymore). That checking has included the multiple monitors and negative coordinates cases. --- win/tkWinPointer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/tkWinPointer.c b/win/tkWinPointer.c index 55fa35e..8ab512c 100644 --- a/win/tkWinPointer.c +++ b/win/tkWinPointer.c @@ -352,7 +352,7 @@ XQueryPointer( /* * TkSetCursorPos is a helper function replacing SetCursorPos since this - * latter Windows function appears the have been broken by Microsoft + * latter Windows function appears to have been broken by Microsoft * since Win10 Falls Creator Update - See ticket [69b48f427e] along with * several other Internet reports about this breakage. */ @@ -364,8 +364,8 @@ void TkSetCursorPos( INPUT input; input.type = INPUT_MOUSE; - input.mi.dx = x * (65536.0 / GetSystemMetrics(SM_CXSCREEN)); - input.mi.dy = y * (65536.0 / GetSystemMetrics(SM_CYSCREEN)); + input.mi.dx = x * (65535.0 / (GetSystemMetrics(SM_CXSCREEN) - 1)); + input.mi.dy = y * (65535.0 / (GetSystemMetrics(SM_CYSCREEN) - 1)); input.mi.mouseData = 0; input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; input.mi.time = 0; -- cgit v0.12