From 876a2e62254be0ef7ed6bf4293f4b43578840dc4 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Wed, 8 Sep 2021 17:51:07 +0200 Subject: [PATCH] GdkWin32: Ensure a consistent order of operations when handling DPI scale and GDK screen offset --- gdk/win32/gdkdevice-win32.c | 28 ++++----- gdk/win32/gdkdevice-winpointer.c | 28 ++++----- gdk/win32/gdkdevice-wintab.c | 28 ++++----- gdk/win32/gdkdnd-win32.c | 24 ++++---- gdk/win32/gdkevents-win32.c | 4 +- gdk/win32/gdkmonitor-win32.c | 11 ++-- gdk/win32/gdkwindow-win32.c | 98 ++++++++++++++++---------------- 7 files changed, 109 insertions(+), 112 deletions(-) diff --git a/gdk/win32/gdkdevice-win32.c b/gdk/win32/gdkdevice-win32.c index 8e107db981..9c90eb880f 100644 --- a/gdk/win32/gdkdevice-win32.c +++ b/gdk/win32/gdkdevice-win32.c @@ -120,32 +120,28 @@ gdk_device_win32_query_state (GdkDevice *device, _gdk_win32_get_cursor_pos (&point); if (root_x) - *root_x = point.x / impl->window_scale; + *root_x = (point.x + _gdk_offset_x) / impl->window_scale; if (root_y) - *root_y = point.y / impl->window_scale; - - ScreenToClient (hwnd, &point); - - if (win_x) - *win_x = point.x / impl->window_scale; - - if (win_y) - *win_y = point.y / impl->window_scale; + *root_y = (point.y + _gdk_offset_y) / impl->window_scale; if (window == gdk_screen_get_root_window (screen)) { if (win_x) - *win_x += _gdk_offset_x; + *win_x = (point.x + _gdk_offset_x) / impl->window_scale; if (win_y) - *win_y += _gdk_offset_y; + *win_y = (point.y + _gdk_offset_y) / impl->window_scale; + } + else + { + ScreenToClient (hwnd, &point); - if (root_x) - *root_x += _gdk_offset_x; + if (win_x) + *win_x = point.x / impl->window_scale; - if (root_y) - *root_y += _gdk_offset_y; + if (win_y) + *win_y = point.y / impl->window_scale; } if (child_window) diff --git a/gdk/win32/gdkdevice-winpointer.c b/gdk/win32/gdkdevice-winpointer.c index 42cb5b8f03..1b4f5553e6 100644 --- a/gdk/win32/gdkdevice-winpointer.c +++ b/gdk/win32/gdkdevice-winpointer.c @@ -114,32 +114,28 @@ gdk_device_winpointer_query_state (GdkDevice *device, _gdk_win32_get_cursor_pos (&point); if (root_x) - *root_x = point.x / impl->window_scale; + *root_x = (point.x + _gdk_offset_x) / impl->window_scale; if (root_y) - *root_y = point.y / impl->window_scale; - - ScreenToClient (hwnd, &point); - - if (win_x) - *win_x = point.x / impl->window_scale; - - if (win_y) - *win_y = point.y / impl->window_scale; + *root_y = (point.y + _gdk_offset_y) / impl->window_scale; if (window == gdk_screen_get_root_window (screen)) { if (win_x) - *win_x += _gdk_offset_x; + *win_x = (point.x + _gdk_offset_x) / impl->window_scale; if (win_y) - *win_y += _gdk_offset_y; + *win_y = (point.y + _gdk_offset_y) / impl->window_scale; + } + else + { + ScreenToClient (hwnd, &point); - if (root_x) - *root_x += _gdk_offset_x; + if (win_x) + *win_x = point.x / impl->window_scale; - if (root_y) - *root_y += _gdk_offset_y; + if (win_y) + *win_y = point.y / impl->window_scale; } if (child_window) diff --git a/gdk/win32/gdkdevice-wintab.c b/gdk/win32/gdkdevice-wintab.c index 1f9de43fa7..fb69420ce2 100644 --- a/gdk/win32/gdkdevice-wintab.c +++ b/gdk/win32/gdkdevice-wintab.c @@ -131,26 +131,28 @@ gdk_device_wintab_query_state (GdkDevice *device, _gdk_win32_get_cursor_pos (&point); if (root_x) - *root_x = point.x / impl->window_scale; + *root_x = (point.x + _gdk_offset_x) / impl->window_scale; if (root_y) - *root_y = point.y / impl->window_scale; + *root_y = (point.y + _gdk_offset_y) / impl->window_scale; - ScreenToClient (hwnd, &point); - - if (win_x) - *win_x = point.x / impl->window_scale; - - if (win_y) - *win_y = point.y / impl->window_scale; - - if (window == gdk_get_default_root_window ()) + if (window == gdk_screen_get_root_window (screen)) { if (win_x) - *win_x += _gdk_offset_x; + *win_x = (point.x + _gdk_offset_x) / impl->window_scale; if (win_y) - *win_y += _gdk_offset_y; + *win_y = (point.y + _gdk_offset_y) / impl->window_scale; + } + else + { + ScreenToClient (hwnd, &point); + + if (win_x) + *win_x = point.x / impl->window_scale; + + if (win_y) + *win_y = point.y / impl->window_scale; } if (child_window) diff --git a/gdk/win32/gdkdnd-win32.c b/gdk/win32/gdkdnd-win32.c index 762e5c3023..e9a70cf89e 100644 --- a/gdk/win32/gdkdnd-win32.c +++ b/gdk/win32/gdkdnd-win32.c @@ -588,8 +588,8 @@ idroptarget_dragenter (LPDROPTARGET This, ctx->context->suggested_action = get_suggested_action (grfKeyState); set_data_object (&sel_win32->dnd_data_object_target, pDataObj); - pt_x = pt.x / context_win32->scale + _gdk_offset_x; - pt_y = pt.y / context_win32->scale + _gdk_offset_y; + pt_x = (pt.x + _gdk_offset_x) / context_win32->scale; + pt_y = (pt.y + _gdk_offset_y) / context_win32->scale; dnd_event_put (GDK_DRAG_ENTER, ctx->context, pt_x, pt_y, TRUE); dnd_event_put (GDK_DRAG_MOTION, ctx->context, pt_x, pt_y, TRUE); context_win32->last_key_state = grfKeyState; @@ -611,8 +611,8 @@ idroptarget_dragover (LPDROPTARGET This, { target_drag_context *ctx = (target_drag_context *) This; GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (ctx->context); - gint pt_x = pt.x / context_win32->scale + _gdk_offset_x; - gint pt_y = pt.y / context_win32->scale + _gdk_offset_y; + gint pt_x = (pt.x + _gdk_offset_x) / context_win32->scale; + gint pt_y = (pt.y + _gdk_offset_y) / context_win32->scale; ctx->context->suggested_action = get_suggested_action (grfKeyState); @@ -664,8 +664,8 @@ idroptarget_drop (LPDROPTARGET This, { target_drag_context *ctx = (target_drag_context *) This; GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (ctx->context); - gint pt_x = pt.x / context_win32->scale + _gdk_offset_x; - gint pt_y = pt.y / context_win32->scale + _gdk_offset_y; + gint pt_x = (pt.x + _gdk_offset_x) / context_win32->scale; + gint pt_y = (pt.y + _gdk_offset_y) / context_win32->scale; GdkWin32Selection *sel_win32 = _gdk_win32_selection_get (); GDK_NOTE (DND, g_print ("idroptarget_drop %p ", This)); @@ -789,8 +789,8 @@ send_change_events (GdkDragContext *context, if (!API_CALL (ScreenToClient, (hwnd, &pt_client))) return FALSE; - pt_x = pt.x / context_win32->scale + _gdk_offset_x; - pt_y = pt.y / context_win32->scale + _gdk_offset_y; + pt_x = (pt.x + _gdk_offset_x) / context_win32->scale; + pt_y = (pt.y + _gdk_offset_y) / context_win32->scale; if (pt_x != context_win32->last_x || pt_y != context_win32->last_y || key_state != context_win32->last_key_state) @@ -909,8 +909,8 @@ idropsource_givefeedback (LPDROPSOURCE This, else if (ctx->context->dest_window == NULL) ctx->context->dest_window = g_object_ref (gdk_get_default_root_window ()); - context_win32->last_x = pt.x / context_win32->scale + _gdk_offset_x; - context_win32->last_y = pt.y / context_win32->scale + _gdk_offset_y; + context_win32->last_x = (pt.x + _gdk_offset_x) / context_win32->scale; + context_win32->last_y = (pt.y + _gdk_offset_y) / context_win32->scale; e = gdk_event_new (GDK_DRAG_STATUS); @@ -1708,8 +1708,8 @@ gdk_dropfiles_filter (GdkXEvent *xev, DragQueryPoint (hdrop, &pt); ClientToScreen (msg->hwnd, &pt); - event->dnd.x_root = pt.x / context_win32->scale + _gdk_offset_x; - event->dnd.y_root = pt.y / context_win32->scale + _gdk_offset_y; + event->dnd.x_root = (pt.x + _gdk_offset_x) / context_win32->scale; + event->dnd.y_root = (pt.y + _gdk_offset_y) / context_win32->scale; event->dnd.time = _gdk_win32_get_next_tick (msg->time); nfiles = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index a7cc3e2394..1b722584c4 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -1628,8 +1628,8 @@ _gdk_win32_get_window_rect (GdkWindow *window, if (gdk_window_get_parent (window) == gdk_get_default_root_window ()) { ClientToScreen (hwnd, &point); - point.x += _gdk_offset_x * window_impl->window_scale; - point.y += _gdk_offset_y * window_impl->window_scale; + point.x += _gdk_offset_x; + point.y += _gdk_offset_y; } rect->left = point.x; diff --git a/gdk/win32/gdkmonitor-win32.c b/gdk/win32/gdkmonitor-win32.c index 771763c4ee..e5bd520e81 100644 --- a/gdk/win32/gdkmonitor-win32.c +++ b/gdk/win32/gdkmonitor-win32.c @@ -905,16 +905,19 @@ _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display) { GdkWin32Monitor *m; GdkRectangle rect; + int scale = 0; m = g_ptr_array_index (data.monitors, i); gdk_monitor_get_geometry (GDK_MONITOR (m), &rect); - rect.x += _gdk_offset_x; - rect.y += _gdk_offset_y; + scale = gdk_monitor_get_scale_factor (GDK_MONITOR (m)); + + rect.x += _gdk_offset_x / scale; + rect.y += _gdk_offset_y / scale; gdk_monitor_set_position (GDK_MONITOR (m), rect.x, rect.y); - m->work_rect.x += _gdk_offset_x; - m->work_rect.y += _gdk_offset_y; + m->work_rect.x += _gdk_offset_x / scale; + m->work_rect.y += _gdk_offset_y / scale; GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n", i, rect.width, rect.height, rect.x, rect.y)); diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 2d0faaca3e..cd465103a3 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -303,10 +303,10 @@ gdk_win32_window_get_queued_window_rect (GdkWindow *window, _gdk_win32_adjust_client_rect (window, &window_rect); /* Convert GDK screen coordinates to W32 desktop coordinates */ - window_rect.left -= _gdk_offset_x * impl->window_scale; - window_rect.right -= _gdk_offset_x * impl->window_scale; - window_rect.top -= _gdk_offset_y * impl->window_scale; - window_rect.bottom -= _gdk_offset_y * impl->window_scale; + window_rect.left -= _gdk_offset_x; + window_rect.right -= _gdk_offset_x; + window_rect.top -= _gdk_offset_y; + window_rect.bottom -= _gdk_offset_y; *return_window_rect = window_rect; } @@ -841,8 +841,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle); - real_x = (window->x - offset_x) * impl->window_scale; - real_y = (window->y - offset_y) * impl->window_scale; + real_x = window->x * impl->window_scale - offset_x; + real_y = window->y * impl->window_scale - offset_y; if (window->window_type == GDK_WINDOW_TOPLEVEL) { @@ -866,8 +866,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, window_width = impl->unscaled_width; window_height = impl->unscaled_height; /* use given position for initial placement, native coordinates */ - x = (window->x + window->parent->abs_x - offset_x) * impl->window_scale; - y = (window->y + window->parent->abs_y - offset_y) * impl->window_scale; + x = (window->x + window->parent->abs_x) * impl->window_scale; + y = (window->y + window->parent->abs_y) * impl->window_scale; } if (attributes_mask & GDK_WA_TITLE) @@ -952,8 +952,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n", title, window_width, window_height, - window->x - offset_x, - window->y - offset_y, + window->x, + window->y, hparent, GDK_WINDOW_HWND (window))); @@ -1338,8 +1338,8 @@ show_window_internal (GdkWindow *window, { GdkWindow *owner = window_impl->transient_owner; /* Center on transient parent */ - center_on_rect.left = (owner->x - _gdk_offset_x) * window_impl->window_scale; - center_on_rect.top = (owner->y - _gdk_offset_y) * window_impl->window_scale; + center_on_rect.left = owner->x * window_impl->window_scale - _gdk_offset_x; + center_on_rect.top = owner->y * window_impl->window_scale - _gdk_offset_y; center_on_rect.right = center_on_rect.left + owner->width * window_impl->window_scale; center_on_rect.bottom = center_on_rect.top + owner->height * window_impl->window_scale; @@ -1552,13 +1552,13 @@ gdk_win32_window_move (GdkWindow *window, GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0," "NOACTIVATE|NOSIZE|NOZORDER)\n", GDK_WINDOW_HWND (window), - (x - _gdk_offset_x) * impl->window_scale, - (y - _gdk_offset_y) * impl->window_scale)); + x * impl->window_scale - _gdk_offset_x, + y * impl->window_scale - _gdk_offset_y)); API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), SWP_NOZORDER_SPECIFIED, - (x - _gdk_offset_x) * impl->window_scale, - (y - _gdk_offset_y) * impl->window_scale, + x * impl->window_scale - _gdk_offset_x, + y * impl->window_scale - _gdk_offset_y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER)); } @@ -1651,15 +1651,15 @@ gdk_win32_window_move_resize_internal (GdkWindow *window, GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld," "NOACTIVATE|NOZORDER)\n", GDK_WINDOW_HWND (window), - (x - _gdk_offset_x) * impl->window_scale, - (y - _gdk_offset_y) * impl->window_scale, + x * impl->window_scale - _gdk_offset_x, + y * impl->window_scale - _gdk_offset_y, outer_rect.right - outer_rect.left, outer_rect.bottom - outer_rect.top)); API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), SWP_NOZORDER_SPECIFIED, - (x - _gdk_offset_x) * impl->window_scale, - (y - _gdk_offset_y) * impl->window_scale, + x * impl->window_scale - _gdk_offset_x, + y * impl->window_scale - _gdk_offset_y, outer_rect.right - outer_rect.left, outer_rect.bottom - outer_rect.top, SWP_NOACTIVATE | SWP_NOZORDER)); @@ -2321,10 +2321,10 @@ gdk_win32_window_get_geometry (GdkWindow *window, if (gdk_screen_get_root_window (screen) == parent) { - rect.left += _gdk_offset_x * impl->window_scale; - rect.top += _gdk_offset_y * impl->window_scale; - rect.right += _gdk_offset_x * impl->window_scale; - rect.bottom += _gdk_offset_y * impl->window_scale; + rect.left += _gdk_offset_x; + rect.top += _gdk_offset_y; + rect.right += _gdk_offset_x; + rect.bottom += _gdk_offset_y; } } @@ -2421,19 +2421,19 @@ gdk_win32_window_get_frame_extents (GdkWindow *window, hwnd = GDK_WINDOW_HWND (window); API_CALL (GetWindowRect, (hwnd, &r)); - /* Initialize to real, unscaled size */ - rect->x = r.left + _gdk_offset_x * impl->window_scale; - rect->y = r.top + _gdk_offset_y * impl->window_scale; + /* Initialize GdkRectangle to unscaled coordinates */ + rect->x = r.left + _gdk_offset_x; + rect->y = r.top + _gdk_offset_y; rect->width = (r.right - r.left); rect->height = (r.bottom - r.top); /* Extend width and height to ensure that they cover the real size when de-scaled, - * and replace everyting with scaled values + * and replace everything with scaled values */ rect->width = (rect->width + rect->x % impl->window_scale + impl->window_scale - 1) / impl->window_scale; rect->height = (rect->height + rect->y % impl->window_scale + impl->window_scale - 1) / impl->window_scale; - rect->x = r.left / impl->window_scale + _gdk_offset_x; - rect->y = r.top / impl->window_scale + _gdk_offset_y; + rect->x = r.left / impl->window_scale; + rect->y = r.top / impl->window_scale; GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n", GDK_WINDOW_HWND (window), @@ -3937,8 +3937,8 @@ redraw_indicator (gpointer user_data) last_draw = draw_indicator (context, context->draw_timestamp); - window_position.x = (context->indicator_window_rect.x - _gdk_offset_x) * impl->window_scale; - window_position.y = (context->indicator_window_rect.y - _gdk_offset_y) * impl->window_scale; + window_position.x = context->indicator_window_rect.x * impl->window_scale - _gdk_offset_x; + window_position.y = context->indicator_window_rect.y * impl->window_scale - _gdk_offset_y; window_size.cx = context->indicator_window_rect.width * impl->window_scale; window_size.cy = context->indicator_window_rect.height * impl->window_scale; @@ -4595,8 +4595,8 @@ setup_drag_move_resize_context (GdkWindow *window, GDK_NOTE (MISC, g_print ("W32 WM unmaximized window placement is %ld x %ld @ %ld : %ld\n", placement.rcNormalPosition.right - placement.rcNormalPosition.left, placement.rcNormalPosition.bottom - placement.rcNormalPosition.top, - placement.rcNormalPosition.left + _gdk_offset_x * impl->window_scale, - placement.rcNormalPosition.top + _gdk_offset_y * impl->window_scale)); + placement.rcNormalPosition.left + _gdk_offset_x, + placement.rcNormalPosition.top + _gdk_offset_y)); unmax_width = placement.rcNormalPosition.right - placement.rcNormalPosition.left; unmax_height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top; @@ -4607,17 +4607,17 @@ setup_drag_move_resize_context (GdkWindow *window, if (offsetx * impl->window_scale < (shadow_unmax_width / 2) && offsety * impl->window_scale < (shadow_unmax_height / 2)) { - placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->window_scale; + placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top) * impl->window_scale - _gdk_offset_y; placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height; if (left_half) { - placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left - _gdk_offset_x) * impl->window_scale; + placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left) * impl->window_scale - _gdk_offset_x; placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width; } else { - placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right - _gdk_offset_x) * impl->window_scale; + placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right) * impl->window_scale - _gdk_offset_x; placement.rcNormalPosition.left = placement.rcNormalPosition.right - unmax_width; } } @@ -4625,22 +4625,22 @@ setup_drag_move_resize_context (GdkWindow *window, { placement.rcNormalPosition.left = (root_x * impl->window_scale) - (unmax_width / 2) - - (_gdk_offset_x * impl->window_scale); + _gdk_offset_x; if (offsety * impl->window_scale < shadow_unmax_height / 2) - placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->window_scale; + placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top) * impl->window_scale - _gdk_offset_y; else placement.rcNormalPosition.top = (root_y * impl->window_scale) - (unmax_height / 2) - - (_gdk_offset_y * impl->window_scale); + _gdk_offset_y; placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width; placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height; } GDK_NOTE (MISC, g_print ("Unmaximized window will be at %ld : %ld\n", - placement.rcNormalPosition.left + _gdk_offset_x * impl->window_scale, - placement.rcNormalPosition.top + _gdk_offset_y * impl->window_scale)); + placement.rcNormalPosition.left + _gdk_offset_x, + placement.rcNormalPosition.top + _gdk_offset_y)); API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &placement)); } @@ -4823,10 +4823,10 @@ gdk_win32_get_window_size_and_position_from_client_rect (GdkWindow *window, _gdk_win32_adjust_client_rect (window, window_rect); /* Convert GDK screen coordinates to W32 desktop coordinates */ - window_rect->left -= _gdk_offset_x * impl->window_scale; - window_rect->right -= _gdk_offset_x * impl->window_scale; - window_rect->top -= _gdk_offset_y * impl->window_scale; - window_rect->bottom -= _gdk_offset_y * impl->window_scale; + window_rect->left -= _gdk_offset_x; + window_rect->right -= _gdk_offset_x; + window_rect->top -= _gdk_offset_y; + window_rect->bottom -= _gdk_offset_y; window_position->x = window_rect->left; window_position->y = window_rect->top; @@ -5798,13 +5798,13 @@ gdk_win32_window_show_window_menu (GdkWindow *window, } gdk_event_get_root_coords (event, &event_x, &event_y); - x = event_x - _gdk_offset_x; - y = event_y - _gdk_offset_y; + x = event_x * impl->window_scale - _gdk_offset_x; + y = event_y * impl->window_scale - _gdk_offset_y; SendMessage (GDK_WINDOW_HWND (window), WM_SYSMENU, 0, - MAKELPARAM (x * impl->window_scale, y * impl->window_scale)); + MAKELPARAM (x, y)); return TRUE; }