From: Zhiyi Zhang zzhang@codeweavers.com
Manual tests on XP, Win7 and Win10 show that such windows are not shown in pager. --- dlls/win32u/sysparams.c | 35 +++++++++++++++++++++++++++++++++++ dlls/winex11.drv/window.c | 23 +++++++++++++++++++++++ include/ntuser.h | 6 ++++++ 3 files changed, 64 insertions(+)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index d02ff16a2c0..05e477797fd 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1914,6 +1914,38 @@ static BOOL is_window_rect_full_screen( const RECT *rect ) return ret; }
+static BOOL has_visible_owned_window( HWND owner ) +{ + BOOL ret = FALSE; + UINT i, dpi; + DWORD style; + HWND *list; + RECT rect; + + if (!(list = list_window_children( 0, get_desktop_window(), NULL, 0 ))) + return FALSE; + + dpi = get_thread_dpi(); + for (i = 0; list[i]; i++) + { + if (NtUserGetWindowRelative( list[i], GW_OWNER ) != owner) + continue; + + style = get_window_long( list[i], GWL_STYLE ); + if (!(style & WS_VISIBLE)) + continue; + + get_window_rect( list[i], &rect, dpi ); + if (!IsRectEmpty( &rect )) + { + ret = TRUE; + break; + } + } + free( list ); + return ret; +} + RECT get_display_rect( const WCHAR *display ) { struct monitor *monitor; @@ -5496,6 +5528,9 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) case NtUserCallOneParam_GetSysColor: return get_sys_color( arg );
+ case NtUserCallOneParam_HasVisibleOwnedWindow: + return has_visible_owned_window( UlongToHandle(arg) ); + case NtUserCallOneParam_IsWindowRectFullScreen: return is_window_rect_full_screen( (const RECT *)arg );
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 603314ff3bb..39dcfd3b95a 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1011,12 +1011,22 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) } }
+static BOOL is_invisible_owner_window( const struct x11drv_win_data *data, UINT style ) +{ + if ((style & WS_VISIBLE) && !IsRectEmpty( &data->whole_rect )) + return FALSE; + + return NtUserHasVisibleOwnedWindow( data->hwnd ); +} + /*********************************************************************** * update_net_wm_states */ void update_net_wm_states( struct x11drv_win_data *data ) { UINT i, style, ex_style, new_state = 0; + struct x11drv_win_data *owner_data; + HWND owner;
if (!data->managed) return; if (data->whole_window == root_window) return; @@ -1046,6 +1056,19 @@ void update_net_wm_states( struct x11drv_win_data *data ) new_state |= (1 << NET_WM_STATE_SKIP_TASKBAR); }
+ /* If this window has no WS_EX_APPWINDOW and is invisible and has a visible owned window, then + * such a window should not be shown in pager and KDE switcher */ + if (!(ex_style & WS_EX_APPWINDOW) && is_invisible_owner_window( data, style )) + new_state |= (1 << NET_WM_STATE_SKIP_PAGER) | (1 << KDE_NET_WM_STATE_SKIP_SWITCHER); + + /* Update owner as well because a window may be newly owned */ + owner = NtUserGetWindowRelative( data->hwnd, GW_OWNER ); + if (owner && owner != data->hwnd && (owner_data = get_win_data( owner ))) + { + update_net_wm_states( owner_data ); + release_win_data( owner_data ); + } + if (!data->mapped) /* set the _NET_WM_STATE atom directly */ { Atom atoms[NB_NET_WM_STATES+1]; diff --git a/include/ntuser.h b/include/ntuser.h index 5331b3d7400..6e523871702 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -958,6 +958,7 @@ enum NtUserCallOneParam_GetSysColorPen, NtUserCallOneParam_GetSystemMetrics, NtUserCallOneParam_GetVirtualScreenRect, + NtUserCallOneParam_HasVisibleOwnedWindow, NtUserCallOneParam_IsWindowRectFullScreen, NtUserCallOneParam_MessageBeep, NtUserCallOneParam_RealizePalette, @@ -1057,6 +1058,11 @@ static inline RECT NtUserGetVirtualScreenRect(void) return virtual; }
+static inline BOOL NtUserHasVisibleOwnedWindow( HWND owner ) +{ + return NtUserCallOneParam( HandleToUlong(owner), NtUserCallOneParam_HasVisibleOwnedWindow ); +} + static inline BOOL NtUserIsWindowRectFullScreen( const RECT *rect ) { return NtUserCallOneParam( (UINT_PTR)rect, NtUserCallOneParam_IsWindowRectFullScreen );