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.
This is done after WindowPosChanging, as winex11 needs to update its managed flag before computing the visible rect, this means that the visible rect might change between WindowPosChanging and WindowPosChanged. It should hopefully be fine.
-- v2: winex11: Use the driver rects to convert from host visible to window rect. winex11: Keep a window_rects struct in the driver window data. win32u: Move visible rect computation out of the drivers. win32u: Keep SetIMECompositionWindowPos with other IME entries.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 20 ++++++++++++-------- dlls/winex11.drv/init.c | 2 +- dlls/winex11.drv/x11drv.h | 2 +- include/wine/gdi_driver.h | 5 ++--- 4 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 87b2971216d..c56bf89d069 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -686,6 +686,11 @@ static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status ) { }
+static BOOL nulldrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +{ + return FALSE; +} + static LRESULT nulldrv_DesktopWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { return default_window_proc( hwnd, msg, wparam, lparam, FALSE ); @@ -914,11 +919,6 @@ static void nulldrv_ThreadDetach( void ) { }
-static BOOL nulldrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) -{ - return FALSE; -} - static const WCHAR guid_key_prefixW[] = { '\','R','e','g','i','s','t','r','y', @@ -1099,6 +1099,11 @@ static void loaderdrv_NotifyIMEStatus( HWND hwnd, UINT status ) return load_driver()->pNotifyIMEStatus( hwnd, status ); }
+static BOOL loaderdrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +{ + return load_driver()->pSetIMECompositionWindowPos( hwnd, point ); +} + static LONG loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lparam ) { @@ -1243,6 +1248,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_ReleaseKbdTables, loaderdrv_ImeProcessKey, loaderdrv_NotifyIMEStatus, + loaderdrv_SetIMECompositionWindowPos, /* cursor/icon functions */ nulldrv_DestroyCursorIcon, loaderdrv_SetCursor, @@ -1299,8 +1305,6 @@ static const struct user_driver_funcs lazy_load_driver = nulldrv_wine_get_wgl_driver, /* thread management */ nulldrv_ThreadDetach, - /* IME support */ - nulldrv_SetIMECompositionWindowPos, };
const struct user_driver_funcs *user_driver = &lazy_load_driver; @@ -1338,6 +1342,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(ReleaseKbdTables); SET_USER_FUNC(ImeProcessKey); SET_USER_FUNC(NotifyIMEStatus); + SET_USER_FUNC(SetIMECompositionWindowPos); SET_USER_FUNC(DestroyCursorIcon); SET_USER_FUNC(SetCursor); SET_USER_FUNC(GetCursorPos); @@ -1385,7 +1390,6 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(VulkanInit); SET_USER_FUNC(wine_get_wgl_driver); SET_USER_FUNC(ThreadDetach); - SET_USER_FUNC(SetIMECompositionWindowPos); #undef SET_USER_FUNC
prev = InterlockedCompareExchangePointer( (void **)&user_driver, driver, (void *)&lazy_load_driver ); diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 3b919335624..1fa07d38e13 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -385,6 +385,7 @@ static const struct user_driver_funcs x11drv_funcs = .pToUnicodeEx = X11DRV_ToUnicodeEx, .pVkKeyScanEx = X11DRV_VkKeyScanEx, .pNotifyIMEStatus = X11DRV_NotifyIMEStatus, + .pSetIMECompositionWindowPos = X11DRV_SetIMECompositionWindowPos, .pDestroyCursorIcon = X11DRV_DestroyCursorIcon, .pSetCursor = X11DRV_SetCursor, .pGetCursorPos = X11DRV_GetCursorPos, @@ -430,7 +431,6 @@ static const struct user_driver_funcs x11drv_funcs = .pVulkanInit = X11DRV_VulkanInit, .pwine_get_wgl_driver = X11DRV_wine_get_wgl_driver, .pThreadDetach = X11DRV_ThreadDetach, - .pSetIMECompositionWindowPos = X11DRV_SetIMECompositionWindowPos, };
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 72527c7b92d..e75e3d7c70a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -205,6 +205,7 @@ extern INT X11DRV_ToUnicodeEx( UINT virtKey, UINT scanCode, const BYTE *lpKeySta LPWSTR bufW, int bufW_size, UINT flags, HKL hkl ); extern SHORT X11DRV_VkKeyScanEx( WCHAR wChar, HKL hkl ); extern void X11DRV_NotifyIMEStatus( HWND hwnd, UINT status ); +extern BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ); extern void X11DRV_DestroyCursorIcon( HCURSOR handle ); extern void X11DRV_SetCursor( HWND hwnd, HCURSOR handle ); extern BOOL X11DRV_SetCursorPos( INT x, INT y ); @@ -250,7 +251,6 @@ extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flag extern BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags ); extern void X11DRV_ThreadDetach(void); -extern BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point );
/* X11 driver internal functions */
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 7fe492f4776..a2497a39d7b 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 94 +#define WINE_GDI_DRIVER_VERSION 95
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -340,6 +340,7 @@ struct user_driver_funcs /* IME functions */ UINT (*pImeProcessKey)(HIMC,UINT,UINT,const BYTE*); void (*pNotifyIMEStatus)(HWND,UINT); + BOOL (*pSetIMECompositionWindowPos)(HWND, const POINT *); /* cursor/icon functions */ void (*pDestroyCursorIcon)(HCURSOR); void (*pSetCursor)(HWND,HCURSOR); @@ -396,8 +397,6 @@ struct user_driver_funcs struct opengl_funcs * (*pwine_get_wgl_driver)(UINT); /* thread management */ void (*pThreadDetach)(void); - /* IME support */ - BOOL (*pSetIMECompositionWindowPos)(HWND, const POINT *); };
W32KAPI void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version );
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 | 31 +++++++++++- 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 | 79 ++++++++++++++++++------------- dlls/winex11.drv/x11drv.h | 3 +- include/wine/gdi_driver.h | 5 +- 13 files changed, 149 insertions(+), 68 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index c56bf89d069..3e094264d15 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -881,11 +881,16 @@ 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, UINT swp_flags, BOOL shaped, 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; @@ -1294,6 +1299,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_UpdateLayeredWindow, nulldrv_WindowMessage, nulldrv_WindowPosChanging, + nulldrv_GetWindowStyleMasks, nulldrv_CreateWindowSurface, nulldrv_MoveWindowBits, nulldrv_WindowPosChanged, @@ -1383,6 +1389,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 7ad3e1d50ff..18ee91648ce 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1818,6 +1818,28 @@ done: }
+static RECT get_visible_rect( HWND hwnd, UINT style, UINT ex_style, RECT window_rect, 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(); @@ -1874,9 +1896,13 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, BOOL shaped, 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 );
@@ -1885,7 +1911,10 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, 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 (!IsRectEmpty( &rects->window ) && !EqualRect( &rects->window, &rects->client ) && !shaped) + rects->visible = get_visible_rect( hwnd, style, ex_style, rects->window, get_thread_dpi() );
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 f438deb714e..850b235f3a1 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -95,7 +95,7 @@ extern void ANDROID_SetParent( HWND hwnd, 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, 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, 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 8018ee1a567..537aae456e7 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1023,7 +1023,7 @@ static struct android_win_data *create_win_data( HWND hwnd, const struct window_ /*********************************************************************** * ANDROID_WindowPosChanging */ -BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, 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 b417c0e2344..6e506514164 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, UINT swp_flags, BOOL shaped, struct window_rects *rects); +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_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 d3959a005f8..bb11ae12ffa 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); }
@@ -1804,10 +1815,9 @@ 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, UINT swp_flags, BOOL shaped, 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, swp_flags %04x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects(rects)); @@ -1815,9 +1825,6 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct win if (!data && !(data = macdrv_create_win_data(hwnd, rects))) 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);
@@ -1854,6 +1861,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 4e3841d8cf9..40f86526cd2 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -355,7 +355,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, 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); 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 355894f6137..73a8de37f77 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -425,7 +425,7 @@ 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, UINT swp_flags, BOOL shaped, 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 1fa07d38e13..fa477a4de6b 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -424,6 +424,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 6e834457620..c7c785d2510 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -303,19 +303,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;
@@ -333,6 +326,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 * @@ -1337,28 +1348,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 * @@ -2569,7 +2558,7 @@ done: /*********************************************************************** * WindowPosChanging (X11DRV.@) */ -BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ) { struct x11drv_win_data *data = get_win_data( hwnd ); BOOL ret = FALSE; @@ -2589,9 +2578,6 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct wi 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 );
@@ -2628,6 +2614,31 @@ 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 ); + struct x11drv_win_data *data; + + if ((data = get_win_data( hwnd ))) + { + if (!data->managed) decor = 0; + release_win_data( data ); + } + + 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 e75e3d7c70a..c0cf020067e 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -243,7 +243,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, UINT swp_flags, BOOL shaped, struct window_rects *rects ); +extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, 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 a2497a39d7b..fee065af71b 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 95 +#define WINE_GDI_DRIVER_VERSION 96
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -385,7 +385,8 @@ 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,UINT,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*);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 40 +++++----- dlls/winex11.drv/mouse.c | 6 +- dlls/winex11.drv/window.c | 157 ++++++++++++++++++-------------------- dlls/winex11.drv/x11drv.h | 4 +- dlls/winex11.drv/xim.c | 6 +- 5 files changed, 101 insertions(+), 112 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 635025aff97..ca9ab4b8aed 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -896,13 +896,13 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev ) rect.bottom = pos.y + event->height;
if (event->window != data->client_window) - OffsetRect( &rect, data->whole_rect.left - data->client_rect.left, - data->whole_rect.top - data->client_rect.top ); + OffsetRect( &rect, data->rects.visible.left - data->rects.client.left, + data->rects.visible.top - data->rects.client.top );
if (event->window != root_window) { if (NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - mirror_rect( &data->client_rect, &rect ); + mirror_rect( &data->rects.client, &rect ); abs_rect = rect; NtUserMapWindowPoints( hwnd, 0, (POINT *)&abs_rect, 2, 0 /* per-monitor DPI */ );
@@ -1091,22 +1091,22 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */
- if (data->window_rect.left == x && data->window_rect.top == y) flags |= SWP_NOMOVE; + if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE; else TRACE( "%p moving from (%d,%d) to (%d,%d)\n", - hwnd, (int)data->window_rect.left, (int)data->window_rect.top, x, y ); + hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y );
- if ((data->window_rect.right - data->window_rect.left == cx && - data->window_rect.bottom - data->window_rect.top == cy) || - IsRectEmpty( &data->window_rect )) + if ((data->rects.window.right - data->rects.window.left == cx && + data->rects.window.bottom - data->rects.window.top == cy) || + IsRectEmpty( &data->rects.window )) flags |= SWP_NOSIZE; else TRACE( "%p resizing from (%dx%d) to (%dx%d)\n", - hwnd, (int)(data->window_rect.right - data->window_rect.left), - (int)(data->window_rect.bottom - data->window_rect.top), cx, cy ); + hwnd, (int)(data->rects.window.right - data->rects.window.left), + (int)(data->rects.window.bottom - data->rects.window.top), cx, cy );
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - if ((style & WS_CAPTION) == WS_CAPTION || !NtUserIsWindowRectFullScreen( &data->whole_rect, dpi )) + if ((style & WS_CAPTION) == WS_CAPTION || !NtUserIsWindowRectFullScreen( &data->rects.visible, dpi )) { read_net_wm_states( event->display, data ); if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) @@ -1159,13 +1159,13 @@ static BOOL X11DRV_GravityNotify( HWND hwnd, XEvent *xev ) return FALSE; }
- x = event->x + data->window_rect.left - data->whole_rect.left; - y = event->y + data->window_rect.top - data->whole_rect.top; + x = event->x + data->rects.window.left - data->rects.visible.left; + y = event->y + data->rects.window.top - data->rects.visible.top;
TRACE( "win %p/%lx new X pos %d,%d (event %d,%d)\n", hwnd, data->whole_window, x, y, event->x, event->y );
- window_rect = data->window_rect; + window_rect = data->rects.window; release_win_data( data );
if (window_rect.left != x || window_rect.top != y) @@ -1448,8 +1448,8 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) Window win, w_aux_root, w_aux_child;
if (!(data = get_win_data( hWnd ))) return; - cx = data->whole_rect.right - data->whole_rect.left; - cy = data->whole_rect.bottom - data->whole_rect.top; + cx = data->rects.visible.right - data->rects.visible.left; + cy = data->rects.visible.bottom - data->rects.visible.top; win = data->whole_window; release_win_data( data );
@@ -1537,10 +1537,10 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) if ((win_data = get_win_data( hWnd ))) { drop->fNC = - (drop->pt.x < (win_data->client_rect.left - win_data->whole_rect.left) || - drop->pt.y < (win_data->client_rect.top - win_data->whole_rect.top) || - drop->pt.x > (win_data->client_rect.right - win_data->whole_rect.left) || - drop->pt.y > (win_data->client_rect.bottom - win_data->whole_rect.top) ); + (drop->pt.x < (win_data->rects.client.left - win_data->rects.visible.left) || + drop->pt.y < (win_data->rects.client.top - win_data->rects.visible.top) || + drop->pt.x > (win_data->rects.client.right - win_data->rects.visible.left) || + drop->pt.y > (win_data->rects.client.bottom - win_data->rects.visible.top) ); release_win_data( win_data ); }
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 30444de0cdf..ee0191630f7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -513,12 +513,12 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x { if (window == data->whole_window) { - pt.x += data->whole_rect.left - data->client_rect.left; - pt.y += data->whole_rect.top - data->client_rect.top; + pt.x += data->rects.visible.left - data->rects.client.left; + pt.y += data->rects.visible.top - data->rects.client.top; }
if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x; + pt.x = data->rects.client.right - data->rects.client.left - 1 - pt.x; NtUserMapWindowPoints( hwnd, 0, &pt, 1, 0 /* per-monitor DPI */ ); } release_win_data( data ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index c7c785d2510..6b0329418cf 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -297,7 +297,7 @@ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD styl { if (style & WS_THICKFRAME) return TRUE; /* Metacity needs the window to be resizable to make it fullscreen */ - return NtUserIsWindowRectFullScreen( &data->whole_rect, get_win_monitor_dpi( data->hwnd ) ); + return NtUserIsWindowRectFullScreen( &data->rects.visible, get_win_monitor_dpi( data->hwnd ) ); }
/*********************************************************************** @@ -388,7 +388,7 @@ static void sync_window_style( struct x11drv_win_data *data ) static void sync_empty_window_shape( struct x11drv_win_data *data, struct window_surface *surface ) { #ifdef HAVE_LIBXSHAPE - if (IsRectEmpty( &data->window_rect )) /* set an empty shape */ + if (IsRectEmpty( &data->rects.window )) /* set an empty shape */ { static XRectangle empty_rect; XShapeCombineRectangles( data->display, data->whole_window, ShapeBounding, 0, 0, @@ -440,8 +440,8 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region ) if ((pRegionData = X11DRV_GetRegionData( hrgn, 0 ))) { XShapeCombineRectangles( data->display, data->whole_window, ShapeBounding, - data->window_rect.left - data->whole_rect.left, - data->window_rect.top - data->whole_rect.top, + data->rects.window.left - data->rects.visible.left, + data->rects.window.top - data->rects.visible.top, (XRectangle *)pRegionData->Buffer, pRegionData->rdh.nCount, ShapeSet, YXBanded ); free( pRegionData ); @@ -745,7 +745,7 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style ) { if (data->hwnd != NtUserGetDesktopWindow()) /* don't force position of desktop */ { - POINT pt = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + POINT pt = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); size_hints->x = pt.x; size_hints->y = pt.y; size_hints->flags |= PPosition; @@ -754,8 +754,8 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style )
if (!is_window_resizable( data, style )) { - size_hints->max_width = data->whole_rect.right - data->whole_rect.left; - size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top; + size_hints->max_width = data->rects.visible.right - data->rects.visible.left; + size_hints->max_height = data->rects.visible.bottom - data->rects.visible.top; if (size_hints->max_width <= 0 ||size_hints->max_height <= 0) size_hints->max_width = size_hints->max_height = 1; size_hints->min_width = size_hints->max_width; @@ -787,7 +787,7 @@ static void set_mwm_hints( struct x11drv_win_data *data, UINT style, UINT ex_sty } else { - mwm_hints.decorations = get_mwm_decorations( data, style, ex_style, &data->window_rect, &data->client_rect ); + mwm_hints.decorations = get_mwm_decorations( data, style, ex_style, &data->rects.window, &data->rects.client ); mwm_hints.functions = MWM_FUNC_MOVE; if (is_window_resizable( data, style )) mwm_hints.functions |= MWM_FUNC_RESIZE; if (!(style & WS_DISABLED)) @@ -1053,7 +1053,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) if (!X11DRV_DisplayDevices_SupportEventHandlers()) return;
- if (!xinerama_get_fullscreen_monitors( &data->whole_rect, monitors )) + if (!xinerama_get_fullscreen_monitors( &data->rects.visible, monitors )) return;
/* If _NET_WM_FULLSCREEN_MONITORS is not set and the fullscreen monitors are spanning only one @@ -1109,7 +1109,7 @@ void update_net_wm_states( struct x11drv_win_data *data ) style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); if (style & WS_MINIMIZE) new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); - if (NtUserIsWindowRectFullScreen( &data->whole_rect, get_win_monitor_dpi( data->hwnd ) )) + if (NtUserIsWindowRectFullScreen( &data->rects.visible, get_win_monitor_dpi( data->hwnd ) )) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) new_state |= (1 << NET_WM_STATE_MAXIMIZED); @@ -1357,14 +1357,14 @@ void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, i { RECT rc;
- get_decoration_rect( data, &rc, &data->window_rect, &data->client_rect ); + get_decoration_rect( data, &rc, &data->rects.window, &data->rects.client );
- x += min( data->window_rect.left - data->whole_rect.left, rc.left ); - y += min( data->window_rect.top - data->whole_rect.top, rc.top ); - cx += max( (data->window_rect.right - data->window_rect.left) - - (data->whole_rect.right - data->whole_rect.left), rc.right - rc.left ); - cy += max( (data->window_rect.bottom - data->window_rect.top) - - (data->whole_rect.bottom - data->whole_rect.top), rc.bottom - rc.top ); + x += min( data->rects.window.left - data->rects.visible.left, rc.left ); + y += min( data->rects.window.top - data->rects.visible.top, rc.top ); + cx += max( (data->rects.window.right - data->rects.window.left) - + (data->rects.visible.right - data->rects.visible.left), rc.right - rc.left ); + cy += max( (data->rects.window.bottom - data->rects.window.top) - + (data->rects.visible.bottom - data->rects.visible.top), rc.bottom - rc.top ); SetRect( rect, x, y, x + cx, y + cy ); }
@@ -1374,9 +1374,7 @@ void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, i * * Synchronize the X window position with the Windows one */ -static void sync_window_position( struct x11drv_win_data *data, - UINT swp_flags, const RECT *old_window_rect, - const RECT *old_whole_rect, const RECT *old_client_rect ) +static void sync_window_position( struct x11drv_win_data *data, UINT swp_flags ) { DWORD style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); DWORD ex_style = NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ); @@ -1388,8 +1386,8 @@ static void sync_window_position( struct x11drv_win_data *data, /* resizing a managed maximized window is not allowed */ if (!(style & WS_MAXIMIZE) || !data->managed) { - changes.width = data->whole_rect.right - data->whole_rect.left; - changes.height = data->whole_rect.bottom - data->whole_rect.top; + changes.width = data->rects.visible.right - data->rects.visible.left; + changes.height = data->rects.visible.bottom - data->rects.visible.top; /* if window rect is empty force size to 1x1 */ if (changes.width <= 0 || changes.height <= 0) changes.width = changes.height = 1; if (changes.width > 65535) changes.width = 65535; @@ -1400,7 +1398,7 @@ static void sync_window_position( struct x11drv_win_data *data, /* only the size is allowed to change for the desktop window or systray docked windows */ if (data->whole_window != root_window && !data->embedded) { - POINT pt = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + POINT pt = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); changes.x = pt.x; changes.y = pt.y; mask |= CWX | CWY; @@ -1428,9 +1426,9 @@ static void sync_window_position( struct x11drv_win_data *data, XReconfigureWMWindow( data->display, data->whole_window, data->vis.screen, mask, &changes );
TRACE( "win %p/%lx pos %d,%d,%dx%d after %lx changes=%x serial=%lu\n", - data->hwnd, data->whole_window, (int)data->whole_rect.left, (int)data->whole_rect.top, - (int)(data->whole_rect.right - data->whole_rect.left), - (int)(data->whole_rect.bottom - data->whole_rect.top), + data->hwnd, data->whole_window, (int)data->rects.visible.left, (int)data->rects.visible.top, + (int)(data->rects.visible.right - data->rects.visible.left), + (int)(data->rects.visible.bottom - data->rects.visible.top), changes.sibling, mask, data->configure_serial ); }
@@ -1440,23 +1438,22 @@ static void sync_window_position( struct x11drv_win_data *data, * * Synchronize the X client window position with the Windows one */ -static void sync_client_position( struct x11drv_win_data *data, - const RECT *old_client_rect, const RECT *old_whole_rect ) +static void sync_client_position( struct x11drv_win_data *data, const struct window_rects *old_rects ) { int mask = 0; XWindowChanges changes;
if (!data->client_window) return;
- changes.x = data->client_rect.left - data->whole_rect.left; - changes.y = data->client_rect.top - data->whole_rect.top; - changes.width = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + changes.x = data->rects.client.left - data->rects.visible.left; + changes.y = data->rects.client.top - data->rects.visible.top; + changes.width = min( max( 1, data->rects.client.right - data->rects.client.left ), 65535 ); + changes.height = min( max( 1, data->rects.client.bottom - data->rects.client.top ), 65535 );
- if (changes.x != old_client_rect->left - old_whole_rect->left) mask |= CWX; - if (changes.y != old_client_rect->top - old_whole_rect->top) mask |= CWY; - if (changes.width != old_client_rect->right - old_client_rect->left) mask |= CWWidth; - if (changes.height != old_client_rect->bottom - old_client_rect->top) mask |= CWHeight; + if (changes.x != old_rects->client.left - old_rects->visible.left) mask |= CWX; + if (changes.y != old_rects->client.top - old_rects->visible.top) mask |= CWY; + if (changes.width != old_rects->client.right - old_rects->client.left) mask |= CWWidth; + if (changes.height != old_rects->client.bottom - old_rects->client.top) mask |= CWHeight;
if (mask) { @@ -1625,8 +1622,8 @@ static void attach_client_window( struct x11drv_win_data *data, Window client_wi if (data->whole_window) { client_window_events_enable( data, client_window ); - XReparentWindow( gdi_display, client_window, data->whole_window, data->client_rect.left - data->whole_rect.left, - data->client_rect.top - data->whole_rect.top ); + XReparentWindow( gdi_display, client_window, data->whole_window, data->rects.client.left - data->rects.visible.left, + data->rects.client.top - data->rects.visible.top ); }
data->client_window = client_window; @@ -1673,8 +1670,8 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colo HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); if (parent == NtUserGetDesktopWindow() || NtUserGetAncestor( parent, GA_PARENT )) return 0; if (!(data = alloc_win_data( thread_init_display(), hwnd ))) return 0; - NtUserGetClientRect( hwnd, &data->client_rect, get_win_monitor_dpi( hwnd ) ); - data->window_rect = data->whole_rect = data->client_rect; + NtUserGetClientRect( hwnd, &data->rects.client, get_win_monitor_dpi( hwnd ) ); + data->rects.window = data->rects.visible = data->rects.client; }
detach_client_window( data, data->client_window ); @@ -1685,10 +1682,10 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colo attr.backing_store = NotUseful; attr.border_pixel = 0;
- x = data->client_rect.left - data->whole_rect.left; - y = data->client_rect.top - data->whole_rect.top; - cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + x = data->rects.client.left - data->rects.visible.left; + y = data->rects.client.top - data->rects.visible.top; + cx = min( max( 1, data->rects.client.right - data->rects.client.left ), 65535 ); + cy = min( max( 1, data->rects.client.bottom - data->rects.client.top ), 65535 );
XSync( gdi_display, False ); /* make sure whole_window is known from gdi_display */ ret = data->client_window = XCreateWindow( gdi_display, @@ -1727,7 +1724,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->rects.window )) { TRACE( "making win %p/%lx managed\n", data->hwnd, data->whole_window ); data->managed = TRUE; @@ -1746,12 +1743,12 @@ static void create_whole_window( struct x11drv_win_data *data )
mask = get_window_attributes( data, &attr );
- if (!(cx = data->whole_rect.right - data->whole_rect.left)) cx = 1; + if (!(cx = data->rects.visible.right - data->rects.visible.left)) cx = 1; else if (cx > 65535) cx = 65535; - if (!(cy = data->whole_rect.bottom - data->whole_rect.top)) cy = 1; + if (!(cy = data->rects.visible.bottom - data->rects.visible.top)) cy = 1; else if (cy > 65535) cy = 65535;
- pos = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + pos = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); data->whole_window = XCreateWindow( data->display, root_window, pos.x, pos.y, cx, cy, 0, data->vis.depth, InputOutput, data->vis.visual, mask, &attr ); @@ -1769,7 +1766,7 @@ static void create_whole_window( struct x11drv_win_data *data ) sync_window_text( data->display, data->whole_window, text );
/* set the window region */ - if (IsRectEmpty( &data->window_rect )) sync_empty_window_shape( data, NULL ); + if (IsRectEmpty( &data->rects.window )) sync_empty_window_shape( data, NULL ); else if (win_rgn) sync_window_region( data, win_rgn );
/* set the window opacity */ @@ -2108,8 +2105,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, - const RECT *client_rect ) +static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const struct window_rects *rects ) { Display *display; struct x11drv_win_data *data; @@ -2131,15 +2127,14 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *wi init_clip_window(); /* make sure the clip window is initialized in this thread */
if (!(data = alloc_win_data( display, hwnd ))) return NULL; + data->rects = *rects;
- data->whole_rect = data->window_rect = *window_rect; - data->client_rect = *client_rect; if (parent == NtUserGetDesktopWindow()) { create_whole_window( data ); 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 )); + hwnd, data->whole_window, wine_dbgstr_rect( &data->rects.window ), + wine_dbgstr_rect( &data->rects.visible ), wine_dbgstr_rect( &data->rects.client )); } return data; } @@ -2223,7 +2218,7 @@ HWND create_foreign_window( Display *display, Window xwin ) XSaveContext( display, xwin, winContext, (char *)data->hwnd );
TRACE( "win %lx parent %p style %08x %s -> hwnd %p\n", - xwin, parent, style, wine_dbgstr_rect(&data->window_rect), hwnd ); + xwin, parent, style, wine_dbgstr_rect(&data->rects.window), hwnd );
release_win_data( data );
@@ -2565,7 +2560,7 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const str
TRACE( "hwnd %p, swp_flags %#x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, 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, rects ))) return FALSE; /* use default surface */ data->shaped = shaped;
/* check if we need to switch the window to managed */ @@ -2594,8 +2589,8 @@ void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *new_rects, con Window window;
if (!(data = get_win_data( hwnd ))) return; - old_visible_rect = data->whole_rect; - old_client_rect = data->client_rect; + old_visible_rect = data->rects.visible; + old_client_rect = data->rects.client; window = data->whole_window; release_win_data( data );
@@ -2648,34 +2643,30 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, cons struct x11drv_thread_data *thread_data; struct x11drv_win_data *data; UINT new_style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); - RECT old_window_rect, old_whole_rect, old_client_rect; + struct window_rects old_rects; int event_type;
if (!(data = get_win_data( hwnd ))) return;
thread_data = x11drv_thread_data();
- old_window_rect = data->window_rect; - old_whole_rect = data->whole_rect; - old_client_rect = data->client_rect; - data->window_rect = new_rects->window; - data->whole_rect = new_rects->visible; - data->client_rect = new_rects->client; + old_rects = data->rects; + data->rects = *new_rects;
TRACE( "win %p/%lx new_rects %s style %08x flags %08x\n", hwnd, data->whole_window, debugstr_window_rects(new_rects), new_style, swp_flags );
XFlush( gdi_display ); /* make sure painting is done before we move the window */
- sync_client_position( data, &old_client_rect, &old_whole_rect ); + sync_client_position( data, &old_rects );
if (!data->whole_window) { BOOL needs_resize = (!data->client_window && - (data->client_rect.right - data->client_rect.left != - old_client_rect.right - old_client_rect.left || - data->client_rect.bottom - data->client_rect.top != - old_client_rect.bottom - old_client_rect.top)); + (data->rects.client.right - data->rects.client.left != + old_rects.client.right - old_rects.client.left || + data->rects.client.bottom - data->rects.client.top != + old_rects.client.bottom - old_rects.client.top)); release_win_data( data ); if (needs_resize) sync_gl_drawable( hwnd, FALSE ); return; @@ -2697,11 +2688,11 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, cons { if (((swp_flags & SWP_HIDEWINDOW) && !(new_style & WS_VISIBLE)) || (!event_type && !(new_style & WS_MINIMIZE) && - !is_window_rect_mapped( &new_rects->window ) && is_window_rect_mapped( &old_window_rect ))) + !is_window_rect_mapped( &new_rects->window ) && is_window_rect_mapped( &old_rects.window ))) { release_win_data( data ); unmap_window( hwnd ); - if (NtUserIsWindowRectFullScreen( &old_window_rect, get_win_monitor_dpi( hwnd ) )) + if (NtUserIsWindowRectFullScreen( &old_rects.window, get_win_monitor_dpi( hwnd ) )) NtUserClipCursor( NULL ); if (!(data = get_win_data( hwnd ))) return; } @@ -2711,16 +2702,16 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, cons if (!event_type && !(data->managed && (swp_flags & SWP_STATECHANGED) && (new_style & (WS_MINIMIZE|WS_MAXIMIZE)))) { - sync_window_position( data, swp_flags, &old_window_rect, &old_whole_rect, &old_client_rect ); + sync_window_position( data, swp_flags ); #ifdef HAVE_LIBXSHAPE - if (IsRectEmpty( &old_window_rect ) != IsRectEmpty( &data->window_rect )) + if (IsRectEmpty( &old_rects.window ) != IsRectEmpty( &new_rects->window )) sync_empty_window_shape( data, surface ); if (data->shaped) { - int old_x_offset = old_window_rect.left - old_whole_rect.left; - int old_y_offset = old_window_rect.top - old_whole_rect.top; - int new_x_offset = data->window_rect.left - data->whole_rect.left; - int new_y_offset = data->window_rect.top - data->whole_rect.top; + int old_x_offset = old_rects.window.left - old_rects.visible.left; + int old_y_offset = old_rects.window.top - old_rects.visible.top; + int new_x_offset = new_rects->window.left - new_rects->visible.left; + int new_y_offset = new_rects->window.top - new_rects->visible.top; if (old_x_offset != new_x_offset || old_y_offset != new_y_offset) XShapeOffsetShape( data->display, data->whole_window, ShapeBounding, new_x_offset - old_x_offset, new_y_offset - old_y_offset ); @@ -2896,7 +2887,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO DWORD style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
if ((style & WS_VISIBLE) && - ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->window_rect ))) + ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->rects.window ))) { release_win_data( data ); map_window( hwnd, style ); @@ -2935,7 +2926,7 @@ void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ) { DWORD style = NtUserGetWindowLongW( hwnd, GWL_STYLE );
- if ((style & WS_VISIBLE) && ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->window_rect ))) + if ((style & WS_VISIBLE) && ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->rects.window ))) map_window( hwnd, style ); } } @@ -3002,8 +2993,8 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) if (data->whole_window) { /* sync window position with the new virtual screen rect */ - POINT old_pos = {.x = data->whole_rect.left - wp, .y = data->whole_rect.top - lp}; - POINT pos = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + POINT old_pos = {.x = data->rects.visible.left - wp, .y = data->rects.visible.top - lp}; + POINT pos = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); XWindowChanges changes = {.x = pos.x, .y = pos.y}; UINT mask = 0;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c0cf020067e..947eb1a10e3 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -600,9 +600,7 @@ struct x11drv_win_data HWND hwnd; /* hwnd that this private data belongs to */ Window whole_window; /* X window for the complete window */ Window client_window; /* X window for the client area */ - RECT window_rect; /* USER window rectangle relative to win32 parent window client area */ - RECT whole_rect; /* X window rectangle for the whole window relative to win32 parent window client area */ - RECT client_rect; /* client area relative to win32 parent window client area */ + struct window_rects rects; /* window rects in monitor DPI, relative to parent client area */ XIC xic; /* X input context */ UINT managed : 1; /* is window managed? */ UINT mapped : 1; /* is window mapped? (in either normal or iconic state) */ diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 1bb20c845f3..732a55a978a 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -507,10 +507,10 @@ BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point )
pt = *point; if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x; + pt.x = data->rects.client.right - data->rects.client.left - 1 - pt.x;
- xpoint.x = pt.x + data->client_rect.left - data->whole_rect.left; - xpoint.y = pt.y + data->client_rect.top - data->whole_rect.top; + xpoint.x = pt.x + data->rects.client.left - data->rects.visible.left; + xpoint.y = pt.y + data->rects.client.top - data->rects.visible.top; attr = XVaCreateNestedList( 0, XNSpotLocation, &xpoint, NULL ); if (attr) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 3 ++- dlls/winex11.drv/window.c | 53 ++------------------------------------- dlls/winex11.drv/x11drv.h | 1 - 3 files changed, 4 insertions(+), 53 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index ca9ab4b8aed..e7cc3855c2d 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1073,7 +1073,8 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) } else pos = root_to_virtual_screen( x, y );
- X11DRV_X_to_window_rect( data, &rect, pos.x, pos.y, event->width, event->height ); + SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height ); + rect = window_rect_from_visible( &data->rects, rect ); if (root_coords) NtUserMapWindowPoints( 0, parent, (POINT *)&rect, 2, 0 /* per-monitor DPI */ );
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n", diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 6b0329418cf..82c6a372530 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1319,56 +1319,6 @@ void make_window_embedded( struct x11drv_win_data *data ) }
-/*********************************************************************** - * get_decoration_rect - */ -static void get_decoration_rect( struct x11drv_win_data *data, RECT *rect, - const RECT *window_rect, const RECT *client_rect ) -{ - DWORD style, ex_style, style_mask = 0, ex_style_mask = 0; - unsigned long decor; - UINT dpi; - - SetRectEmpty( rect ); - if (!data->managed) return; - - dpi = get_win_monitor_dpi( data->hwnd ); - style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - ex_style = NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ); - decor = get_mwm_decorations( data, style, ex_style, window_rect, client_rect ); - - 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; - } - - NtUserAdjustWindowRect( rect, style & style_mask, FALSE, ex_style & ex_style_mask, dpi ); -} - - -/*********************************************************************** - * X11DRV_X_to_window_rect - * - * Opposite of X11DRV_window_to_X_rect - */ -void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, int y, int cx, int cy ) -{ - RECT rc; - - get_decoration_rect( data, &rc, &data->rects.window, &data->rects.client ); - - x += min( data->rects.window.left - data->rects.visible.left, rc.left ); - y += min( data->rects.window.top - data->rects.visible.top, rc.top ); - cx += max( (data->rects.window.right - data->rects.window.left) - - (data->rects.visible.right - data->rects.visible.left), rc.right - rc.left ); - cy += max( (data->rects.window.bottom - data->rects.window.top) - - (data->rects.visible.bottom - data->rects.visible.top), rc.bottom - rc.top ); - SetRect( rect, x, y, x + cx, y + cy ); -} - - /*********************************************************************** * sync_window_position * @@ -2810,7 +2760,8 @@ UINT X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) &root, &x, &y, &width, &height, &border, &depth ); XTranslateCoordinates( thread_data->display, data->whole_window, root, 0, 0, &x, &y, &top ); pos = root_to_virtual_screen( x, y ); - X11DRV_X_to_window_rect( data, rect, pos.x, pos.y, width, height ); + SetRect( rect, pos.x, pos.y, pos.x + width, pos.y + height ); + *rect = window_rect_from_visible( &data->rects, *rect ); swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE | SWP_NOSIZE | SWP_NOCLIENTSIZE);
done: diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 947eb1a10e3..b87d6a87932 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -678,7 +678,6 @@ typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void
extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg ); extern int X11DRV_check_error(void); -extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, int y, int cx, int cy ); extern POINT virtual_screen_to_root( INT x, INT y ); extern POINT root_to_virtual_screen( INT x, INT y ); extern RECT get_host_primary_monitor_rect(void);
v2: Initialize visible rect to window rect before calling WindowPosChanging: when a window is created, so without a previously visible rect, we would be using a 0 size visible rect.
It's hopefully the issue here as there is some XCreateWindow errors although I'm not sure why, XCreateWindow calls are always guarded against 0x0 sizes, and I don't reproduce the failures locally.
On Wed Aug 21 11:25:55 2024 +0000, Rémi Bernon wrote:
v2: Initialize visible rect to window rect before calling WindowPosChanging: when a window is created, so without a previously visible rect, we would be using a 0 size visible rect. It's hopefully the issue here as there is some XCreateWindow errors although I'm not sure why, XCreateWindow calls are always guarded against 0x0 sizes, and I don't reproduce the failures locally.
Failures are still present, will keep looking.