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 )
/***********************************************************************
* 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
*
* Check if the X client window should be mapped
......@@ -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.
*/
static void sync_window_style( Display *display, WND *win )
void X11DRV_sync_window_style( Display *display, WND *win )
{
XSetWindowAttributes attr;
int mask;
......@@ -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
*/
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;
Window group_leader;
......@@ -711,7 +700,7 @@ static Window create_whole_window( Display *display, WND *win )
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;
}
......@@ -966,7 +955,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
sync_window_style( display, wndPtr );
X11DRV_sync_window_style( display, wndPtr );
/* send WM_NCCALCSIZE */
rect = wndPtr->rectWindow;
......@@ -1043,6 +1032,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
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 );
return TRUE;
......@@ -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();
sync_window_style( display, wndPtr );
X11DRV_sync_window_style( display, wndPtr );
XReparentWindow( display, data->whole_window, X11DRV_get_client_window(parent),
data->whole_rect.left, data->whole_rect.top );
wine_tsx11_unlock();
......
......@@ -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.@)
*
* Update the X state of a window to reflect a style change
......@@ -783,7 +827,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, LONG oldStyle )
if (changed & WS_VISIBLE)
{
if (!IsRectEmpty( &wndPtr->rectWindow ))
if (!IsRectEmpty( &wndPtr->rectWindow ) && !is_window_top_level(wndPtr))
{
if (wndPtr->dwStyle & WS_VISIBLE)
{
......@@ -904,7 +948,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
/* clear the update region */
RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME |
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) &&
!IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect ))
......@@ -933,7 +977,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
}
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) &&
IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect ))
......@@ -948,9 +992,9 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
else /* no X window, simply toggle the window style */
{
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)
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 */
......
......@@ -408,6 +408,11 @@ inline static Window get_whole_window( WND *wnd )
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 Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
......@@ -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_create_desktop_thread(void);
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_client_window_position( Display *display, WND *win );
extern void X11DRV_set_wm_hints( Display *display, WND *win );
#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