From: Rémi Bernon rbernon@codeweavers.com
It's unnecessary, we are only dealing with toplevel windows. --- dlls/winemac.drv/window.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index ff287c6f749..55bbc63e833 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1837,7 +1837,6 @@ void macdrv_window_frame_changed(HWND hwnd, const macdrv_event *event) { struct macdrv_win_data *data; RECT rect; - HWND parent; UINT flags = SWP_NOACTIVATE | SWP_NOZORDER; int width, height; BOOL being_dragged; @@ -1852,16 +1851,12 @@ void macdrv_window_frame_changed(HWND hwnd, const macdrv_event *event)
/* Get geometry */
- parent = NtUserGetAncestor(hwnd, GA_PARENT); - TRACE("win %p/%p new Cocoa frame %s fullscreen %d in_resize %d\n", hwnd, data->cocoa_window, wine_dbgstr_cgrect(event->window_frame_changed.frame), event->window_frame_changed.fullscreen, event->window_frame_changed.in_resize);
rect = rect_from_cgrect(event->window_frame_changed.frame); rect = window_rect_from_visible(&data->rects, rect); - NtUserMapWindowPoints(0, parent, (POINT *)&rect, 2, 0 /* per-monitor DPI */); - width = rect.right - rect.left; height = rect.bottom - rect.top;
@@ -2090,13 +2085,8 @@ void macdrv_window_restore_requested(HWND hwnd, const macdrv_event *event)
if ((style & WS_MAXIMIZE) && (style & WS_VISIBLE) && (data = get_win_data(hwnd))) { - RECT rect; - HWND parent = NtUserGetAncestor(hwnd, GA_PARENT); - - rect = rect_from_cgrect(event->window_restore_requested.frame); + RECT rect = rect_from_cgrect(event->window_restore_requested.frame); rect = window_rect_from_visible(&data->rects, rect); - NtUserMapWindowPoints(0, parent, (POINT *)&rect, 2, 0 /* per-monitor DPI */); - release_win_data(data);
set_internal_window_pos(hwnd, SW_SHOW, &rect, NULL);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 55bbc63e833..ef9a5775e93 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -743,7 +743,7 @@ static void set_focus(HWND hwnd, BOOL raise) if (!(hwnd = NtUserGetAncestor(hwnd, GA_ROOT))) return;
if (raise && hwnd == NtUserGetForegroundWindow() && hwnd != NtUserGetDesktopWindow() && !is_all_the_way_front(hwnd)) - set_window_pos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); + NtUserSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
if (!(data = get_win_data(hwnd))) return;
@@ -2054,7 +2054,7 @@ done: void macdrv_window_brought_forward(HWND hwnd) { TRACE("win %p\n", hwnd); - set_window_pos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + NtUserSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index ce8ff32da07..ab17cb40a1c 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -921,7 +921,7 @@ static void make_owner_managed( HWND hwnd ) if (is_managed( owner )) return; if (!is_managed( hwnd )) return;
- set_window_pos( owner, 0, 0, 0, 0, 0, flags ); + NtUserSetWindowPos( owner, 0, 0, 0, 0, 0, flags ); }
From: Rémi Bernon rbernon@codeweavers.com
Instead of NtUserMapWindowPoints, which will be problematic with display settings virtualization. --- dlls/winex11.drv/event.c | 44 +++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 048375e5adb..531f9f73f2e 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1021,6 +1021,28 @@ static BOOL X11DRV_ReparentNotify( HWND hwnd, XEvent *xev ) return TRUE; }
+/* map XConfigureNotify event coordinates to parent-relative monitor DPI coordinates */ +static POINT map_configure_event_coords( struct x11drv_win_data *data, XConfigureEvent *event ) +{ + Window child, parent = data->embedder ? data->embedder : root_window; + POINT pos; + + if (event->send_event) + { + /* synthetic events are always in root coords */ + XTranslateCoordinates( event->display, DefaultRootWindow( event->display ), parent, + event->x, event->y, (int *)&pos.x, (int *)&pos.y, &child ); + } + else + { + /* query the current window position */ + XTranslateCoordinates( event->display, event->window, parent, 0, 0, + (int *)&pos.x, (int *)&pos.y, &child ); + } + + if (parent == root_window) pos = root_to_virtual_screen( pos.x, pos.y ); + return pos; +}
/*********************************************************************** * X11DRV_ConfigureNotify @@ -1032,8 +1054,6 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) RECT rect; POINT pos; UINT flags; - HWND parent; - BOOL root_coords; int cx, cy, x = event->x, y = event->y; DWORD style;
@@ -1053,27 +1073,9 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
/* Get geometry */
- parent = NtUserGetAncestor( hwnd, GA_PARENT ); - root_coords = event->send_event; /* synthetic events are always in root coords */ - - if (!root_coords && parent == NtUserGetDesktopWindow()) /* normal event, map coordinates to the root */ - { - Window child; - XTranslateCoordinates( event->display, event->window, root_window, - 0, 0, &x, &y, &child ); - root_coords = TRUE; - } - - if (!root_coords) - { - pos.x = x; - pos.y = y; - } - else pos = root_to_virtual_screen( x, y ); - + pos = map_configure_event_coords( data, event ); SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height ); rect = window_rect_from_visible( &data->rects, rect ); - if (root_coords) NtUserMapWindowPoints( 0, parent, (POINT *)&rect, 2, 0 /* per-monitor DPI */ );
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n", hwnd, data->whole_window, (int)rect.left, (int)rect.top,
From: Rémi Bernon rbernon@codeweavers.com
As a per-monitor DPI and later raw per-monitor DPI entry for both NtUserSetWindowPos and NtUserSetInternalWindowPos. --- dlls/win32u/window.c | 24 ++++++++++++++++++++++++ dlls/winemac.drv/window.c | 13 ++----------- dlls/winewayland.drv/window.c | 14 ++++---------- dlls/winex11.drv/event.c | 11 ++++++++--- dlls/winex11.drv/x11drv.h | 9 --------- include/ntuser.h | 14 ++++++++++++++ 6 files changed, 52 insertions(+), 33 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index c1eec5ec266..c48235cf90f 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5717,6 +5717,24 @@ static BOOL set_dialog_info( HWND hwnd, void *info ) return TRUE; }
+static BOOL set_raw_window_pos( HWND hwnd, RECT rect, UINT flags, BOOL internal ) +{ + UINT dpi, raw_dpi; + + TRACE( "hwnd %p, rect %s, flags %#x, internal %u\n", hwnd, wine_dbgstr_rect(&rect), flags, internal ); + + dpi = get_win_monitor_dpi( hwnd, &raw_dpi ); + rect = map_dpi_rect( rect, dpi, get_thread_dpi() ); + + if (internal) + { + NtUserSetInternalWindowPos( hwnd, SW_SHOW, &rect, NULL ); + return TRUE; + } + + return NtUserSetWindowPos( hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags ); +} + /***************************************************************************** * NtUserCallHwnd (win32u.@) */ @@ -5922,6 +5940,12 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) return param == MDT_EFFECTIVE_DPI ? dpi : raw_dpi; }
+ case NtUserCallHwndParam_SetRawWindowPos: + { + struct set_raw_window_pos_params *params = (void *)param; + return set_raw_window_pos( hwnd, params->rect, params->flags, params->internal ); + } + /* temporary exports */ case NtUserSetWindowStyle: { diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index ef9a5775e93..3f12bd146f2 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -56,15 +56,6 @@ static BOOL set_window_pos(HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, }
-/* per-monitor DPI aware NtUserSetInternalWindowPos call */ -static void set_internal_window_pos(HWND hwnd, UINT cmd, RECT *rect, POINT *pt) -{ - UINT context = NtUserSetThreadDpiAwarenessContext(NTUSER_DPI_PER_MONITOR_AWARE_V2); - NtUserSetInternalWindowPos(hwnd, cmd, rect, pt); - NtUserSetThreadDpiAwarenessContext(context); -} - - static struct macdrv_window_features get_window_features_for_style(DWORD style, DWORD ex_style, BOOL shaped) { struct macdrv_window_features wf = {0}; @@ -1884,7 +1875,7 @@ void macdrv_window_frame_changed(HWND hwnd, const macdrv_event *event) int send_sizemove = !event->window_frame_changed.in_resize && !being_dragged && !event->window_frame_changed.skip_size_move_loop; if (send_sizemove) send_message(hwnd, WM_ENTERSIZEMOVE, 0, 0); - set_window_pos(hwnd, 0, rect.left, rect.top, width, height, flags); + NtUserSetRawWindowPos(hwnd, rect, flags, FALSE); if (send_sizemove) send_message(hwnd, WM_EXITSIZEMOVE, 0, 0); } @@ -2089,7 +2080,7 @@ void macdrv_window_restore_requested(HWND hwnd, const macdrv_event *event) rect = window_rect_from_visible(&data->rects, rect); release_win_data(data);
- set_internal_window_pos(hwnd, SW_SHOW, &rect, NULL); + NtUserSetRawWindowPos(hwnd, rect, 0, TRUE); } }
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index a5de1318141..75ef7d9fba9 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -37,15 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
-/* per-monitor DPI aware NtUserSetWindowPos call */ -static BOOL set_window_pos(HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags) -{ - UINT context = NtUserSetThreadDpiAwarenessContext(NTUSER_DPI_PER_MONITOR_AWARE_V2); - BOOL ret = NtUserSetWindowPos(hwnd, after, x, y, cx, cy, flags); - NtUserSetThreadDpiAwarenessContext(context); - return ret; -} - /* per-monitor DPI aware NtUserWindowFromPoint call */ static HWND window_from_point(INT x, INT y) { @@ -518,6 +509,7 @@ static void wayland_configure_window(HWND hwnd) BOOL needs_enter_size_move = FALSE; BOOL needs_exit_size_move = FALSE; struct wayland_win_data *data; + RECT rect;
if (!(data = wayland_win_data_get(hwnd))) return; if (!(surface = data->wayland_surface)) @@ -623,7 +615,9 @@ static void wayland_configure_window(HWND hwnd) flags |= SWP_NOSENDCHANGING; }
- set_window_pos(hwnd, 0, 0, 0, window_width, window_height, flags); + SetRect(&rect, 0, 0, window_width, window_height); + OffsetRect(&rect, data->rects.window.left, data->rects.window.top); + NtUserSetRawWindowPos(hwnd, rect, flags, FALSE); }
/********************************************************************** diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 531f9f73f2e..1fe2e44aea5 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -960,6 +960,7 @@ static void reparent_notify( Display *display, HWND hwnd, Window xparent, int x, { HWND parent, old_parent; DWORD style, flags = 0; + RECT rect;
style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); if (xparent == root_window) @@ -978,7 +979,8 @@ static void reparent_notify( Display *display, HWND hwnd, Window xparent, int x, NtUserSetWindowLong( hwnd, GWL_STYLE, style, FALSE );
if (style & WS_VISIBLE) flags = SWP_SHOWWINDOW; - set_window_pos( hwnd, HWND_TOP, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS | flags ); + SetRect( &rect, x, y, x, y ); + NtUserSetRawWindowPos( hwnd, rect, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS | flags, FALSE );
/* make old parent destroy itself if it no longer has children */ if (old_parent != NtUserGetDesktopWindow()) NtUserPostMessage( old_parent, WM_CLOSE, 0, 0 ); @@ -1132,7 +1134,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE)) { release_win_data( data ); - set_window_pos( hwnd, 0, x, y, cx, cy, flags ); + NtUserSetRawWindowPos( hwnd, rect, flags, FALSE ); return TRUE; }
@@ -1170,7 +1172,10 @@ static BOOL X11DRV_GravityNotify( HWND hwnd, XEvent *xev ) release_win_data( data );
if (window_rect.left != x || window_rect.top != y) - set_window_pos( hwnd, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS ); + { + RECT rect = {x, y, x, y}; + NtUserSetRawWindowPos( hwnd, rect, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS, FALSE ); + }
return TRUE; } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 440746688ca..622658a6377 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -873,15 +873,6 @@ static inline BOOL send_notify_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return NtUserMessageCall( hwnd, msg, wparam, lparam, 0, NtUserSendNotifyMessage, FALSE ); }
-/* per-monitor DPI aware NtUserSetWindowPos call */ -static inline BOOL set_window_pos( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags ) -{ - UINT context = NtUserSetThreadDpiAwarenessContext( NTUSER_DPI_PER_MONITOR_AWARE_V2 ); - BOOL ret = NtUserSetWindowPos( hwnd, after, x, y, cx, cy, flags ); - NtUserSetThreadDpiAwarenessContext( context ); - return ret; -} - /* per-monitor DPI aware NtUserChildWindowFromPointEx call */ static inline HWND child_window_from_point( HWND parent, LONG x, LONG y, UINT flags ) { diff --git a/include/ntuser.h b/include/ntuser.h index 558dfacea20..b35f9a54fd2 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -1319,6 +1319,7 @@ enum NtUserCallHwndParam_SendHardwareInput, NtUserCallHwndParam_ExposeWindowSurface, NtUserCallHwndParam_GetWinMonitorDpi, + NtUserCallHwndParam_SetRawWindowPos, /* temporary exports */ NtUserSetWindowStyle, }; @@ -1549,4 +1550,17 @@ static inline UINT NtUserGetWinMonitorDpi( HWND hwnd, MONITOR_DPI_TYPE type ) return NtUserCallHwndParam( hwnd, type, NtUserCallHwndParam_GetWinMonitorDpi ); }
+struct set_raw_window_pos_params +{ + RECT rect; + UINT flags; + BOOL internal; +}; + +static inline BOOL NtUserSetRawWindowPos( HWND hwnd, RECT rect, UINT flags, BOOL internal ) +{ + struct set_raw_window_pos_params params = {.rect = rect, .flags = flags, .internal = internal}; + return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, NtUserCallHwndParam_SetRawWindowPos ); +} + #endif /* _NTUSER_ */
Is there something not right about this? Fwiw my intention is to avoid doing mapping in the drivers as much as possible, especially host to win32 rect mapping, because I want to introduce non-bijective mappings for virtual display settings.
I think it is easier and cleaner to keep all the mappings done in win32u. The drivers would work in "raw" coordinates (ie: raw monitor DPI, using the host/physical display mode), while win32u would work in "virtual" coordinates (ie: effective monitor DPI or window DPI, using the client/current display mode), mapping rects from virt to raw before calling the drivers, and from raw to virt when called from the drivers (mostly only in NtUserSetRawWindowPos).
For mouse input, wineserver would be informed of the virt/raw DPI mapping transformations as well, although ultimately that could perhaps be done by moving the monitor rects fully into it and it could probably be solely in charge of doing all the mappings.
It doesn't seem right to always rely on XTranslateCoordinates, since that requires a server round-trip which is a problem on remote displays.