From: Zhiyi Zhang zzhang@codeweavers.com
CW* masks in window_set_config() are from comparing against the old rect from data->pending_state.rect, not the actual X11 window rectangle. So it's still possible that after removing __NET_WM_STATE_FULLSCREEN, WM moves the window behind Wine's back. Then window_set_config() calculates CW* masks and calls XReconfigureWMWindow(), assuming the old rect is still the actual X11 window rect. As the result, some rectangle updates might be missed. --- dlls/winex11.drv/window.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 690a98a594d..a556c76eae5 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1339,17 +1339,18 @@ static void window_set_config( struct x11drv_win_data *data, RECT rect, BOOL abo
data->desired_state.rect = *new_rect; if (!data->whole_window) return; /* no window, nothing to update */ - if (EqualRect( old_rect, new_rect ) && !above) return; /* rects are the same, no need to be raised, nothing to update */ if (data->managed && window_needs_config_change_delay( data )) { TRACE( "window %p/%lx is updating _NET_WM_STATE/_MOTIF_WM_HINTS, delaying request\n", data->hwnd, data->whole_window ); return; }
+ /* Request an update even if the new_rect equals to the last requested rect because the X11 + * window geometry may have been changed by the WM. For example, removing _NET_WM_STATE_FULLSCREEN + * causes WM to restore geometry for the window */ + /* resizing a managed maximized window is not allowed */ - if ((old_rect->right - old_rect->left != new_rect->right - new_rect->left || - old_rect->bottom - old_rect->top != new_rect->bottom - new_rect->top) && - (!(style & WS_MAXIMIZE) || !data->managed)) + if (!(style & WS_MAXIMIZE) || !data->managed) { changes.width = new_rect->right - new_rect->left; changes.height = new_rect->bottom - new_rect->top; @@ -1366,8 +1367,7 @@ static void window_set_config( struct x11drv_win_data *data, RECT rect, BOOL abo }
/* only the size is allowed to change for the desktop window or systray docked windows */ - if ((old_rect->left != new_rect->left || old_rect->top != new_rect->top) && - (data->whole_window != root_window && !data->embedded)) + if (data->whole_window != root_window && !data->embedded) { POINT pt = virtual_screen_to_root( new_rect->left, new_rect->top ); changes.x = pt.x; @@ -1385,6 +1385,8 @@ static void window_set_config( struct x11drv_win_data *data, RECT rect, BOOL abo mask |= CWStackMode; }
+ if (mask == 0) return; /* nothing to update */ + data->pending_state.rect = *new_rect; data->configure_serial = NextRequest( data->display ); TRACE( "window %p/%lx, requesting config %s mask %#x above %u, serial %lu\n", data->hwnd, data->whole_window,