[gtk/gtk-3-24: 1/2] GdkWin32: Make OLE2 DND work in monitors with different OS scales
- From: Luca Bacci <lbacci src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 1/2] GdkWin32: Make OLE2 DND work in monitors with different OS scales
- Date: Thu, 18 Nov 2021 21:57:37 +0000 (UTC)
commit 4d40300d8a996ca1ef57d327a6e24342cf72c516
Author: Luca Bacci <luca bacci982 gmail com>
Date: Sat Nov 13 19:38:11 2021 +0100
GdkWin32: Make OLE2 DND work in monitors with different OS scales
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3734
gdk/win32/gdkdnd-win32.c | 19 +++++++++++++++++++
gdk/win32/gdkwin32dnd-private.h | 9 +++++++++
2 files changed, 28 insertions(+)
---
diff --git a/gdk/win32/gdkdnd-win32.c b/gdk/win32/gdkdnd-win32.c
index e4a0257bf5..b968294ba9 100644
--- a/gdk/win32/gdkdnd-win32.c
+++ b/gdk/win32/gdkdnd-win32.c
@@ -774,6 +774,7 @@ send_change_events (GdkDragContext *context,
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
POINT pt;
POINT pt_client;
+ HMONITOR monitor = NULL;
gboolean changed = FALSE;
HWND hwnd = GDK_WINDOW_HWND (context->source_window);
LPARAM lparam;
@@ -784,6 +785,24 @@ send_change_events (GdkDragContext *context,
if (!API_CALL (GetCursorPos, (&pt)))
return FALSE;
+ /* Move the DND IPC window to the monitor the cursor is currently on.
+ This esures that OLE2 DND works correctly even if the DPI awareness
+ isn't per-monitor.
+ */
+ monitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
+ if (monitor != context_win32->last_monitor)
+ {
+ MONITORINFO mi;
+
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfoW (monitor, &mi))
+ {
+ MoveWindow (hwnd, mi.rcWork.left, mi.rcWork.top, 1, 1, FALSE);
+ }
+
+ context_win32->last_monitor = monitor;
+ }
+
pt_client = pt;
if (!API_CALL (ScreenToClient, (hwnd, &pt_client)))
diff --git a/gdk/win32/gdkwin32dnd-private.h b/gdk/win32/gdkwin32dnd-private.h
index b0476b468e..a7d11a31de 100644
--- a/gdk/win32/gdkwin32dnd-private.h
+++ b/gdk/win32/gdkwin32dnd-private.h
@@ -55,6 +55,15 @@ struct _GdkWin32DragContext
gint start_x; /* Coordinates of the drag start, in GDK space */
gint start_y;
DWORD last_key_state; /* Key state from last event */
+ HMONITOR last_monitor; /* While dragging we keep track of the monitor the cursor
+ is currently on. As the cursor moves between monitors,
+ we move the invisible dnd ipc window to the top-left
+ corner of the current monitor, because OLE2 does not
+ work correctly if the source window and the dest window
+ are on monitors with different scales (say one is 125%
+ and the other 100%) and the drag-initiating application
+ (effectively driving the DND) is not per-monitor DPI aware
+ */
/* Just like context->targets, but an array, and with format IDs
* stored inside.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]