Commit 911a1774 authored by Alexandre Julliard's avatar Alexandre Julliard

Don't map/unmap a top-level window when WS_VISIBLE changes, only when

we explicitly do a SetWindowPos(SWP_SHOWWINDOW/HIDEWINDOW). Update the WM hints when mapping a window in case the style has changed in the meantime.
parent e9280a1e
...@@ -89,17 +89,6 @@ inline static BOOL is_window_managed( WND *win ) ...@@ -89,17 +89,6 @@ inline static BOOL is_window_managed( WND *win )
/*********************************************************************** /***********************************************************************
* is_window_top_level
*
* Check if a given window is a top level X11 window
*/
inline static BOOL is_window_top_level( WND *win )
{
return (root_window == DefaultRootWindow(gdi_display) && win->parent == GetDesktopWindow());
}
/***********************************************************************
* is_client_window_mapped * is_client_window_mapped
* *
* Check if the X client window should be mapped * Check if the X client window should be mapped
...@@ -139,11 +128,11 @@ static int get_window_attributes( Display *display, WND *win, XSetWindowAttribut ...@@ -139,11 +128,11 @@ static int get_window_attributes( Display *display, WND *win, XSetWindowAttribut
/*********************************************************************** /***********************************************************************
* sync_window_style * X11DRV_sync_window_style
* *
* Change the X window attributes when the window style has changed. * Change the X window attributes when the window style has changed.
*/ */
static void sync_window_style( Display *display, WND *win ) void X11DRV_sync_window_style( Display *display, WND *win )
{ {
XSetWindowAttributes attr; XSetWindowAttributes attr;
int mask; int mask;
...@@ -330,11 +319,11 @@ static void set_size_hints( Display *display, WND *win ) ...@@ -330,11 +319,11 @@ static void set_size_hints( Display *display, WND *win )
/*********************************************************************** /***********************************************************************
* set_wm_hints * X11DRV_set_wm_hints
* *
* Set the window manager hints for a newly-created window * Set the window manager hints for a newly-created window
*/ */
static void set_wm_hints( Display *display, WND *win ) void X11DRV_set_wm_hints( Display *display, WND *win )
{ {
struct x11drv_win_data *data = win->pDriverData; struct x11drv_win_data *data = win->pDriverData;
Window group_leader; Window group_leader;
...@@ -711,7 +700,7 @@ static Window create_whole_window( Display *display, WND *win ) ...@@ -711,7 +700,7 @@ static Window create_whole_window( Display *display, WND *win )
wine_tsx11_unlock(); wine_tsx11_unlock();
if (is_top_level) set_wm_hints( display, win ); if (is_top_level) X11DRV_set_wm_hints( display, win );
return data->whole_window; return data->whole_window;
} }
...@@ -966,7 +955,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) ...@@ -966,7 +955,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE; if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
sync_window_style( display, wndPtr ); X11DRV_sync_window_style( display, wndPtr );
/* send WM_NCCALCSIZE */ /* send WM_NCCALCSIZE */
rect = wndPtr->rectWindow; rect = wndPtr->rectWindow;
...@@ -1043,6 +1032,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) ...@@ -1043,6 +1032,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
newPos.right, newPos.bottom, swFlag ); newPos.right, newPos.bottom, swFlag );
} }
/* if the window was made visible set create struct flag so that
* we do a proper ShowWindow later on */
if (wndPtr->dwStyle & WS_VISIBLE) cs->style |= WS_VISIBLE;
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleaseWndPtr( wndPtr );
return TRUE; return TRUE;
...@@ -1132,9 +1125,9 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) ...@@ -1132,9 +1125,9 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
} }
} }
if (is_window_top_level( wndPtr )) set_wm_hints( display, wndPtr ); if (is_window_top_level( wndPtr )) X11DRV_set_wm_hints( display, wndPtr );
wine_tsx11_lock(); wine_tsx11_lock();
sync_window_style( display, wndPtr ); X11DRV_sync_window_style( display, wndPtr );
XReparentWindow( display, data->whole_window, X11DRV_get_client_window(parent), XReparentWindow( display, data->whole_window, X11DRV_get_client_window(parent),
data->whole_rect.left, data->whole_rect.top ); data->whole_rect.left, data->whole_rect.top );
wine_tsx11_unlock(); wine_tsx11_unlock();
......
...@@ -765,6 +765,50 @@ static BOOL fixup_flags( WINDOWPOS *winpos ) ...@@ -765,6 +765,50 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
/*********************************************************************** /***********************************************************************
* set_visible_style
*
* Set/clear the WS_VISIBLE style of a window and map/unmap the X window.
*/
static void set_visible_style( HWND hwnd, BOOL set )
{
WND *win;
if (!(win = WIN_GetPtr( hwnd ))) return;
if (win == WND_OTHER_PROCESS) return;
TRACE( "hwnd %x (%lx) set %d visible %d empty %d\n",
hwnd, get_whole_window(win),
set, (win->dwStyle & WS_VISIBLE) != 0, IsRectEmpty(&win->rectWindow) );
if (set)
{
if (win->dwStyle & WS_VISIBLE) goto done;
WIN_SetStyle( hwnd, win->dwStyle | WS_VISIBLE );
if (!IsRectEmpty( &win->rectWindow ) && get_whole_window(win) && is_window_top_level(win))
{
Display *display = thread_display();
X11DRV_sync_window_style( display, win );
X11DRV_set_wm_hints( display, win );
TRACE( "mapping win %x\n", hwnd );
TSXMapWindow( display, get_whole_window(win) );
}
}
else
{
if (!(win->dwStyle & WS_VISIBLE)) goto done;
WIN_SetStyle( hwnd, win->dwStyle & ~WS_VISIBLE );
if (!IsRectEmpty( &win->rectWindow ) && get_whole_window(win) && is_window_top_level(win))
{
TRACE( "unmapping win %x\n", hwnd );
TSXUnmapWindow( thread_display(), get_whole_window(win) );
}
}
done:
WIN_ReleasePtr( win );
}
/***********************************************************************
* SetWindowStyle (X11DRV.@) * SetWindowStyle (X11DRV.@)
* *
* Update the X state of a window to reflect a style change * Update the X state of a window to reflect a style change
...@@ -783,7 +827,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, LONG oldStyle ) ...@@ -783,7 +827,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, LONG oldStyle )
if (changed & WS_VISIBLE) if (changed & WS_VISIBLE)
{ {
if (!IsRectEmpty( &wndPtr->rectWindow )) if (!IsRectEmpty( &wndPtr->rectWindow ) && !is_window_top_level(wndPtr))
{ {
if (wndPtr->dwStyle & WS_VISIBLE) if (wndPtr->dwStyle & WS_VISIBLE)
{ {
...@@ -904,7 +948,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) ...@@ -904,7 +948,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
/* clear the update region */ /* clear the update region */
RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME | RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME |
RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN ); RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN );
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE ); set_visible_style( winpos->hwnd, FALSE );
} }
else if ((wndPtr->dwStyle & WS_VISIBLE) && else if ((wndPtr->dwStyle & WS_VISIBLE) &&
!IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect )) !IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect ))
...@@ -933,7 +977,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) ...@@ -933,7 +977,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
} }
if (winpos->flags & SWP_SHOWWINDOW) if (winpos->flags & SWP_SHOWWINDOW)
{ {
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE ); set_visible_style( winpos->hwnd, TRUE );
} }
else if ((wndPtr->dwStyle & WS_VISIBLE) && else if ((wndPtr->dwStyle & WS_VISIBLE) &&
IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect )) IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect ))
...@@ -948,9 +992,9 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) ...@@ -948,9 +992,9 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
else /* no X window, simply toggle the window style */ else /* no X window, simply toggle the window style */
{ {
if (winpos->flags & SWP_SHOWWINDOW) if (winpos->flags & SWP_SHOWWINDOW)
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE ); set_visible_style( winpos->hwnd, TRUE );
else if (winpos->flags & SWP_HIDEWINDOW) else if (winpos->flags & SWP_HIDEWINDOW)
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE ); set_visible_style( winpos->hwnd, FALSE );
} }
/* manually expose the areas that X won't expose because they are still covered by something */ /* manually expose the areas that X won't expose because they are still covered by something */
......
...@@ -408,6 +408,11 @@ inline static Window get_whole_window( WND *wnd ) ...@@ -408,6 +408,11 @@ inline static Window get_whole_window( WND *wnd )
return data->whole_window; return data->whole_window;
} }
inline static BOOL is_window_top_level( WND *win )
{
return (root_window == DefaultRootWindow(gdi_display) && win->parent == GetDesktopWindow());
}
extern void X11DRV_SetFocus( HWND hwnd ); extern void X11DRV_SetFocus( HWND hwnd );
extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr ); extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
...@@ -421,7 +426,9 @@ extern void X11DRV_window_to_X_rect( WND *win, RECT *rect ); ...@@ -421,7 +426,9 @@ extern void X11DRV_window_to_X_rect( WND *win, RECT *rect );
extern void X11DRV_X_to_window_rect( WND *win, RECT *rect ); extern void X11DRV_X_to_window_rect( WND *win, RECT *rect );
extern void X11DRV_create_desktop_thread(void); extern void X11DRV_create_desktop_thread(void);
extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry ); extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
extern void X11DRV_sync_window_style( Display *display, WND *win );
extern int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder ); extern int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder );
extern int X11DRV_sync_client_window_position( Display *display, WND *win ); extern int X11DRV_sync_client_window_position( Display *display, WND *win );
extern void X11DRV_set_wm_hints( Display *display, WND *win );
#endif /* __WINE_X11DRV_H */ #endif /* __WINE_X11DRV_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment