From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/window.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index e8d6b770496..639526486c7 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -372,7 +372,7 @@ static inline HWND get_active_window(void) * * Check if a given window should be managed */ -static BOOL is_window_managed(HWND hwnd, UINT swp_flags, const RECT *window_rect) +static BOOL is_window_managed(HWND hwnd, UINT swp_flags, const RECT *window_rect, UINT dpi) { DWORD style, ex_style;
@@ -388,18 +388,10 @@ static BOOL is_window_managed(HWND hwnd, UINT swp_flags, const RECT *window_rect if (style & WS_THICKFRAME) return TRUE; if (style & WS_POPUP) { - HMONITOR hmon; - MONITORINFO mi; - /* popup with sysmenu == caption are managed */ if (style & WS_SYSMENU) return TRUE; /* full-screen popup windows are managed */ - hmon = NtUserMonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); - mi.cbSize = sizeof(mi); - NtUserGetMonitorInfo(hmon, &mi); - if (window_rect->left <= mi.rcWork.left && window_rect->right >= mi.rcWork.right && - window_rect->top <= mi.rcWork.top && window_rect->bottom >= mi.rcWork.bottom) - return TRUE; + if (NtUserIsWindowRectFullScreen(window_rect, dpi)) return TRUE; } /* application windows are managed */ ex_style = NtUserGetWindowLongW(hwnd, GWL_EXSTYLE); @@ -454,7 +446,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, cons /* 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. */ - managed = is_window_managed(hwnd, swp_flags, &new_rects->window); + managed = is_window_managed(hwnd, swp_flags, &new_rects->window, get_win_monitor_dpi(hwnd));
if (!(data = wayland_win_data_get(hwnd))) return;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 6e834457620..97c8becb2ac 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -247,7 +247,7 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) * * Check if a given window should be managed */ -static BOOL is_window_managed( HWND hwnd, UINT swp_flags, const RECT *window_rect ) +static BOOL is_window_managed( HWND hwnd, UINT swp_flags, const RECT *window_rect, UINT dpi ) { DWORD style, ex_style;
@@ -265,18 +265,10 @@ static BOOL is_window_managed( HWND hwnd, UINT swp_flags, const RECT *window_rec if (style & WS_THICKFRAME) return TRUE; if (style & WS_POPUP) { - HMONITOR hmon; - MONITORINFO mi; - /* popup with sysmenu == caption are managed */ if (style & WS_SYSMENU) return TRUE; /* full-screen popup windows are managed */ - hmon = NtUserMonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY ); - mi.cbSize = sizeof( mi ); - NtUserGetMonitorInfo( hmon, &mi ); - if (window_rect->left <= mi.rcWork.left && window_rect->right >= mi.rcWork.right && - window_rect->top <= mi.rcWork.top && window_rect->bottom >= mi.rcWork.bottom) - return TRUE; + if (NtUserIsWindowRectFullScreen(window_rect, dpi)) return TRUE; } /* application windows are managed */ ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ); @@ -1738,7 +1730,7 @@ static void create_whole_window( struct x11drv_win_data *data ) HRGN win_rgn; POINT pos;
- if (!data->managed && is_window_managed( data->hwnd, SWP_NOACTIVATE, &data->window_rect )) + if (!data->managed && is_window_managed( data->hwnd, SWP_NOACTIVATE, &data->window_rect, get_win_monitor_dpi( data->hwnd ) )) { TRACE( "making win %p/%lx managed\n", data->hwnd, data->whole_window ); data->managed = TRUE; @@ -2580,7 +2572,7 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct wi data->shaped = shaped;
/* check if we need to switch the window to managed */ - if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, &rects->window )) + if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, &rects->window, get_win_monitor_dpi( hwnd ) )) { TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window ); release_win_data( data );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 4 +- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/sysparams.c | 2 +- dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 110 ++++++++++++++++++++++++-- dlls/wineandroid.drv/android.h | 4 +- dlls/wineandroid.drv/window.c | 8 +- dlls/winemac.drv/macdrv.h | 4 +- dlls/winemac.drv/window.c | 8 +- dlls/winewayland.drv/waylanddrv.h | 2 +- dlls/winewayland.drv/window.c | 96 +---------------------- dlls/winex11.drv/window.c | 123 +++--------------------------- dlls/winex11.drv/x11drv.h | 4 +- include/wine/gdi_driver.h | 6 +- 14 files changed, 141 insertions(+), 232 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index ca31eec5f49..8cbf4b8c2e2 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -837,7 +837,7 @@ static void nulldrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE al { }
-static void nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent ) +static void nulldrv_SetParent( HWND hwnd, BOOL managed, HWND parent, HWND old_parent ) { }
@@ -876,7 +876,7 @@ static LRESULT nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM return 0; }
-static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +static BOOL nulldrv_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ) { return TRUE; } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index fd594488c08..2412d4def64 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -90,6 +90,7 @@ typedef struct tagWND #define WIN_NEEDS_SHOW_OWNEDPOPUP 0x0020 /* WM_SHOWWINDOW:SC_SHOW must be sent in the next ShowOwnedPopup call */ #define WIN_CHILDREN_MOVED 0x0040 /* children may have moved, ignore stored positions */ #define WIN_HAS_IME_WIN 0x0080 /* the window has been registered with imm32 */ +#define WIN_IS_MANAGED 0x0100 /* the window is managed by the host WM */
#define WND_OTHER_PROCESS ((WND *)1) /* returned by get_win_ptr on unknown window handles */ #define WND_DESKTOP ((WND *)2) /* returned by get_win_ptr on the desktop window */ diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 094a963d305..141bc5741ed 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2330,7 +2330,7 @@ RECT get_virtual_screen_rect( UINT dpi ) return rect; }
-static BOOL is_window_rect_full_screen( const RECT *rect, UINT dpi ) +BOOL is_window_rect_full_screen( const RECT *rect, UINT dpi ) { struct monitor *monitor; BOOL ret = FALSE; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index c4521899299..a1c22fea269 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -178,6 +178,7 @@ extern UINT get_thread_dpi(void); extern UINT set_thread_dpi_awareness_context( UINT context ); extern UINT get_thread_dpi_awareness_context(void); extern RECT get_virtual_screen_rect( UINT dpi ); +extern BOOL is_window_rect_full_screen( const RECT *rect, UINT dpi ); extern BOOL is_exiting_thread( DWORD tid ); extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ); extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 1301f230211..66d116c1d4e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -253,6 +253,75 @@ WND *get_win_ptr( HWND hwnd ) return win; }
+ +static HWND *build_hwnd_list(void) +{ + NTSTATUS status; + HWND *list; + ULONG count = 128; + + for (;;) + { + if (!(list = malloc( count * sizeof(*list) ))) return NULL; + status = NtUserBuildHwndList( 0, 0, 0, 0, 0, count, list, &count ); + if (!status) return list; + free( list ); + if (status != STATUS_BUFFER_TOO_SMALL) return NULL; + } +} + +static BOOL has_owned_popups( HWND hwnd ) +{ + HWND *list; + UINT i; + BOOL ret = FALSE; + + if (!(list = build_hwnd_list())) return FALSE; + + for (i = 0; list[i] != HWND_BOTTOM; i++) + { + if (list[i] == hwnd) break; /* popups are always above owner */ + if (NtUserGetWindowRelative( list[i], GW_OWNER ) != hwnd) continue; + if ((ret = win_get_flags( list[i] ) & WIN_IS_MANAGED)) break; + } + + free( list ); + return ret; +} + +/*********************************************************************** + * is_window_managed + * + * Check if a given window should be managed by the host window manager + */ +static BOOL is_window_managed( HWND hwnd, UINT swp_flags, UINT style, UINT ex_style, + const RECT *window_rect, UINT dpi ) +{ + /* child windows are not managed */ + if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD) return FALSE; + /* activated windows are managed */ + if (!(swp_flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW))) return TRUE; + if (hwnd == get_active_window()) return TRUE; + /* windows with caption are managed */ + if ((style & WS_CAPTION) == WS_CAPTION) return TRUE; + /* windows with thick frame are managed */ + if (style & WS_THICKFRAME) return TRUE; + if (style & WS_POPUP) + { + /* popup with sysmenu == caption are managed */ + if (style & WS_SYSMENU) return TRUE; + /* full-screen popup windows are managed */ + if (is_window_rect_full_screen( window_rect, dpi )) return TRUE; + } + /* application windows are managed */ + if (ex_style & WS_EX_APPWINDOW) return TRUE; + /* windows that own popups are managed */ + if (has_owned_popups( hwnd )) return TRUE; + /* default: not managed */ + return FALSE; +} + + /*********************************************************************** * is_current_thread_window * @@ -384,17 +453,33 @@ HWND get_parent( HWND hwnd ) return retval; }
+ +static void set_window_managed( HWND hwnd, BOOL managed ) +{ + UINT updated; + HWND owner; + + if (!managed) updated = win_set_flags( hwnd, 0, WIN_IS_MANAGED ); + else updated = ~win_set_flags( hwnd, WIN_IS_MANAGED, 0 ); + if (!(updated & WIN_IS_MANAGED)) return; + + if (!(owner = NtUserGetWindowRelative( hwnd, GW_OWNER ))) return; + /* if the window is managed, make sure its owner window is too. */ + update_window_state( owner ); +} + + /***************************************************************** * NtUserSetParent (win32u.@) */ HWND WINAPI NtUserSetParent( HWND hwnd, HWND parent ) { RECT window_rect = {0}, old_screen_rect = {0}, new_screen_rect = {0}; - UINT context; + UINT context, style, ex_style; WINDOWPOS winpos; HWND full_handle; HWND old_parent = 0; - BOOL was_visible; + BOOL was_visible, managed; WND *win; BOOL ret;
@@ -461,7 +546,13 @@ HWND WINAPI NtUserSetParent( HWND hwnd, HWND parent ) get_window_rect_rel( hwnd, COORDS_SCREEN, &new_screen_rect, 0 ); context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd ));
- user_driver->pSetParent( full_handle, parent, old_parent ); + style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); + ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ); + + managed = is_window_managed( hwnd, SWP_NOACTIVATE, style, ex_style, &window_rect, get_thread_dpi() ); + set_window_managed( hwnd, managed ); + + user_driver->pSetParent( full_handle, managed, parent, old_parent );
winpos.hwnd = hwnd; winpos.hwndInsertAfter = HWND_TOP; @@ -1871,21 +1962,28 @@ static BOOL get_default_window_surface( HWND hwnd, const RECT *surface_rect, str static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, BOOL create_layered, struct window_rects *rects, RECT *surface_rect ) { - BOOL shaped, needs_surface, create_opaque, is_layered; + BOOL shaped, managed, needs_surface, create_opaque, is_layered; HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); struct window_surface *new_surface; + UINT style, ex_style; RECT dummy; HRGN shape;
+ style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); + ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ); + if (get_window_region( hwnd, FALSE, &shape, &dummy )) shaped = FALSE; else if ((shaped = !!shape)) NtGdiDeleteObjectApp( shape );
+ managed = is_window_managed( hwnd, swp_flags, style, ex_style, &rects->window, get_thread_dpi() ); + set_window_managed( hwnd, managed ); + rects->visible = rects->window; - if (!user_driver->pWindowPosChanging( hwnd, swp_flags, shaped, rects )) needs_surface = FALSE; + if (!user_driver->pWindowPosChanging( hwnd, shaped, managed, rects )) needs_surface = FALSE; else if (parent && parent != NtUserGetDesktopWindow()) needs_surface = FALSE; else if (swp_flags & SWP_HIDEWINDOW) needs_surface = FALSE; else if (swp_flags & SWP_SHOWWINDOW) needs_surface = TRUE; - else needs_surface = !!(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE); + else needs_surface = !!(style & WS_VISIBLE);
if (!get_surface_rect( &rects->visible, surface_rect )) needs_surface = FALSE; if (!get_default_window_surface( hwnd, surface_rect, &new_surface )) return NULL; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 616bd5beffe..f389da7279a 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -92,11 +92,11 @@ extern BOOL ANDROID_CreateWindow( HWND hwnd ); extern void ANDROID_DestroyWindow( HWND hwnd ); extern BOOL ANDROID_ProcessEvents( DWORD mask ); extern LRESULT ANDROID_DesktopWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); -extern void ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent ); +extern void ANDROID_SetParent( HWND hwnd, BOOL managed, HWND parent, HWND old_parent ); extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); 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, struct window_rects *rects ); +extern BOOL ANDROID_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, 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, const struct window_rects *new_rects, struct window_surface *surface ); diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index bb7a8985f3c..dabae0354d8 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1032,11 +1032,11 @@ static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_r /*********************************************************************** * ANDROID_WindowPosChanging */ -BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +BOOL ANDROID_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ) { struct android_win_data *data = get_win_data( hwnd );
- TRACE( "hwnd %p, swp_flags %#x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects( rects ) ); + TRACE( "hwnd %p, shaped %u, managed %u, rects %s\n", hwnd, shaped, managed, debugstr_window_rects( rects ) );
if (!data && !(data = create_win_data( hwnd, &rects->window, &rects->client ))) return FALSE; /* use default surface */ release_win_data(data); @@ -1114,14 +1114,14 @@ UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) /***************************************************************** * ANDROID_SetParent */ -void ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent ) +void ANDROID_SetParent( HWND hwnd, BOOL managed, HWND parent, HWND old_parent ) { struct android_win_data *data;
if (parent == old_parent) return; if (!(data = get_win_data( hwnd ))) return;
- TRACE( "win %p parent %p -> %p\n", hwnd, old_parent, parent ); + TRACE( "win %p managed %u parent %p -> %p\n", hwnd, managed, old_parent, parent );
data->parent = (parent == NtUserGetDesktopWindow()) ? 0 : parent; ioctl_set_window_parent( hwnd, parent, (float)get_win_monitor_dpi( hwnd ) / NtUserGetDpiForWindow( hwnd )); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 40fa08605c1..49185e99507 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -139,7 +139,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern void macdrv_SetFocus(HWND hwnd); extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alpha, DWORD flags); -extern void macdrv_SetParent(HWND hwnd, HWND parent, HWND old_parent); +extern void macdrv_SetParent(HWND hwnd, BOOL managed, HWND parent, HWND old_parent); extern void macdrv_SetWindowRgn(HWND hwnd, HRGN hrgn, BOOL redraw); extern void macdrv_SetWindowStyle(HWND hwnd, INT offset, STYLESTRUCT *style); extern void macdrv_SetWindowText(HWND hwnd, LPCWSTR text); @@ -147,7 +147,7 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern LRESULT macdrv_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam); extern void macdrv_UpdateLayeredWindow(HWND hwnd, UINT flags); extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); -extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects); +extern BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects); extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); extern void macdrv_MoveWindowBits(HWND hwnd, const struct window_rects *new_rects, const RECT *valid_rects); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index f7d9dfd76ea..7d100b01226 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1591,11 +1591,11 @@ void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alpha, DWOR /***************************************************************** * SetParent (MACDRV.@) */ -void macdrv_SetParent(HWND hwnd, HWND parent, HWND old_parent) +void macdrv_SetParent(HWND hwnd, BOOL managed, HWND parent, HWND old_parent) { struct macdrv_win_data *data;
- TRACE("%p, %p, %p\n", hwnd, parent, old_parent); + TRACE("%p, %u, %p, %p\n", hwnd, managed, parent, old_parent);
if (parent == old_parent) return; if (!(data = get_win_data(hwnd))) return; @@ -1835,13 +1835,13 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) /*********************************************************************** * WindowPosChanging (MACDRV.@) */ -BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects) +BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects) { struct macdrv_win_data *data = get_win_data(hwnd); DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); BOOL ret = FALSE;
- TRACE("hwnd %p, swp_flags %04x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects(rects)); + TRACE("hwnd %p, shaped %u, managed %u, rects %s\n", hwnd, shaped, managed, debugstr_window_rects(rects));
if (!data && !(data = macdrv_create_win_data(hwnd, &rects->window, &rects->client))) return FALSE; /* use default surface */ data->shaped = shaped; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 1a2eeeecb93..49bae8510fe 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -357,7 +357,7 @@ UINT WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manage LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); -BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects); +BOOL WAYLAND_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects); BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 639526486c7..059343b8e8c 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -317,90 +317,6 @@ out: wl_display_flush(process_wayland.wl_display); }
-static BOOL is_managed(HWND hwnd) -{ - struct wayland_win_data *data = wayland_win_data_get(hwnd); - BOOL ret = data && data->managed; - if (data) wayland_win_data_release(data); - return ret; -} - -static HWND *build_hwnd_list(void) -{ - NTSTATUS status; - HWND *list; - ULONG count = 128; - - for (;;) - { - if (!(list = malloc(count * sizeof(*list)))) return NULL; - status = NtUserBuildHwndList(0, 0, 0, 0, 0, count, list, &count); - if (!status) return list; - free(list); - if (status != STATUS_BUFFER_TOO_SMALL) return NULL; - } -} - -static BOOL has_owned_popups(HWND hwnd) -{ - HWND *list; - UINT i; - BOOL ret = FALSE; - - if (!(list = build_hwnd_list())) return FALSE; - - for (i = 0; list[i] != HWND_BOTTOM; i++) - { - if (list[i] == hwnd) break; /* popups are always above owner */ - if (NtUserGetWindowRelative(list[i], GW_OWNER) != hwnd) continue; - if ((ret = is_managed(list[i]))) break; - } - - free(list); - return ret; -} - -static inline HWND get_active_window(void) -{ - GUITHREADINFO info; - info.cbSize = sizeof(info); - return NtUserGetGUIThreadInfo(GetCurrentThreadId(), &info) ? info.hwndActive : 0; -} - -/*********************************************************************** - * is_window_managed - * - * Check if a given window should be managed - */ -static BOOL is_window_managed(HWND hwnd, UINT swp_flags, const RECT *window_rect, UINT dpi) -{ - DWORD style, ex_style; - - /* child windows are not managed */ - style = NtUserGetWindowLongW(hwnd, GWL_STYLE); - if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD) return FALSE; - /* activated windows are managed */ - if (!(swp_flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW))) return TRUE; - if (hwnd == get_active_window()) return TRUE; - /* windows with caption are managed */ - if ((style & WS_CAPTION) == WS_CAPTION) return TRUE; - /* windows with thick frame are managed */ - if (style & WS_THICKFRAME) return TRUE; - if (style & WS_POPUP) - { - /* popup with sysmenu == caption are managed */ - if (style & WS_SYSMENU) return TRUE; - /* full-screen popup windows are managed */ - if (NtUserIsWindowRectFullScreen(window_rect, dpi)) return TRUE; - } - /* application windows are managed */ - ex_style = NtUserGetWindowLongW(hwnd, GWL_EXSTYLE); - if (ex_style & WS_EX_APPWINDOW) return TRUE; - /* windows that own popups are managed */ - if (has_owned_popups(hwnd)) return TRUE; - /* default: not managed */ - return FALSE; -}
/*********************************************************************** * WAYLAND_DestroyWindow @@ -419,13 +335,14 @@ void WAYLAND_DestroyWindow(HWND hwnd) /*********************************************************************** * WAYLAND_WindowPosChanging */ -BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects) +BOOL WAYLAND_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects) { struct wayland_win_data *data = wayland_win_data_get(hwnd);
- TRACE("hwnd %p, swp_flags %04x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects(rects)); + TRACE("hwnd %p, shaped %u, managed %u, rects %s\n", hwnd, shaped, managed, debugstr_window_rects(rects));
if (!data && !(data = wayland_win_data_create(hwnd, &rects->window, &rects->client))) return FALSE; /* use default surface */ + data->managed = managed; wayland_win_data_release(data);
return TRUE; @@ -439,20 +356,13 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, cons struct window_surface *surface) { struct wayland_win_data *data; - BOOL managed;
TRACE("hwnd %p new_rects %s after %p flags %08x\n", hwnd, debugstr_window_rects(new_rects), insert_after, swp_flags);
- /* 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. */ - managed = is_window_managed(hwnd, swp_flags, &new_rects->window, get_win_monitor_dpi(hwnd)); - if (!(data = wayland_win_data_get(hwnd))) return;
data->window_rect = new_rects->window; data->client_rect = new_rects->client; - data->managed = managed;
if (surface) window_surface_add_ref(surface); if (data->window_surface) window_surface_release(data->window_surface); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 97c8becb2ac..a397d2c297c 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -179,49 +179,6 @@ static void remove_startup_notification(Display *display, Window window) } }
-static BOOL is_managed( HWND hwnd ) -{ - struct x11drv_win_data *data = get_win_data( hwnd ); - BOOL ret = data && data->managed; - release_win_data( data ); - return ret; -} - -HWND *build_hwnd_list(void) -{ - NTSTATUS status; - HWND *list; - ULONG count = 128; - - for (;;) - { - if (!(list = malloc( count * sizeof(*list) ))) return NULL; - status = NtUserBuildHwndList( 0, 0, 0, 0, 0, count, list, &count ); - if (!status) return list; - free( list ); - if (status != STATUS_BUFFER_TOO_SMALL) return NULL; - } -} - -static BOOL has_owned_popups( HWND hwnd ) -{ - HWND *list; - UINT i; - BOOL ret = FALSE; - - if (!(list = build_hwnd_list())) return FALSE; - - for (i = 0; list[i] != HWND_BOTTOM; i++) - { - if (list[i] == hwnd) break; /* popups are always above owner */ - if (NtUserGetWindowRelative( list[i], GW_OWNER ) != hwnd) continue; - if ((ret = is_managed( list[i] ))) break; - } - - free( list ); - return ret; -} -
/*********************************************************************** * alloc_win_data @@ -242,44 +199,6 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) }
-/*********************************************************************** - * is_window_managed - * - * Check if a given window should be managed - */ -static BOOL is_window_managed( HWND hwnd, UINT swp_flags, const RECT *window_rect, UINT dpi ) -{ - DWORD style, ex_style; - - if (!managed_mode) return FALSE; - - /* child windows are not managed */ - style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); - if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD) return FALSE; - /* activated windows are managed */ - if (!(swp_flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW))) return TRUE; - if (hwnd == get_active_window()) return TRUE; - /* windows with caption are managed */ - if ((style & WS_CAPTION) == WS_CAPTION) return TRUE; - /* windows with thick frame are managed */ - if (style & WS_THICKFRAME) return TRUE; - if (style & WS_POPUP) - { - /* popup with sysmenu == caption are managed */ - if (style & WS_SYSMENU) return TRUE; - /* full-screen popup windows are managed */ - if (NtUserIsWindowRectFullScreen(window_rect, dpi)) return TRUE; - } - /* application windows are managed */ - ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ); - if (ex_style & WS_EX_APPWINDOW) return TRUE; - /* windows that own popups are managed */ - if (has_owned_popups( hwnd )) return TRUE; - /* default: not managed */ - return FALSE; -} - - /*********************************************************************** * is_window_resizable * @@ -902,25 +821,6 @@ static void set_initial_wm_hints( Display *display, Window window ) }
-/*********************************************************************** - * make_owner_managed - * - * If the window is managed, make sure its owner window is too. - */ -static void make_owner_managed( HWND hwnd ) -{ - static const UINT flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | - SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_STATECHANGED; - HWND owner; - - if (!(owner = NtUserGetWindowRelative( hwnd, GW_OWNER ))) return; - if (is_managed( owner )) return; - if (!is_managed( hwnd )) return; - - set_window_pos( owner, 0, 0, 0, 0, 0, flags ); -} - - /*********************************************************************** * set_wm_hints * @@ -1226,7 +1126,6 @@ static void map_window( HWND hwnd, DWORD new_style ) { struct x11drv_win_data *data;
- make_owner_managed( hwnd ); wait_for_withdrawn_state( hwnd, TRUE );
if (!(data = get_win_data( hwnd ))) return; @@ -1719,7 +1618,7 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colo * * Create the whole X window for a given window */ -static void create_whole_window( struct x11drv_win_data *data ) +static void create_whole_window( struct x11drv_win_data *data, BOOL managed ) { int cx, cy, mask; XSetWindowAttributes attr; @@ -1730,7 +1629,7 @@ static void create_whole_window( struct x11drv_win_data *data ) HRGN win_rgn; POINT pos;
- if (!data->managed && is_window_managed( data->hwnd, SWP_NOACTIVATE, &data->window_rect, get_win_monitor_dpi( data->hwnd ) )) + if (!data->managed && managed && managed_mode) { TRACE( "making win %p/%lx managed\n", data->hwnd, data->whole_window ); data->managed = TRUE; @@ -1857,7 +1756,7 @@ void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BO detach_client_window( data, client_window ); destroy_whole_window( data, FALSE ); data->vis = *vis; - create_whole_window( data ); + create_whole_window( data, data->managed ); /* attach the client back to the re-created whole_window */ attach_client_window( data, client_window ); } @@ -2111,7 +2010,7 @@ void release_win_data( struct x11drv_win_data *data ) * * Create an X11 data window structure for an existing window. */ -static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *window_rect, +static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, BOOL managed, const RECT *window_rect, const RECT *client_rect ) { Display *display; @@ -2139,7 +2038,7 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *wi data->client_rect = *client_rect; if (parent == NtUserGetDesktopWindow()) { - create_whole_window( data ); + create_whole_window( data, managed ); TRACE( "win %p/%lx window %s whole %s client %s\n", hwnd, data->whole_window, wine_dbgstr_rect( &data->window_rect ), wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( &data->client_rect )); @@ -2524,7 +2423,7 @@ void X11DRV_SetCapture( HWND hwnd, UINT flags ) /***************************************************************** * SetParent (X11DRV.@) */ -void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ) +void X11DRV_SetParent( HWND hwnd, BOOL managed, HWND parent, HWND old_parent ) { struct x11drv_win_data *data;
@@ -2543,7 +2442,7 @@ void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ) } else /* new top level window */ { - create_whole_window( data ); + create_whole_window( data, managed ); } done: release_win_data( data ); @@ -2561,18 +2460,18 @@ done: /*********************************************************************** * WindowPosChanging (X11DRV.@) */ -BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ) { struct x11drv_win_data *data = get_win_data( hwnd ); BOOL ret = FALSE;
- TRACE( "hwnd %p, swp_flags %#x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects( rects ) ); + TRACE( "hwnd %p, shaped %u, managed %u, rects %s\n", hwnd, shaped, managed, debugstr_window_rects( rects ) );
- if (!data && !(data = X11DRV_create_win_data( hwnd, &rects->window, &rects->client ))) return FALSE; /* use default surface */ + if (!data && !(data = X11DRV_create_win_data( hwnd, managed, &rects->window, &rects->client ))) return FALSE; /* use default surface */ data->shaped = shaped;
/* check if we need to switch the window to managed */ - if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, &rects->window, get_win_monitor_dpi( hwnd ) )) + if (!data->managed && data->whole_window && managed && managed_mode) { TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window ); release_win_data( data ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 61d532d9ba1..3a8563d9431 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -231,7 +231,7 @@ extern void X11DRV_SetCapture( HWND hwnd, UINT flags ); extern void X11DRV_SetDesktopWindow( HWND hwnd ); extern void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ); -extern void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ); +extern void X11DRV_SetParent( HWND hwnd, BOOL managed, HWND parent, HWND old_parent ); extern void X11DRV_SetWindowIcon( HWND hwnd, UINT type, HICON icon ); extern void X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ); extern void X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ); @@ -242,7 +242,7 @@ extern LRESULT X11DRV_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARA extern void X11DRV_UpdateClipboard(void); extern void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); -extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ); +extern BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ); 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 *new_rects, const RECT *valid_rects ); extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 69bd096a1a5..14dd9ba868a 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -193,7 +193,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 93 +#define WINE_GDI_DRIVER_VERSION 94
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -349,7 +349,7 @@ struct user_driver_funcs void (*pSetDesktopWindow)(HWND); void (*pSetFocus)(HWND); void (*pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); - void (*pSetParent)(HWND,HWND,HWND); + void (*pSetParent)(HWND,BOOL,HWND,HWND); void (*pSetWindowRgn)(HWND,HRGN,BOOL); void (*pSetWindowIcon)(HWND,UINT,HICON); void (*pSetWindowStyle)(HWND,INT,STYLESTRUCT*); @@ -358,7 +358,7 @@ struct user_driver_funcs LRESULT (*pSysCommand)(HWND,WPARAM,LPARAM); void (*pUpdateLayeredWindow)(HWND,UINT); LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); - BOOL (*pWindowPosChanging)(HWND,UINT,BOOL,struct window_rects *); + BOOL (*pWindowPosChanging)(HWND,BOOL,BOOL,struct window_rects *); BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const RECT *); void (*pWindowPosChanged)(HWND,HWND,UINT,const struct window_rects*,struct window_surface*);
From: Rémi Bernon rbernon@codeweavers.com
Using a new GetWindowStyleMasks driver entry to get the style masks to be used to mask out non-client decorations which are hidden by the host decorations. --- dlls/win32u/driver.c | 9 +++- dlls/win32u/window.c | 28 ++++++++++- dlls/wineandroid.drv/android.h | 2 +- dlls/wineandroid.drv/window.c | 2 +- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 3 +- dlls/winemac.drv/window.c | 77 +++++++++++++++++++++---------- dlls/winewayland.drv/waylanddrv.h | 2 +- dlls/winewayland.drv/window.c | 2 +- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/window.c | 72 +++++++++++++++-------------- dlls/winex11.drv/x11drv.h | 3 +- include/wine/gdi_driver.h | 5 +- 13 files changed, 139 insertions(+), 68 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 8cbf4b8c2e2..18d3fdd2926 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -876,11 +876,16 @@ static LRESULT nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM return 0; }
-static BOOL nulldrv_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ) +static BOOL nulldrv_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects ) { return TRUE; }
+extern BOOL nulldrv_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ) +{ + return FALSE; +} + static BOOL nulldrv_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) { return FALSE; @@ -1283,6 +1288,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_UpdateLayeredWindow, nulldrv_WindowMessage, nulldrv_WindowPosChanging, + nulldrv_GetWindowStyleMasks, nulldrv_CreateWindowSurface, nulldrv_MoveWindowBits, nulldrv_WindowPosChanged, @@ -1371,6 +1377,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(UpdateLayeredWindow); SET_USER_FUNC(WindowMessage); SET_USER_FUNC(WindowPosChanging); + SET_USER_FUNC(GetWindowStyleMasks); SET_USER_FUNC(CreateWindowSurface); SET_USER_FUNC(MoveWindowBits); SET_USER_FUNC(WindowPosChanged); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 66d116c1d4e..3d4f63b0213 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1909,6 +1909,28 @@ done: }
+static RECT get_visible_rect( HWND hwnd, RECT window_rect, UINT style, UINT ex_style, UINT dpi ) +{ + RECT visible_rect = window_rect; + UINT style_mask, ex_style_mask; + RECT rect = {0}; + + if (!user_driver->pGetWindowStyleMasks( hwnd, style, ex_style, &style_mask, &ex_style_mask )) return visible_rect; + NtUserAdjustWindowRect( &rect, style & style_mask, FALSE, ex_style & ex_style_mask, dpi ? dpi : get_system_dpi() ); + + visible_rect.left -= rect.left; + visible_rect.right -= rect.right; + visible_rect.top -= rect.top; + visible_rect.bottom -= rect.bottom; + if (visible_rect.top >= visible_rect.bottom) visible_rect.bottom = visible_rect.top + 1; + if (visible_rect.left >= visible_rect.right) visible_rect.right = visible_rect.left + 1; + + TRACE( "hwnd %p, window_rect %s, style %#x, ex_style %#x -> visible_rect %s\n", hwnd, + wine_dbgstr_rect( &window_rect ), style, ex_style, wine_dbgstr_rect( &visible_rect ) ); + return visible_rect; +} + + static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) { RECT virtual_rect = NtUserGetVirtualScreenRect(); @@ -1978,7 +2000,11 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, managed = is_window_managed( hwnd, swp_flags, style, ex_style, &rects->window, get_thread_dpi() ); set_window_managed( hwnd, managed );
- rects->visible = rects->window; + if (IsRectEmpty( &rects->window )) rects->visible = rects->window; + else if (EqualRect( &rects->window, &rects->client )) rects->visible = rects->window; + else if (shaped || !managed) rects->visible = rects->window; + else rects->visible = get_visible_rect( hwnd, rects->window, style, ex_style, get_thread_dpi() ); + if (!user_driver->pWindowPosChanging( hwnd, shaped, managed, rects )) needs_surface = FALSE; else if (parent && parent != NtUserGetDesktopWindow()) needs_surface = FALSE; else if (swp_flags & SWP_HIDEWINDOW) needs_surface = FALSE; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index f389da7279a..1b2b239171e 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -96,7 +96,7 @@ extern void ANDROID_SetParent( HWND hwnd, BOOL managed, HWND parent, HWND old_pa extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); 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, BOOL shaped, BOOL managed, struct window_rects *rects ); +extern BOOL ANDROID_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, 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, const struct window_rects *new_rects, struct window_surface *surface ); diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index dabae0354d8..8569952794a 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1032,7 +1032,7 @@ static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_r /*********************************************************************** * ANDROID_WindowPosChanging */ -BOOL ANDROID_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ) +BOOL ANDROID_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects ) { struct android_win_data *data = get_win_data( hwnd );
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 0505938a822..8492b0030c0 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -309,6 +309,7 @@ static const struct user_driver_funcs macdrv_funcs = .pMoveWindowBits = macdrv_MoveWindowBits, .pWindowPosChanged = macdrv_WindowPosChanged, .pWindowPosChanging = macdrv_WindowPosChanging, + .pGetWindowStyleMasks = macdrv_GetWindowStyleMasks, .pCreateWindowSurface = macdrv_CreateWindowSurface, .pVulkanInit = macdrv_VulkanInit, .pwine_get_wgl_driver = macdrv_wine_get_wgl_driver, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 49185e99507..bb1700d8ff1 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -147,7 +147,8 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern LRESULT macdrv_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam); extern void macdrv_UpdateLayeredWindow(HWND hwnd, UINT flags); extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); -extern BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects); +extern BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, 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_MoveWindowBits(HWND hwnd, const struct window_rects *new_rects, const RECT *valid_rects); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 7d100b01226..7004d535e2d 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -74,6 +74,35 @@ static void set_internal_window_pos(HWND hwnd, UINT cmd, RECT *rect, POINT *pt) }
+static struct macdrv_window_features get_window_features_for_style(DWORD style, DWORD ex_style, BOOL shaped) +{ + struct macdrv_window_features wf = {0}; + + if (ex_style & WS_EX_NOACTIVATE) wf.prevents_app_activation = TRUE; + + if ((style & WS_CAPTION) == WS_CAPTION && !(ex_style & WS_EX_LAYERED)) + { + wf.shadow = TRUE; + if (!shaped) + { + wf.title_bar = TRUE; + if (style & WS_SYSMENU) wf.close_button = TRUE; + if (style & WS_MINIMIZEBOX) wf.minimize_button = TRUE; + if (style & WS_MAXIMIZEBOX) wf.maximize_button = TRUE; + if (ex_style & WS_EX_TOOLWINDOW) wf.utility = TRUE; + } + } + if (style & WS_THICKFRAME) + { + wf.shadow = TRUE; + if (!shaped) wf.resizable = TRUE; + } + else if (ex_style & WS_EX_DLGMODALFRAME) wf.shadow = TRUE; + else if ((style & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) wf.shadow = TRUE; + + return wf; +} + /*********************************************************************** * get_cocoa_window_features */ @@ -91,25 +120,7 @@ static void get_cocoa_window_features(struct macdrv_win_data *data, if (IsRectEmpty(window_rect)) return; if (EqualRect(window_rect, client_rect)) return;
- if ((style & WS_CAPTION) == WS_CAPTION && !(ex_style & WS_EX_LAYERED)) - { - wf->shadow = TRUE; - if (!data->shaped) - { - wf->title_bar = TRUE; - if (style & WS_SYSMENU) wf->close_button = TRUE; - if (style & WS_MINIMIZEBOX) wf->minimize_button = TRUE; - if (style & WS_MAXIMIZEBOX) wf->maximize_button = TRUE; - if (ex_style & WS_EX_TOOLWINDOW) wf->utility = TRUE; - } - } - if (style & WS_THICKFRAME) - { - wf->shadow = TRUE; - if (!data->shaped) wf->resizable = TRUE; - } - else if (ex_style & WS_EX_DLGMODALFRAME) wf->shadow = TRUE; - else if ((style & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) wf->shadow = TRUE; + *wf = get_window_features_for_style(style, ex_style, data->shaped); }
@@ -1835,10 +1846,9 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) /*********************************************************************** * WindowPosChanging (MACDRV.@) */ -BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects) +BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects) { struct macdrv_win_data *data = get_win_data(hwnd); - DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); BOOL ret = FALSE;
TRACE("hwnd %p, shaped %u, managed %u, rects %s\n", hwnd, shaped, managed, debugstr_window_rects(rects)); @@ -1846,9 +1856,6 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct windo if (!data && !(data = macdrv_create_win_data(hwnd, &rects->window, &rects->client))) return FALSE; /* use default surface */ data->shaped = shaped;
- macdrv_window_to_mac_rect(data, style, &rects->visible, &rects->window, &rects->client); - TRACE("-> %s\n", debugstr_window_rects(rects)); - ret = !!data->cocoa_window; /* use default surface if we don't have a window */ release_win_data(data);
@@ -1885,6 +1892,28 @@ void macdrv_MoveWindowBits(HWND hwnd, const struct window_rects *new_rects, cons } }
+/*********************************************************************** + * GetWindowStyleMasks (X11DRV.@) + */ +BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask) +{ + struct macdrv_window_features wf = get_window_features_for_style(style, ex_style, FALSE); + + if (wf.title_bar) + { + *style_mask |= WS_CAPTION; + *ex_style_mask |= WS_EX_TOOLWINDOW; + } + if (wf.shadow) + { + *style_mask |= WS_DLGFRAME | WS_THICKFRAME; + *ex_style_mask |= WS_EX_DLGMODALFRAME; + } + + return TRUE; +} + + /*********************************************************************** * WindowPosChanged (MACDRV.@) */ diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 49bae8510fe..16b1b46eeac 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -357,7 +357,7 @@ UINT WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manage LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); -BOOL WAYLAND_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects); +BOOL WAYLAND_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects); BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 059343b8e8c..879a06bee4b 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -335,7 +335,7 @@ void WAYLAND_DestroyWindow(HWND hwnd) /*********************************************************************** * WAYLAND_WindowPosChanging */ -BOOL WAYLAND_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects) +BOOL WAYLAND_WindowPosChanging(HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects) { struct wayland_win_data *data = wayland_win_data_get(hwnd);
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 297a451f82b..6a7b6d7ea62 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -423,6 +423,7 @@ static const struct user_driver_funcs x11drv_funcs = .pUpdateLayeredWindow = X11DRV_UpdateLayeredWindow, .pWindowMessage = X11DRV_WindowMessage, .pWindowPosChanging = X11DRV_WindowPosChanging, + .pGetWindowStyleMasks = X11DRV_GetWindowStyleMasks, .pCreateWindowSurface = X11DRV_CreateWindowSurface, .pMoveWindowBits = X11DRV_MoveWindowBits, .pWindowPosChanged = X11DRV_WindowPosChanged, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index a397d2c297c..a2057198009 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -214,19 +214,12 @@ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD styl /*********************************************************************** * get_mwm_decorations */ -static unsigned long get_mwm_decorations( struct x11drv_win_data *data, - DWORD style, DWORD ex_style, - const RECT *window_rect, - const RECT *client_rect ) +static unsigned long get_mwm_decorations_for_style( DWORD style, DWORD ex_style ) { unsigned long ret = 0;
if (!decorated_mode) return 0;
- if (EqualRect( window_rect, client_rect )) return 0; - if (IsRectEmpty( window_rect )) return 0; - if (data->shaped) return 0; - if (ex_style & WS_EX_TOOLWINDOW) return 0; if (ex_style & WS_EX_LAYERED) return 0;
@@ -244,6 +237,24 @@ static unsigned long get_mwm_decorations( struct x11drv_win_data *data, }
+/*********************************************************************** + * get_mwm_decorations + */ +static unsigned long get_mwm_decorations( struct x11drv_win_data *data, + DWORD style, DWORD ex_style, + const RECT *window_rect, + const RECT *client_rect ) +{ + if (!decorated_mode) return 0; + + if (EqualRect( window_rect, client_rect )) return 0; + if (IsRectEmpty( window_rect )) return 0; + if (data->shaped) return 0; + + return get_mwm_decorations_for_style( style, ex_style ); +} + + /*********************************************************************** * get_window_attributes * @@ -1228,28 +1239,6 @@ static void get_decoration_rect( struct x11drv_win_data *data, RECT *rect, }
-/*********************************************************************** - * X11DRV_window_to_X_rect - * - * Convert a rect from client to X window coordinates - */ -static void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect, - const RECT *window_rect, const RECT *client_rect ) -{ - RECT rc; - - if (IsRectEmpty( rect )) return; - - get_decoration_rect( data, &rc, window_rect, client_rect ); - rect->left -= rc.left; - rect->right -= rc.right; - rect->top -= rc.top; - rect->bottom -= rc.bottom; - if (rect->top >= rect->bottom) rect->bottom = rect->top + 1; - if (rect->left >= rect->right) rect->right = rect->left + 1; -} - - /*********************************************************************** * X11DRV_X_to_window_rect * @@ -2460,7 +2449,7 @@ done: /*********************************************************************** * WindowPosChanging (X11DRV.@) */ -BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ) +BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects ) { struct x11drv_win_data *data = get_win_data( hwnd ); BOOL ret = FALSE; @@ -2480,9 +2469,6 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct wind data->managed = TRUE; }
- X11DRV_window_to_X_rect( data, &rects->visible, &rects->window, &rects->client ); - TRACE( "-> %s\n", debugstr_window_rects(rects) ); - ret = !!data->whole_window; /* use default surface if we don't have a window */ release_win_data( data );
@@ -2519,6 +2505,24 @@ void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *new_rects, con } }
+/*********************************************************************** + * GetWindowStyleMasks (X11DRV.@) + */ +BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ) +{ + unsigned long decor = get_mwm_decorations_for_style( style, ex_style ); + + if (decor & MWM_DECOR_TITLE) *style_mask |= WS_CAPTION; + if (decor & MWM_DECOR_BORDER) + { + *style_mask |= WS_DLGFRAME | WS_THICKFRAME; + *ex_style_mask |= WS_EX_DLGMODALFRAME; + } + + return TRUE; +} + + /*********************************************************************** * WindowPosChanged (X11DRV.@) */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 3a8563d9431..c94133a6425 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -242,7 +242,8 @@ extern LRESULT X11DRV_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARA extern void X11DRV_UpdateClipboard(void); extern void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); -extern BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, struct window_rects *rects ); +extern BOOL X11DRV_WindowPosChanging( HWND hwnd, BOOL shaped, BOOL managed, const struct window_rects *rects ); +extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ); 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 *new_rects, const RECT *valid_rects ); extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 14dd9ba868a..977187e437b 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -193,7 +193,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 94 +#define WINE_GDI_DRIVER_VERSION 95
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -358,7 +358,8 @@ struct user_driver_funcs LRESULT (*pSysCommand)(HWND,WPARAM,LPARAM); void (*pUpdateLayeredWindow)(HWND,UINT); LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); - BOOL (*pWindowPosChanging)(HWND,BOOL,BOOL,struct window_rects *); + BOOL (*pWindowPosChanging)(HWND,BOOL,BOOL,const struct window_rects *); + BOOL (*pGetWindowStyleMasks)(HWND,UINT,UINT,UINT*,UINT*); BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const RECT *); void (*pWindowPosChanged)(HWND,HWND,UINT,const struct window_rects*,struct window_surface*);
This merge request was approved by Huw Davies.
I'm not sure this make sense. 'managed' is a very X11-centric concept, essentially reflecting the override-redirect flag. I wouldn't expect other drivers to use the same heuristics, or even need that concept at all.
On Mon Aug 19 16:26:44 2024 +0000, Alexandre Julliard wrote:
I'm not sure this make sense. 'managed' is a very X11-centric concept, essentially reflecting the override-redirect flag. I wouldn't expect other drivers to use the same heuristics, or even need that concept at all.
Well, winewayland has introduced the same kind of thing and is about to use it for popups, tooltips and other overlay-like windows.
Maybe "managed" isn't the right term but I think it still represents a specific property of some windows: those are meant to be displayed either relatively to some top-level, or as overlays and are not meant to be moved around.
Then, drivers may or may not be able to respect that specific nature, but moving thins in win32u may make sense.
On Mon Aug 19 16:27:09 2024 +0000, Rémi Bernon wrote:
Well, winewayland has introduced the same kind of thing and is about to use it for popups, tooltips and other overlay-like windows. Maybe "managed" isn't the right term but I think it still represents a specific property of some windows: those are meant to be displayed either relatively to some top-level, or as overlays and are not meant to be moved around. Then, drivers may or may not be able to respect that specific nature, but moving thins in win32u may make sense.
Then the main reason to move it is also that it makes the other commit possible, and later changes easier: computing the visible rect in win32u let us do that in window DPI, while later convert all rects at once to monitor DPI and call the driver with them.
Otherwise it gets a bit awkward where we would pass monitor DPI rects to WindowPosChanging, return a monitor DPI visible rect to convert back, or pass both window DPI and monitor DPI rects, though without the visible rect set yet, and return a window DPI visible rect.
On Mon Aug 19 16:36:14 2024 +0000, Rémi Bernon wrote:
Then the main reason to move it is also that it makes the other commit possible, and later changes easier: computing the visible rect in win32u let us do that in window DPI, while later convert all rects at once to monitor DPI and call the driver with them. Otherwise it gets a bit awkward where we would pass monitor DPI rects to WindowPosChanging, return a monitor DPI visible rect to convert back, or pass both window DPI and monitor DPI rects, though without the visible rect set yet, and return a window DPI visible rect.
Yes, computing the visible rect in win32u make sense, and doing that using driver-specified style masks is the right thing to do. But whether or not there's a managed flag, and what impact it has on the host decorations, should be decided by the driver IMO.
This merge request was closed by Rémi Bernon.
The visible rect computation is included in https://gitlab.winehq.org/wine/wine/-/merge_requests/6310.