-- v2: win32u: Introduce a new NtUserSetRawWindowPos call for the drivers. winex11: Use XTranslateCoordinates to compute relative coordinates. winex11: Use NtUserSetWindowPos when DPI awareness is unnecessary. winemac: Use NtUserSetWindowPos when DPI awareness is unnecessary. winemac: Stop mapping toplevel window rects to parent window.
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 | 49 +++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 048375e5adb..2533ab58ff1 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1021,6 +1021,33 @@ 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 (parent == DefaultRootWindow( event->display )) + { + pos.x = event->x; + pos.y = event->y; + } + else 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, events are relative to their parent */ + 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 +1059,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 +1078,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 2533ab58ff1..d5b2f591150 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 ); @@ -1137,7 +1139,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; }
@@ -1175,7 +1177,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_ */
I added a change to avoid calling XTranslateCoordinates if the parent is the root window, but in the other cases it's quite as it was before: synthetic events are rather the exceptional case, they happen when the window is being dragged but otherwise the events are in parent-relative coordinates, which were translated with XTranslateCoordinates before already.