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*);