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);
|
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
|
||||||
POINT pt;
|
POINT pt;
|
||||||
POINT pt_client;
|
POINT pt_client;
|
||||||
|
HMONITOR monitor = NULL;
|
||||||
gboolean changed = FALSE;
|
gboolean changed = FALSE;
|
||||||
HWND hwnd = GDK_WINDOW_HWND (context->source_window);
|
HWND hwnd = GDK_WINDOW_HWND (context->source_window);
|
||||||
LPARAM lparam;
|
LPARAM lparam;
|
||||||
@ -784,6 +785,24 @@ send_change_events (GdkDragContext *context,
|
|||||||
if (!API_CALL (GetCursorPos, (&pt)))
|
if (!API_CALL (GetCursorPos, (&pt)))
|
||||||
return FALSE;
|
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;
|
pt_client = pt;
|
||||||
|
|
||||||
if (!API_CALL (ScreenToClient, (hwnd, &pt_client)))
|
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_x; /* Coordinates of the drag start, in GDK space */
|
||||||
gint start_y;
|
gint start_y;
|
||||||
DWORD last_key_state; /* Key state from last event */
|
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
|
/* Just like context->targets, but an array, and with format IDs
|
||||||
* stored inside.
|
* stored inside.
|
||||||
|
|||||||
Reference in New Issue
Block a user