mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:27:35 +00:00
winex11: Add window data structure locking to the map/unmap functions.
This commit is contained in:
parent
ba926faf91
commit
a6c543d0e6
2 changed files with 86 additions and 54 deletions
|
@ -1163,7 +1163,7 @@ static int get_window_wm_state( Display *display, Window window )
|
|||
*/
|
||||
static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window )
|
||||
{
|
||||
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
|
||||
struct x11drv_win_data *data = get_win_data( hwnd );
|
||||
DWORD style;
|
||||
|
||||
if (!data) return;
|
||||
|
@ -1185,13 +1185,13 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
|
|||
data->wm_state = new_state;
|
||||
/* ignore the initial state transition out of withdrawn state */
|
||||
/* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
|
||||
if (!old_state) return;
|
||||
if (!old_state) goto done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!update_window || !data->managed || !data->mapped) return;
|
||||
if (!update_window || !data->managed || !data->mapped) goto done;
|
||||
|
||||
style = GetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
|
@ -1203,17 +1203,20 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
|
|||
if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
|
||||
release_win_data( data );
|
||||
SendMessageW( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
|
||||
return;
|
||||
}
|
||||
else TRACE( "not restoring to max win %p/%lx style %08x\n",
|
||||
data->hwnd, data->whole_window, style );
|
||||
TRACE( "not restoring to max win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
else if (style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
|
||||
release_win_data( data );
|
||||
SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
|
||||
return;
|
||||
}
|
||||
else TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
else if (!data->iconic && data->wm_state == IconicState)
|
||||
{
|
||||
|
@ -1221,10 +1224,14 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
|
|||
if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
|
||||
release_win_data( data );
|
||||
SendMessageW( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
|
||||
return;
|
||||
}
|
||||
else TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
done:
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1254,20 +1261,33 @@ static Bool is_wm_state_notify( Display *display, XEvent *event, XPointer arg )
|
|||
void wait_for_withdrawn_state( HWND hwnd, BOOL set )
|
||||
{
|
||||
Display *display = thread_display();
|
||||
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
|
||||
struct x11drv_win_data *data;
|
||||
DWORD end = GetTickCount() + 2000;
|
||||
|
||||
if (!data || !data->managed) return;
|
||||
TRACE( "waiting for window %p to become %swithdrawn\n", hwnd, set ? "" : "not " );
|
||||
|
||||
TRACE( "waiting for window %p/%lx to become %swithdrawn\n",
|
||||
data->hwnd, data->whole_window, set ? "" : "not " );
|
||||
|
||||
while (data->whole_window && ((data->wm_state == WithdrawnState) == !set))
|
||||
for (;;)
|
||||
{
|
||||
XEvent event;
|
||||
Window window;
|
||||
int count = 0;
|
||||
|
||||
while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)data->whole_window ))
|
||||
if (!(data = get_win_data( hwnd ))) break;
|
||||
if (!data->managed || data->embedded || data->display != display) break;
|
||||
if (!(window = data->whole_window)) break;
|
||||
if (!data->mapped == !set)
|
||||
{
|
||||
TRACE( "window %p/%lx now %smapped\n", hwnd, window, data->mapped ? "" : "un" );
|
||||
break;
|
||||
}
|
||||
if ((data->wm_state == WithdrawnState) != !set)
|
||||
{
|
||||
TRACE( "window %p/%lx state now %d\n", hwnd, window, data->wm_state );
|
||||
break;
|
||||
}
|
||||
release_win_data( data );
|
||||
|
||||
while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)window ))
|
||||
{
|
||||
count++;
|
||||
if (XFilterEvent( &event, None )) continue; /* filtered, ignore it */
|
||||
|
@ -1284,12 +1304,12 @@ void wait_for_withdrawn_state( HWND hwnd, BOOL set )
|
|||
pfd.events = POLLIN;
|
||||
if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1)
|
||||
{
|
||||
FIXME( "window %p/%lx wait timed out\n", data->hwnd, data->whole_window );
|
||||
break;
|
||||
FIXME( "window %p/%lx wait timed out\n", hwnd, window );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE( "window %p/%lx state now %d\n", data->hwnd, data->whole_window, data->wm_state );
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1068,24 +1068,31 @@ static void set_xembed_flags( struct x11drv_win_data *data, unsigned long flags
|
|||
*/
|
||||
static void map_window( HWND hwnd, DWORD new_style )
|
||||
{
|
||||
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
|
||||
|
||||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
|
||||
remove_startup_notification( data->display, data->whole_window );
|
||||
struct x11drv_win_data *data;
|
||||
|
||||
wait_for_withdrawn_state( hwnd, TRUE );
|
||||
|
||||
if (!data->embedded)
|
||||
{
|
||||
update_net_wm_states( data );
|
||||
sync_window_style( data );
|
||||
XMapWindow( data->display, data->whole_window );
|
||||
}
|
||||
else set_xembed_flags( data, XEMBED_MAPPED );
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
|
||||
data->mapped = TRUE;
|
||||
data->iconic = (new_style & WS_MINIMIZE) != 0;
|
||||
if (data->whole_window && !data->mapped)
|
||||
{
|
||||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
|
||||
remove_startup_notification( data->display, data->whole_window );
|
||||
set_wm_hints( data );
|
||||
|
||||
if (!data->embedded)
|
||||
{
|
||||
update_net_wm_states( data );
|
||||
sync_window_style( data );
|
||||
XMapWindow( data->display, data->whole_window );
|
||||
}
|
||||
else set_xembed_flags( data, XEMBED_MAPPED );
|
||||
|
||||
data->mapped = TRUE;
|
||||
data->iconic = (new_style & WS_MINIMIZE) != 0;
|
||||
}
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1094,20 +1101,24 @@ static void map_window( HWND hwnd, DWORD new_style )
|
|||
*/
|
||||
static void unmap_window( HWND hwnd )
|
||||
{
|
||||
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
|
||||
struct x11drv_win_data *data;
|
||||
|
||||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
wait_for_withdrawn_state( hwnd, FALSE );
|
||||
|
||||
if (!data->embedded)
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
|
||||
if (data->mapped)
|
||||
{
|
||||
wait_for_withdrawn_state( hwnd, FALSE );
|
||||
if (!data->managed) XUnmapWindow( data->display, data->whole_window );
|
||||
else XWithdrawWindow( data->display, data->whole_window, DefaultScreen(data->display) );
|
||||
}
|
||||
else set_xembed_flags( data, 0 );
|
||||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
|
||||
data->mapped = FALSE;
|
||||
data->net_wm_state = 0;
|
||||
if (data->embedded) set_xembed_flags( data, 0 );
|
||||
else if (!data->managed) XUnmapWindow( data->display, data->whole_window );
|
||||
else XWithdrawWindow( data->display, data->whole_window, DefaultScreen(data->display) );
|
||||
|
||||
data->mapped = FALSE;
|
||||
data->net_wm_state = 0;
|
||||
}
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1116,21 +1127,23 @@ static void unmap_window( HWND hwnd )
|
|||
*/
|
||||
void make_window_embedded( HWND hwnd )
|
||||
{
|
||||
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
|
||||
BOOL was_mapped = data->mapped;
|
||||
struct x11drv_win_data *data = get_win_data( hwnd );
|
||||
|
||||
if (!data) return;
|
||||
|
||||
/* the window cannot be mapped before being embedded */
|
||||
if (data->mapped) unmap_window( hwnd );
|
||||
|
||||
if (data->mapped)
|
||||
{
|
||||
if (data->managed) XUnmapWindow( data->display, data->whole_window );
|
||||
else XWithdrawWindow( data->display, data->whole_window, DefaultScreen(data->display) );
|
||||
data->net_wm_state = 0;
|
||||
}
|
||||
data->embedded = TRUE;
|
||||
data->managed = TRUE;
|
||||
SetPropA( hwnd, managed_prop, (HANDLE)1 );
|
||||
sync_window_style( data );
|
||||
|
||||
if (was_mapped)
|
||||
map_window( hwnd, 0 );
|
||||
else
|
||||
set_xembed_flags( data, 0 );
|
||||
set_xembed_flags( data, data->mapped ? XEMBED_MAPPED : 0 );
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2161,7 +2174,6 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
|
|||
{
|
||||
make_owner_managed( hwnd );
|
||||
if (!data->icon_pixmap) fetch_icon_data( hwnd, 0, 0 );
|
||||
set_wm_hints( data );
|
||||
map_window( hwnd, new_style );
|
||||
}
|
||||
else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE)))
|
||||
|
|
Loading…
Reference in a new issue