GdkWin32: Make OLE2 DND work in monitors with different OS scales
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3734
This commit is contained in:
@ -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)))
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user