Moving the logic out of the event handlers, in preparation for asynchronous state changes.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 8 +++----- dlls/winex11.drv/window.c | 8 ++------ dlls/winex11.drv/x11drv.h | 1 - 3 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 5300982d6b2..cada76a6329 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1142,13 +1142,12 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); if ((style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen) { - data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window ); - if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(style & WS_MAXIMIZE)) + if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(style & WS_MAXIMIZE)) { TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window ); config_cmd = SC_MAXIMIZE; } - else if (!(data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (style & WS_MAXIMIZE)) + else if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (style & WS_MAXIMIZE)) { TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window ); config_cmd = SC_RESTORE; @@ -1268,8 +1267,7 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat if (data->iconic && data->wm_state == NormalState) /* restore window */ { data->iconic = FALSE; - data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window ); - if ((style & WS_CAPTION) == WS_CAPTION && (data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) + if ((style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) { if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED)) { diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 02a1eb13c48..df5eeb5bc46 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1160,7 +1160,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) long monitors[4]; XEvent xev;
- if (!(data->net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop() + if (!(data->pending_state.net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop() || NtUserGetWindowLongW( data->hwnd, GWL_STYLE ) & WS_MINIMIZE) return;
@@ -1328,7 +1328,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); if (style & WS_MINIMIZE) - new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); + new_state |= data->pending_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); if (data->is_fullscreen) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) @@ -1352,7 +1352,6 @@ static void update_net_wm_states( struct x11drv_win_data *data ) }
window_set_net_wm_state( data, new_state ); - data->net_wm_state = new_state; update_net_wm_fullscreen_monitors( data ); }
@@ -1490,7 +1489,6 @@ static void unmap_window( HWND hwnd ) TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); window_set_wm_state( data, WithdrawnState ); data->mapped = FALSE; - data->net_wm_state = 0; } release_win_data( data ); } @@ -1600,7 +1598,6 @@ void make_window_embedded( struct x11drv_win_data *data ) { /* the window cannot be mapped before being embedded */ window_set_wm_state( data, WithdrawnState ); - data->net_wm_state = 0; data->embedded = TRUE; data->managed = TRUE; sync_window_style( data ); @@ -2012,7 +2009,6 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des data->whole_window = data->client_window = 0; data->whole_colormap = 0; data->wm_state = WithdrawnState; - data->net_wm_state = 0; data->mapped = FALSE;
memset( &data->pending_state, 0, sizeof(data->pending_state) ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f1f0f97486b..bf0fe26f925 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -634,7 +634,6 @@ struct x11drv_win_data UINT is_fullscreen : 1; /* is the window visible rect fullscreen */ UINT parent_invalid : 1; /* is the parent host window possibly invalid */ int wm_state; /* current value of the WM_STATE property */ - DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */ Window embedder; /* window id of embedder */ Pixmap icon_pixmap; Pixmap icon_mask;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index cada76a6329..d155ebbf33f 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1264,7 +1264,7 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
- if (data->iconic && data->wm_state == NormalState) /* restore window */ + if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */ { data->iconic = FALSE; if ((style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) @@ -1285,7 +1285,7 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat } } } - else if (!data->iconic && data->wm_state == IconicState) + else if (!data->iconic && data->current_state.wm_state == IconicState) { data->iconic = TRUE; if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 40 ++------------------------------------- dlls/winex11.drv/window.c | 38 +++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 2 ++ 3 files changed, 42 insertions(+), 38 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index d155ebbf33f..540c9b30a1f 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1231,7 +1231,7 @@ static int get_window_xembed_info( Display *display, Window window ) static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window ) { struct x11drv_win_data *data; - UINT style, value = 0, state_cmd = 0; + UINT value = 0, state_cmd = 0;
if (!(data = get_win_data( hwnd ))) return; if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window ); @@ -1252,49 +1252,13 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat TRACE( "%p/%lx: new WM_STATE %d from %d\n", data->hwnd, data->whole_window, new_state, old_state ); 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) goto done; } } break; }
- if (!update_window || !data->managed || !data->mapped) goto done; + if (update_window) state_cmd = window_update_client_state( data );
- style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - - if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */ - { - data->iconic = FALSE; - if ((style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) - { - if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED)) - { - TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window ); - state_cmd = SC_MAXIMIZE; - } - } - else - { - if (style & (WS_MINIMIZE | WS_MAXIMIZE)) - { - BOOL activate = (style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE); - TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window ); - state_cmd = MAKELONG(SC_RESTORE, activate); - } - } - } - else if (!data->iconic && data->current_state.wm_state == IconicState) - { - data->iconic = TRUE; - if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED)) - { - TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window ); - state_cmd = SC_MINIMIZE; - } - } -done: release_win_data( data );
if (state_cmd) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index df5eeb5bc46..686b93e855f 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1493,6 +1493,44 @@ static void unmap_window( HWND hwnd ) release_win_data( data ); }
+UINT window_update_client_state( struct x11drv_win_data *data ) +{ + UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); + + if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */ + if (!data->mapped) return 0; /* ignore state changes on invisible windows */ + + if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */ + { + data->iconic = FALSE; + if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) + { + if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED)) + { + TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window ); + return SC_MAXIMIZE; + } + } + else if (old_style & (WS_MINIMIZE | WS_MAXIMIZE)) + { + BOOL activate = (old_style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE); + TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window ); + return MAKELONG(SC_RESTORE, activate); + } + } + else if (!data->iconic && data->current_state.wm_state == IconicState) + { + data->iconic = TRUE; + if ((old_style & WS_MINIMIZEBOX) && !(old_style & WS_DISABLED)) + { + TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window ); + return SC_MINIMIZE; + } + } + + return 0; +} + void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ) { UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index bf0fe26f925..e73941a7578 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -661,6 +661,8 @@ extern void destroy_vk_surface( HWND hwnd ); extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ); extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ); extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect ); +extern UINT window_update_client_state( struct x11drv_win_data *data ); + extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ); extern Window init_clip_window(void); extern void update_user_time( Time time );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 67 ++------------------------------------- dlls/winex11.drv/window.c | 39 +++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 1 + 3 files changed, 43 insertions(+), 64 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 540c9b30a1f..7535e89ed50 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1078,8 +1078,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) struct x11drv_win_data *data; RECT rect; POINT pos = {event->x, event->y}; - UINT style, flags = 0, config_cmd = 0; - int cx, cy, x, y; + UINT config_cmd;
if (!hwnd) return FALSE; if (!(data = get_win_data( hwnd ))) return FALSE; @@ -1098,68 +1097,8 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height ); window_configure_notify( data, event->serial, &rect );
- if (!data->mapped || data->iconic) goto done; - if (!data->whole_window || !data->managed) goto done; - if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0) - { - TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n", - hwnd, data->whole_window, event->x, event->y, event->width, event->height, - event->serial, data->configure_serial ); - goto done; - } - - rect = window_rect_from_visible( &data->rects, rect ); - - TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n", - hwnd, data->whole_window, (int)rect.left, (int)rect.top, - (int)(rect.right-rect.left), (int)(rect.bottom-rect.top), - event->x, event->y, event->width, event->height ); - - /* Compare what has changed */ - - x = rect.left; - y = rect.top; - cx = rect.right - rect.left; - cy = rect.bottom - rect.top; - flags = SWP_NOACTIVATE | SWP_NOZORDER; - - if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */ - - if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE; - else - TRACE( "%p moving from (%d,%d) to (%d,%d)\n", - hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y ); - - if ((data->rects.window.right - data->rects.window.left == cx && - data->rects.window.bottom - data->rects.window.top == cy) || - IsRectEmpty( &data->rects.window )) - flags |= SWP_NOSIZE; - else - TRACE( "%p resizing from (%dx%d) to (%dx%d)\n", - hwnd, (int)(data->rects.window.right - data->rects.window.left), - (int)(data->rects.window.bottom - data->rects.window.top), cx, cy ); - - style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - if ((style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen) - { - if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(style & WS_MAXIMIZE)) - { - TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window ); - config_cmd = SC_MAXIMIZE; - } - else if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (style & WS_MAXIMIZE)) - { - TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window ); - config_cmd = SC_RESTORE; - } - } - if (!config_cmd && (flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE)) - { - TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window, - wine_dbgstr_rect(&data->rects.window), wine_dbgstr_rect(&rect), flags ); - config_cmd = MAKELONG(SC_MOVE, flags); - } -done: + config_cmd = window_update_client_config( data ); + rect = window_rect_from_visible( &data->rects, data->current_state.rect ); release_win_data( data );
if (config_cmd) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 686b93e855f..6e7a2f6b050 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1531,6 +1531,45 @@ UINT window_update_client_state( struct x11drv_win_data *data ) return 0; }
+UINT window_update_client_config( struct x11drv_win_data *data ) +{ + UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), flags; + RECT rect, old_rect = data->rects.window, new_rect; + + if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */ + if (!data->mapped) return 0; /* ignore config changes on invisible windows */ + if (data->iconic) return 0; /* ignore config changes on minimized windows */ + + if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */ + + if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen) + { + if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(old_style & WS_MAXIMIZE)) + { + TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window ); + return SC_MAXIMIZE; + } + if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (old_style & WS_MAXIMIZE)) + { + TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window ); + return SC_RESTORE; + } + } + + flags = SWP_NOACTIVATE | SWP_NOZORDER; + rect = new_rect = window_rect_from_visible( &data->rects, data->current_state.rect ); + if (new_rect.left == old_rect.left && new_rect.top == old_rect.top) flags |= SWP_NOMOVE; + else OffsetRect( &rect, old_rect.left - new_rect.left, old_rect.top - new_rect.top ); + if (rect.right == old_rect.right && rect.bottom == old_rect.bottom) flags |= SWP_NOSIZE; + else if (IsRectEmpty( &rect )) flags |= SWP_NOSIZE; + + if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) return 0; + + TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window, + wine_dbgstr_rect(&old_rect), wine_dbgstr_rect(&new_rect), flags ); + return MAKELONG(SC_MOVE, flags); +} + void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ) { UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index e73941a7578..d5f487d8247 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -662,6 +662,7 @@ extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ); extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect ); extern UINT window_update_client_state( struct x11drv_win_data *data ); +extern UINT window_update_client_config( struct x11drv_win_data *data );
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ); extern Window init_clip_window(void);