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.
This commit is contained in:
parent
e9280a1eec
commit
911a17748f
|
@ -88,17 +88,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
|
||||
*
|
||||
|
@ -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();
|
||||
|
|
|
@ -764,6 +764,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.@)
|
||||
*
|
||||
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue