From 412bc1713a697337cc2e4a837f94b3a015b7b1c7 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Wed, 21 Jun 2023 15:19:05 +0200 Subject: [PATCH 1/5] GdkWin32: Keep track of the last cursor position in move / resize contexts ...and avoid doing any work if the position hasn't changed. --- gdk/win32/gdksurface-win32.c | 9 +++++++++ gdk/win32/gdksurface-win32.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c index 9a37969944..ecae5e7d6d 100644 --- a/gdk/win32/gdksurface-win32.c +++ b/gdk/win32/gdksurface-win32.c @@ -3535,6 +3535,8 @@ setup_drag_move_resize_context (GdkSurface *surface, context->button = button; context->start_root_x = root_x; context->start_root_y = root_y; + context->current_root_x = root_x; + context->current_root_y = root_y; context->timestamp = timestamp; context->start_rect = rect; @@ -3650,6 +3652,13 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window, if (!_gdk_win32_get_window_rect (window, &rect)) return; + if (context->current_root_x == x && + context->current_root_y == y) + return; + + context->current_root_x = x; + context->current_root_y = y; + new_rect = context->start_rect; diffx = (x - context->start_root_x) * impl->surface_scale; diffy = (y - context->start_root_y) * impl->surface_scale; diff --git a/gdk/win32/gdksurface-win32.h b/gdk/win32/gdksurface-win32.h index afe8d42010..e4b3e837ba 100644 --- a/gdk/win32/gdksurface-win32.h +++ b/gdk/win32/gdksurface-win32.h @@ -137,6 +137,12 @@ struct _GdkW32DragMoveResizeContext int start_root_x; int start_root_y; + /* Last processed cursor position. Values are divided by the window + * scale. + */ + int current_root_x; + int current_root_y; + /* Initial window rectangle (position and size). * The window is resized/moved relative to this (see start_root_*). */ From 5e9daa9728efed8cf9c434667e13e995a629a3f7 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Wed, 21 Jun 2023 15:57:40 +0200 Subject: [PATCH 2/5] GdkWin32: Unscaled coordinates in current_root_x, current_root_y Also modify gdk_win32_surface_do_move_resize_drag() to take unscaled root coordinates. Fixes #5877 --- gdk/win32/gdkevents-win32.c | 8 ++++---- gdk/win32/gdksurface-win32.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 4f8feed052..326e511070 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -2350,12 +2350,12 @@ gdk_event_translate (MSG *msg, * sends WM_MOUSEMOVE messages after a new window is shown under * the mouse, even if the mouse hasn't moved. This disturbs gtk. */ - if (msg->pt.x / impl->surface_scale == current_root_x && - msg->pt.y / impl->surface_scale == current_root_y) + if (msg->pt.x == current_root_x && + msg->pt.y == current_root_y) break; - current_root_x = msg->pt.x / impl->surface_scale; - current_root_y = msg->pt.y / impl->surface_scale; + current_root_x = msg->pt.x; + current_root_y = msg->pt.y; if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE) gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y); diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c index ecae5e7d6d..72b65407a2 100644 --- a/gdk/win32/gdksurface-win32.c +++ b/gdk/win32/gdksurface-win32.c @@ -3652,6 +3652,9 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window, if (!_gdk_win32_get_window_rect (window, &rect)) return; + x /= impl->surface_scale; + y /= impl->surface_scale; + if (context->current_root_x == x && context->current_root_y == y) return; From 871685e271760bf3468341fe6bde9fce8090483d Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Wed, 21 Jun 2023 16:07:55 +0200 Subject: [PATCH 3/5] GdkWin32: Use double coordinates for mouse events Mouse coordinates reported by the system are still integers, but go sub-pixel when dividing by the window scale factor. --- gdk/win32/gdkevents-win32.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 326e511070..9562b664ae 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -139,7 +139,6 @@ static GSourceFuncs event_funcs = { static GdkSurface *mouse_window = NULL; static GdkSurface *mouse_window_ignored_leave = NULL; -static int current_x, current_y; static int current_root_x, current_root_y; static UINT got_gdk_events_message; @@ -1522,14 +1521,15 @@ generate_button_event (GdkEventType type, GdkEvent *event; GdkDeviceManagerWin32 *device_manager; GdkWin32Surface *impl = GDK_WIN32_SURFACE (window); + double x, y; if (_gdk_input_ignore_core > 0) return; device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager); - current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale; - current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale; + x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale; + y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale; _gdk_device_virtual_set_active (_gdk_device_manager->core_pointer, _gdk_device_manager->system_pointer); @@ -1541,10 +1541,10 @@ generate_button_event (GdkEventType type, _gdk_win32_get_next_tick (msg->time), build_pointer_event_state (msg), button, - current_x, - current_y, + x, + y, NULL); - + _gdk_win32_append_event (event); } @@ -2358,11 +2358,11 @@ gdk_event_translate (MSG *msg, current_root_y = msg->pt.y; if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE) - gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y); + gdk_win32_surface_do_move_resize_drag (window, msg->pt.x, msg->pt.y); else if (_gdk_input_ignore_core == 0) { - current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale; - current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale; + double x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale; + double y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale; _gdk_device_virtual_set_active (_gdk_device_manager->core_pointer, _gdk_device_manager->system_pointer); @@ -2372,8 +2372,8 @@ gdk_event_translate (MSG *msg, NULL, _gdk_win32_get_next_tick (msg->time), build_pointer_event_state (msg), - current_x, - current_y, + x, + y, NULL); _gdk_win32_append_event (event); From 3912d6aba9245f632069fabf1e23cc470d857aa4 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Wed, 21 Jun 2023 16:14:56 +0200 Subject: [PATCH 4/5] GdkWin32: Fix keyboard state for WinPointer input The dwKeyStates field of the POINTER_INFO structure is always set to 0, no matter what. Use GetKeyState instead. Forward-port of !4327 to GTK4 --- gdk/win32/gdkinput-winpointer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gdk/win32/gdkinput-winpointer.c b/gdk/win32/gdkinput-winpointer.c index 0782743453..1a9e6bbff5 100644 --- a/gdk/win32/gdkinput-winpointer.c +++ b/gdk/win32/gdkinput-winpointer.c @@ -271,9 +271,10 @@ winpointer_make_event (GdkDeviceWinpointer *device, y /= impl->surface_scale; state = 0; - if (info->dwKeyStates & POINTER_MOD_CTRL) + /* Note that info->dwKeyStates is not reliable, use GetKeyState() */ + if (GetKeyState (VK_CONTROL) < 0) state |= GDK_CONTROL_MASK; - if (info->dwKeyStates & POINTER_MOD_SHIFT) + if (GetKeyState (VK_SHIFT) < 0) state |= GDK_SHIFT_MASK; if (GetKeyState (VK_MENU) < 0) state |= GDK_ALT_MASK; From 43af0ee51472869da62498d3a5b611542392d5fd Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Wed, 21 Jun 2023 16:18:40 +0200 Subject: [PATCH 5/5] Define this_module with (void) argument Fixes a compiler warning about K&R (old-style) function definition --- gtk/gtkwin32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkwin32.c b/gtk/gtkwin32.c index 2144279e03..71cb2c0597 100644 --- a/gtk/gtkwin32.c +++ b/gtk/gtkwin32.c @@ -36,7 +36,7 @@ extern IMAGE_DOS_HEADER __ImageBase; static inline HMODULE -this_module () +this_module (void) { return (HMODULE) &__ImageBase; }