From a9f9062df295bec9202df4ebd88fbb044fbef85b Mon Sep 17 00:00:00 2001 From: Jonas Holzman Date: Tue, 6 Aug 2024 02:25:22 +0200 Subject: [PATCH] Fix: Interactive Docking support on High-DPI/Retina Displays When dragging an area from one window to another, the target location was out by the monitor dot-pitch on macOS Retina displays. This commit fixes this by converting the window position coordinates to the display native pixel size via a new `WM_window_pixels_coords` API function. Pull Request: https://projects.blender.org/blender/blender/pulls/125926 --- source/blender/editors/screen/screen_ops.cc | 11 +++++++++-- source/blender/windowmanager/WM_api.hh | 1 + source/blender/windowmanager/intern/wm_window.cc | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.cc b/source/blender/editors/screen/screen_ops.cc index 0da0d08ff35..37de7c816ae 100644 --- a/source/blender/editors/screen/screen_ops.cc +++ b/source/blender/editors/screen/screen_ops.cc @@ -3841,8 +3841,15 @@ static AreaDockTarget area_docking_target(sAreaJoinData *jd, const wmEvent *even } /* Convert to local coordinates in sa2. */ - const int x = event->xy[0] + jd->win1->posx - jd->win2->posx - jd->sa2->totrct.xmin; - const int y = event->xy[1] + jd->win1->posy - jd->win2->posy - jd->sa2->totrct.ymin; + int win1_posx = jd->win1->posx; + int win1_posy = jd->win1->posy; + int win2_posx = jd->win2->posx; + int win2_posy = jd->win2->posy; + WM_window_pixels_coords(jd->win1, &win1_posx, &win1_posy); + WM_window_pixels_coords(jd->win2, &win2_posx, &win2_posy); + + const int x = event->xy[0] + win1_posx - win2_posx - jd->sa2->totrct.xmin; + const int y = event->xy[1] + win1_posy - win2_posy - jd->sa2->totrct.ymin; const float fac_x = float(x) / float(jd->sa2->winx); const float fac_y = float(y) / float(jd->sa2->winy); diff --git a/source/blender/windowmanager/WM_api.hh b/source/blender/windowmanager/WM_api.hh index a604c9ed5a0..943bcd5955d 100644 --- a/source/blender/windowmanager/WM_api.hh +++ b/source/blender/windowmanager/WM_api.hh @@ -275,6 +275,7 @@ bool WM_window_pixels_read_sample(bContext *C, wmWindow *win, const int pos[2], */ int WM_window_pixels_x(const wmWindow *win); int WM_window_pixels_y(const wmWindow *win); +void WM_window_pixels_coords(const wmWindow *win, int *x, int *y); /** * Get boundaries usable by all window contents, including global areas. */ diff --git a/source/blender/windowmanager/intern/wm_window.cc b/source/blender/windowmanager/intern/wm_window.cc index 11735749d3c..63ac1d0e7ec 100644 --- a/source/blender/windowmanager/intern/wm_window.cc +++ b/source/blender/windowmanager/intern/wm_window.cc @@ -2672,15 +2672,23 @@ void WM_cursor_warp(wmWindow *win, int x, int y) int WM_window_pixels_x(const wmWindow *win) { - float f = GHOST_GetNativePixelSize(static_cast(win->ghostwin)); + const float fac = GHOST_GetNativePixelSize(static_cast(win->ghostwin)); - return int(f * float(win->sizex)); + return int(fac * float(win->sizex)); } int WM_window_pixels_y(const wmWindow *win) { - float f = GHOST_GetNativePixelSize(static_cast(win->ghostwin)); + const float fac = GHOST_GetNativePixelSize(static_cast(win->ghostwin)); - return int(f * float(win->sizey)); + return int(fac * float(win->sizey)); +} + +void WM_window_pixels_coords(const wmWindow *win, int *x, int *y) +{ + const float fac = GHOST_GetNativePixelSize(static_cast(win->ghostwin)); + + *x *= fac; + *y *= fac; } void WM_window_rect_calc(const wmWindow *win, rcti *r_rect)