From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 91 ++++++++++++++------------------------- 1 file changed, 33 insertions(+), 58 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index fca59bc0680..a6a887e5862 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1611,38 +1611,50 @@ BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, return *state_cmd || *config_cmd; }
-void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value, Time time ) +static BOOL handle_state_change( struct x11drv_win_data *data, unsigned long serial, unsigned long *expect_serial, UINT size, + const void *value, void *desired, void *pending, void *current, const char *expected, + const char *received, const char *reason ) { - UINT *desired = &data->desired_state.wm_state, *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state; - unsigned long *expect_serial = &data->wm_state_serial; - const char *reason = NULL, *expected, *received; - - received = wine_dbg_sprintf( "WM_STATE %#x/%lu", value, serial ); - expected = *expect_serial ? wine_dbg_sprintf( ", expected %#x/%lu", *pending, *expect_serial ) : ""; - if (serial < *expect_serial) reason = "old "; - else if (!*expect_serial && *current == value) reason = "no-op "; - /* ignore Metacity/Mutter transient NormalState during WithdrawnState <-> IconicState transitions */ - else if (value == NormalState && *current + *pending == IconicState) reason = "transient "; + else if (!*expect_serial && !memcmp( current, value, size )) reason = "no-op ";
if (reason) { WARN( "Ignoring window %p/%lx %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - return; + return FALSE; }
if (!*expect_serial) reason = "unexpected "; - else if (*pending != value) reason = "mismatch "; + else if (memcmp( pending, value, size )) reason = "mismatch ";
if (!reason) TRACE( "window %p/%lx, %s%s\n", data->hwnd, data->whole_window, received, expected ); else { WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - *desired = *pending = value; /* avoid requesting the same state again */ + /* avoid requesting the same state again */ + memcpy( desired, value, size ); + memcpy( pending, value, size ); }
- *current = value; + memcpy( current, value, size ); *expect_serial = 0; + return TRUE; +} + +void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value, Time time ) +{ + UINT *desired = &data->desired_state.wm_state, *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state; + unsigned long *expect_serial = &data->wm_state_serial; + const char *reason = NULL, *expected, *received; + + received = wine_dbg_sprintf( "WM_STATE %#x/%lu", value, serial ); + expected = *expect_serial ? wine_dbg_sprintf( ", expected %#x/%lu", *pending, *expect_serial ) : ""; + /* ignore Metacity/Mutter transient NormalState during WithdrawnState <-> IconicState transitions */ + if (value == NormalState && *current + *pending == IconicState) reason = "transient "; + + if (!handle_state_change( data, serial, expect_serial, sizeof(value), &value, + desired, pending, current, expected, received, reason )) + return;
/* send any pending changes from the desired state */ window_set_wm_state( data, data->desired_state.wm_state ); @@ -1657,32 +1669,14 @@ void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long ser { UINT *desired = &data->desired_state.net_wm_state, *pending = &data->pending_state.net_wm_state, *current = &data->current_state.net_wm_state; unsigned long *expect_serial = &data->net_wm_state_serial; - const char *reason = NULL, *expected, *received; + const char *expected, *received;
received = wine_dbg_sprintf( "_NET_WM_STATE %#x/%lu", value, serial ); expected = *expect_serial ? wine_dbg_sprintf( ", expected %#x/%lu", *pending, *expect_serial ) : "";
- if (serial < *expect_serial) reason = "old "; - else if (!*expect_serial && *current == value) reason = "no-op "; - - if (reason) - { - WARN( "Ignoring window %p/%lx %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); + if (!handle_state_change( data, serial, expect_serial, sizeof(value), &value, + desired, pending, current, expected, received, NULL )) return; - } - - if (!*expect_serial) reason = "unexpected "; - else if (*pending != value) reason = "mismatch "; - - if (!reason) TRACE( "window %p/%lx, %s%s\n", data->hwnd, data->whole_window, received, expected ); - else - { - WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - *desired = *pending = value; /* avoid requesting the same state again */ - } - - *current = value; - *expect_serial = 0;
/* send any pending changes from the desired state */ window_set_wm_state( data, data->desired_state.wm_state ); @@ -1694,32 +1688,13 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial { RECT *desired = &data->desired_state.rect, *pending = &data->pending_state.rect, *current = &data->current_state.rect; unsigned long *expect_serial = &data->configure_serial; - const char *reason = NULL, *expected, *received; + const char *expected, *received;
received = wine_dbg_sprintf( "config %s/%lu", wine_dbgstr_rect(value), serial ); expected = *expect_serial ? wine_dbg_sprintf( ", expected %s/%lu", wine_dbgstr_rect(pending), *expect_serial ) : "";
- if (serial < *expect_serial) reason = "old "; - else if (!*expect_serial && EqualRect( current, value )) reason = "no-op "; - - if (reason) - { - WARN( "Ignoring window %p/%lx %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - return; - } - - if (!*expect_serial) reason = "unexpected "; - else if (!EqualRect( pending, value )) reason = "mismatch "; - - if (!reason) TRACE( "window %p/%lx, %s%s\n", data->hwnd, data->whole_window, received, expected ); - else - { - WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - *desired = *pending = *value; /* avoid requesting the same state again */ - } - - *current = *value; - *expect_serial = 0; + handle_state_change( data, serial, expect_serial, sizeof(*value), value, + desired, pending, current, expected, received, NULL ); }
BOOL window_has_pending_wm_state( HWND hwnd, UINT state )