From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/clipping.c | 15 ++++++++++++++- dlls/winex11.drv/init.c | 25 +------------------------ include/ntgdi.h | 2 ++ 3 files changed, 17 insertions(+), 25 deletions(-)
diff --git a/dlls/win32u/clipping.c b/dlls/win32u/clipping.c index 11027824362..3681b542fc3 100644 --- a/dlls/win32u/clipping.c +++ b/dlls/win32u/clipping.c @@ -417,7 +417,7 @@ INT WINAPI NtGdiGetRandomRgn( HDC hDC, HRGN hRgn, INT iCode )
if (!dc) return -1;
- switch (iCode & ~NTGDI_RGN_MIRROR_RTL) + switch (iCode & ~(NTGDI_RGN_MIRROR_RTL | NTGDI_RGN_MONITOR_DPI)) { case 1: if (!dc->hClipRgn) ret = 0; @@ -459,6 +459,19 @@ INT WINAPI NtGdiGetRandomRgn( HDC hDC, HRGN hRgn, INT iCode ) mirror_region( hRgn, hRgn, dc->attr->vis_rect.right - dc->attr->vis_rect.left );
release_dc_ptr( dc ); + + if (ret > 0 && (iCode & NTGDI_RGN_MONITOR_DPI)) + { + HWND hwnd = NtUserWindowFromDC( hDC ); + UINT raw_dpi, monitor_dpi = get_win_monitor_dpi( hwnd, &raw_dpi ); + HRGN region; + + NtGdiOffsetRgn( hRgn, -dc->attr->vis_rect.left, -dc->attr->vis_rect.top ); + region = map_dpi_region( hRgn, get_dpi_for_window( hwnd ), monitor_dpi ); + NtGdiCombineRgn( hRgn, region, 0, RGN_COPY ); + NtGdiDeleteObjectApp( region ); + } + return ret; }
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 63b47e3769a..7963d9cbbc0 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -225,33 +225,10 @@ Drawable get_dc_drawable( HDC hdc, RECT *rect )
HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ) { - RGNDATA *data; - UINT i, size; HRGN region; - POINT pt;
if (!(region = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) return 0; - if (NtGdiGetRandomRgn( hdc, region, SYSRGN ) <= 0) goto failed; - if (!(size = NtGdiGetRegionData( region, 0, NULL ))) goto failed; - if (!(data = malloc( size ))) goto failed; - NtGdiGetRegionData( region, size, data ); - NtGdiDeleteObjectApp( region ); - - NtGdiGetDCPoint( hdc, NtGdiGetDCOrg, &pt ); - NtUserLogicalToPerMonitorDPIPhysicalPoint( hwnd, &pt ); - for (i = 0; i < data->rdh.nCount; i++) - { - RECT *rect = (RECT *)data->Buffer + i; - NtUserLogicalToPerMonitorDPIPhysicalPoint( hwnd, (POINT *)&rect->left ); - NtUserLogicalToPerMonitorDPIPhysicalPoint( hwnd, (POINT *)&rect->right ); - OffsetRect( rect, -pt.x, -pt.y ); - } - - region = NtGdiExtCreateRegion( NULL, size, data ); - free( data ); - return region; - -failed: + if (NtGdiGetRandomRgn( hdc, region, SYSRGN | NTGDI_RGN_MONITOR_DPI ) > 0) return region; NtGdiDeleteObjectApp( region ); return 0; } diff --git a/include/ntgdi.h b/include/ntgdi.h index 224d13c377e..2f7b284a679 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -218,6 +218,8 @@ struct font_enum_entry
/* flag for NtGdiGetRandomRgn to respect LAYOUT_RTL */ #define NTGDI_RGN_MIRROR_RTL 0x80000000 +/* internal flag to get region in monitor raw DPI */ +#define NTGDI_RGN_MONITOR_DPI 0x40000000
#endif /* __WINESRC__ */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 9e380141e18..38d282e12fd 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -965,10 +965,8 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev )
if (event->window != root_window) { - if (NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - mirror_rect( &data->rects.client, &rect ); abs_rect = rect; - NtUserMapWindowPoints( hwnd, 0, (POINT *)&abs_rect, 2, 0 /* per-monitor DPI */ ); + OffsetRect( &abs_rect, data->rects.client.left, data->rects.client.top );
SERVER_START_REQ( update_window_zorder ) {
From: Rémi Bernon rbernon@codeweavers.com
We don't create drawables on child windows. --- dlls/winex11.drv/window.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 893c73df62f..4be1dc9592e 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2374,7 +2374,6 @@ void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, const RECT *top_rect, DWORD flags ) { struct x11drv_escape_set_drawable escape; - HWND parent;
escape.code = X11DRV_SET_DRAWABLE; escape.mode = IncludeInferiors; @@ -2397,19 +2396,7 @@ void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, } else { - /* find the first ancestor that has a drawable */ - for (parent = hwnd; parent && parent != top; parent = NtUserGetAncestor( parent, GA_PARENT )) - if ((escape.drawable = X11DRV_get_whole_window( parent ))) break; - - if (escape.drawable) - { - POINT pt = { 0, 0 }; - NtUserMapWindowPoints( 0, parent, &pt, 1, 0 /* per-monitor DPI */ ); - escape.dc_rect = *win_rect; - OffsetRect( &escape.dc_rect, pt.x, pt.y ); - if (flags & DCX_CLIPCHILDREN) escape.mode = ClipByChildren; - } - else escape.drawable = X11DRV_get_whole_window( top ); + escape.drawable = X11DRV_get_whole_window( top ); }
if (!escape.drawable) return; /* don't create a GC for foreign windows */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/x11drv.h | 9 --------- 1 file changed, 9 deletions(-)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 64380c1322f..d3112424e2c 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -887,15 +887,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 NtUserChildWindowFromPointEx call */ -static inline HWND child_window_from_point( HWND parent, LONG x, LONG y, UINT flags ) -{ - UINT context = NtUserSetThreadDpiAwarenessContext( NTUSER_DPI_PER_MONITOR_AWARE_V2 ); - HWND ret = NtUserChildWindowFromPointEx( parent, x, y, flags ); - NtUserSetThreadDpiAwarenessContext( context ); - return ret; -} - static inline HWND get_focus(void) { GUITHREADINFO info;
From: Rémi Bernon rbernon@codeweavers.com
To avoid having to map DPI for NtUserWindowFromPoint. --- dlls/win32u/driver.c | 2 +- dlls/win32u/window.c | 10 ++++++++-- dlls/wineandroid.drv/android.h | 2 +- dlls/wineandroid.drv/window.c | 2 +- dlls/winemac.drv/macdrv.h | 2 +- dlls/winemac.drv/window.c | 2 +- dlls/winewayland.drv/waylanddrv.h | 2 +- dlls/winewayland.drv/window.c | 20 ++------------------ dlls/winex11.drv/window.c | 2 +- dlls/winex11.drv/x11drv.h | 2 +- include/wine/gdi_driver.h | 4 ++-- 11 files changed, 20 insertions(+), 30 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 55c07a00572..92bad66fc2f 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -891,7 +891,7 @@ static void nulldrv_MoveWindowBits( HWND hwnd, const struct window_rects *old_re { }
-static void nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +static void nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface ) { } diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 48a7304b6b0..47ace040c37 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1998,7 +1998,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru { struct window_rects monitor_rects; WND *win; - HWND surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT ); + HWND owner_hint, surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT ); BOOL ret, is_fullscreen, is_layered, is_child, needs_update = FALSE; struct window_rects old_rects; RECT extra_rects[3]; @@ -2138,7 +2138,13 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru } }
- user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, is_fullscreen, &monitor_rects, get_driver_window_surface( new_surface, monitor_dpi ) ); + owner_hint = NtUserGetWindowRelative(hwnd, GW_OWNER); + /* fallback to any window that is right below our top left corner */ + if (!owner_hint) owner_hint = NtUserWindowFromPoint(new_rects->window.left - 1, new_rects->window.top - 1); + if (owner_hint) owner_hint = NtUserGetAncestor(owner_hint, GA_ROOT); + + user_driver->pWindowPosChanged( hwnd, insert_after, owner_hint, swp_flags, is_fullscreen, &monitor_rects, + get_driver_window_surface( new_surface, monitor_dpi ) );
update_children_window_state( hwnd ); } diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index cab16c484a8..26c6cd9ad20 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -97,7 +97,7 @@ extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); -extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface );
/* unixlib interface */ diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 3e4e9f1697d..17d076d65b5 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1050,7 +1050,7 @@ BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_r /*********************************************************************** * ANDROID_WindowPosChanged */ -void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface ) { struct android_win_data *data; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 76c9be9519f..c17cb1220c8 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -153,7 +153,7 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); extern BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask); extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); -extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface); extern void macdrv_DestroyCursorIcon(HCURSOR cursor); extern BOOL macdrv_GetCursorPos(LPPOINT pos); diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 3f12bd146f2..07874cf985e 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1723,7 +1723,7 @@ BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *styl /*********************************************************************** * WindowPosChanged (MACDRV.@) */ -void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface) { struct macdrv_thread_data *thread_data; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 008e91708cb..8eebee1a5f4 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -379,7 +379,7 @@ void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text); LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam); UINT WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, void *param); LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); -void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface); BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 75ef7d9fba9..b89cc97b08c 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -37,16 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
-/* per-monitor DPI aware NtUserWindowFromPoint call */ -static HWND window_from_point(INT x, INT y) -{ - UINT context = NtUserSetThreadDpiAwarenessContext(NTUSER_DPI_PER_MONITOR_AWARE_V2); - HWND ret = NtUserWindowFromPoint(x, y); - NtUserSetThreadDpiAwarenessContext(context); - return ret; -} - - static int wayland_win_data_cmp_rb(const void *key, const struct rb_entry *entry) { @@ -444,7 +434,7 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const str /*********************************************************************** * WAYLAND_WindowPosChanged */ -void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface) { HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); @@ -458,13 +448,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, BOOL /* Get the managed state with win_data unlocked, as is_window_managed * may need to query win_data information about other HWNDs and thus * acquire the lock itself internally. */ - if (!(managed = is_window_managed(hwnd, swp_flags, &new_rects->window)) && surface) - { - toplevel = NtUserGetWindowRelative(hwnd, GW_OWNER); - /* fallback to any window that is right below our top left corner */ - if (!toplevel) toplevel = window_from_point(new_rects->window.left - 1, new_rects->window.top - 1); - if (toplevel) toplevel = NtUserGetAncestor(toplevel, GA_ROOT); - } + if (!(managed = is_window_managed(hwnd, swp_flags, &new_rects->window)) && surface) toplevel = owner_hint;
if (!(data = wayland_win_data_get(hwnd))) return; toplevel_data = toplevel && toplevel != hwnd ? wayland_win_data_get_nolock(toplevel) : NULL; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 4be1dc9592e..7887b0255f1 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2611,7 +2611,7 @@ BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *sty /*********************************************************************** * WindowPosChanged (X11DRV.@) */ -void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface ) { struct x11drv_thread_data *thread_data; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index d3112424e2c..a037d6bea2d 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -246,7 +246,7 @@ extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UI extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *old_rects, const struct window_rects *new_rects, const RECT *valid_rects ); -extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, BOOL fullscreen, +extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface ); extern BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 00b7f5f219e..09b5dd1e73f 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -219,7 +219,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 100 +#define WINE_GDI_DRIVER_VERSION 101
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -387,7 +387,7 @@ struct user_driver_funcs BOOL (*pGetWindowStyleMasks)(HWND,UINT,UINT,UINT*,UINT*); BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const struct window_rects *,const RECT *); - void (*pWindowPosChanged)(HWND,HWND,UINT,BOOL,const struct window_rects*,struct window_surface*); + void (*pWindowPosChanged)(HWND,HWND,HWND,UINT,BOOL,const struct window_rects*,struct window_surface*); /* system parameters */ BOOL (*pSystemParametersInfo)(UINT,UINT,void*,UINT); /* vulkan support */
Actually I don't see how these failures could possibly be related, the changes are fairly simple and nothing should make any difference on display settings. The ddraw failures are recurring failures, the others seemed to be new but I can see some similar failures on the pattern page.
The amount of failures is suspicious though but maybe it's been very unlucky, and I'm also unable to reproduce them locally. I've restarted the test job to double check.
Looks like the second run is much better, I don't know what happened but I'm tempted to say it's unrelated to this MR.
This merge request was approved by Huw Davies.