[gtk: 2/3] Fix DND coordinates on Windows
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 2/3] Fix DND coordinates on Windows
- Date: Sat, 16 Oct 2021 17:04:27 +0000 (UTC)
commit 93878da2ca1ea9adaa7f51faf1d1a984cbe7a518
Author: Luca Bacci <luca bacci982 gmail com>
Date: Mon Sep 6 18:54:30 2021 +0200
Fix DND coordinates on Windows
gdk/win32/gdkdrag-win32.c | 4 ++--
gdk/win32/gdkdrop-win32.c | 52 ++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 51 insertions(+), 5 deletions(-)
---
diff --git a/gdk/win32/gdkdrag-win32.c b/gdk/win32/gdkdrag-win32.c
index 4482e1b3ad..65bd80dadc 100644
--- a/gdk/win32/gdkdrag-win32.c
+++ b/gdk/win32/gdkdrag-win32.c
@@ -2081,8 +2081,8 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id,
WM_MOUSEMOVE,
key_state,
- MAKELPARAM (x * drag_win32->scale,
- y * drag_win32->scale)));
+ MAKELPARAM (x_root * drag_win32->scale - _gdk_offset_x,
+ y_root * drag_win32->scale - _gdk_offset_y)));
return TRUE;
}
diff --git a/gdk/win32/gdkdrop-win32.c b/gdk/win32/gdkdrop-win32.c
index d6e13a3d87..fc8ae391e2 100644
--- a/gdk/win32/gdkdrop-win32.c
+++ b/gdk/win32/gdkdrop-win32.c
@@ -426,6 +426,31 @@ set_source_actions_helper (GdkDrop *drop,
return actions;
}
+/* Utility function to translate win32 screen coordinates to
+ * client coordinates (i.e. relative to the surface origin)
+ *
+ * Note that input is expected to be:
+ * a) NOT scaled by dpi_scale
+ * b) NOT translated by the GDK screen offset (gdk_offset_x / y)
+ *
+ * This utility function preserves subpixel precision
+ */
+static void
+unscaled_screen_to_client (GdkSurface* surface,
+ double screen_x,
+ double screen_y,
+ double *client_x,
+ double *client_y)
+{
+ POINT client_origin;
+
+ client_origin.x = 0;
+ client_origin.y = 0;
+ ClientToScreen (GDK_SURFACE_HWND (surface), &client_origin);
+ *client_x = screen_x - client_origin.x;
+ *client_y = screen_y - client_origin.y;
+}
+
/* The pdwEffect here initially points
* to a DWORD that contains the value of dwOKEffects argument in DoDragDrop,
* i.e. the drag action that the drag source deems acceptable.
@@ -446,6 +471,8 @@ idroptarget_dragenter (LPDROPTARGET This,
GdkDisplay *display;
int pt_x;
int pt_y;
+ double x = 0.0;
+ double y = 0.0;
GdkDrag *drag;
GdkDragAction source_actions;
GdkDragAction dest_actions;
@@ -490,7 +517,12 @@ idroptarget_dragenter (LPDROPTARGET This,
set_data_object (&ctx->data_object, pDataObj);
pt_x = pt.x / drop_win32->scale + _gdk_offset_x;
pt_y = pt.y / drop_win32->scale + _gdk_offset_y;
- gdk_drop_emit_enter_event (drop, TRUE, pt_x, pt_y, GDK_CURRENT_TIME);
+
+ unscaled_screen_to_client (ctx->surface, pt.x, pt.y, &x, &y);
+ x /= drop_win32->scale;
+ y /= drop_win32->scale;
+
+ gdk_drop_emit_enter_event (drop, TRUE, x, y, GDK_CURRENT_TIME);
drop_win32->last_key_state = grfKeyState;
drop_win32->last_x = pt_x;
drop_win32->last_y = pt_y;
@@ -545,7 +577,14 @@ idroptarget_dragover (LPDROPTARGET This,
pt_y != drop_win32->last_y ||
grfKeyState != drop_win32->last_key_state)
{
- gdk_drop_emit_motion_event (ctx->drop, TRUE, pt_x, pt_y, GDK_CURRENT_TIME);
+ double x = 0.0;
+ double y = 0.0;
+
+ unscaled_screen_to_client (ctx->surface, pt.x, pt.y, &x, &y);
+ x /= drop_win32->scale;
+ y /= drop_win32->scale;
+
+ gdk_drop_emit_motion_event (ctx->drop, TRUE, x, y, GDK_CURRENT_TIME);
drop_win32->last_key_state = grfKeyState;
drop_win32->last_x = pt_x;
drop_win32->last_y = pt_y;
@@ -588,6 +627,8 @@ idroptarget_drop (LPDROPTARGET This,
GdkWin32Drop *drop_win32 = GDK_WIN32_DROP (ctx->drop);
int pt_x = pt.x / drop_win32->scale + _gdk_offset_x;
int pt_y = pt.y / drop_win32->scale + _gdk_offset_y;
+ double x = 0.0;
+ double y = 0.0;
GdkDragAction dest_action;
GDK_NOTE (DND, g_print ("idroptarget_drop %p ", This));
@@ -607,7 +648,12 @@ idroptarget_drop (LPDROPTARGET This,
grfKeyState);
drop_win32->drop_finished = FALSE;
- gdk_drop_emit_drop_event (ctx->drop, TRUE, pt_x, pt_y, GDK_CURRENT_TIME);
+
+ unscaled_screen_to_client (ctx->surface, pt.x, pt.y, &x, &y);
+ x /= drop_win32->scale;
+ y /= drop_win32->scale;
+
+ gdk_drop_emit_drop_event (ctx->drop, TRUE, x, y, GDK_CURRENT_TIME);
while (!drop_win32->drop_finished)
g_main_context_iteration (NULL, FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]