From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 7fd1151bdff..c6ef4ab7d9d 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -506,6 +506,8 @@ static void sync_window_style( struct x11drv_win_data *data ) XSetWindowAttributes attr; int mask = get_window_attributes( data, &attr );
+ TRACE( "window %p/%lx changing attributes mask %#x, serial %lu\n", data->hwnd, + data->whole_window, mask, NextRequest( data->display ) ); XChangeWindowAttributes( data->display, data->whole_window, mask, &attr ); x11drv_xinput2_enable( data->display, data->whole_window ); } @@ -893,6 +895,9 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style ) size_hints->flags |= PMinSize | PMaxSize; } } + + TRACE( "window %p/%lx requesting WM_NORMAL_HINTS flags %#lx, serial %lu\n", data->hwnd, + data->whole_window, size_hints->flags, NextRequest( data->display ) ); XSetWMNormalHints( data->display, data->whole_window, size_hints ); XFree( size_hints ); } @@ -935,8 +940,8 @@ static void set_mwm_hints( struct x11drv_win_data *data, UINT style, UINT ex_sty } }
- TRACE( "%p setting mwm hints to %lx,%lx (style %x exstyle %x)\n", - data->hwnd, mwm_hints.decorations, mwm_hints.functions, style, ex_style ); + TRACE( "window %p/%lx requesting _MOTIF_WM_HINTS %#lx,%#lx (style %#x ex_style %#x) serial %lu\n", data->hwnd, + data->whole_window, mwm_hints.decorations, mwm_hints.functions, style, ex_style, NextRequest( data->display ) );
mwm_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; mwm_hints.input_mode = 0; @@ -979,6 +984,8 @@ static void set_style_hints( struct x11drv_win_data *data, DWORD style, DWORD ex else window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_NORMAL);
+ TRACE( "window %p/%lx requesting _NET_WM_WINDOW_TYPE %#lx, serial %lu\n", data->hwnd, + data->whole_window, window_type, NextRequest( data->display ) ); XChangeProperty(data->display, data->whole_window, x11drv_atom(_NET_WM_WINDOW_TYPE), XA_ATOM, 32, PropModeReplace, (unsigned char*)&window_type, 1);
@@ -994,16 +1001,27 @@ static void set_style_hints( struct x11drv_win_data *data, DWORD style, DWORD ex wm_hints->icon_mask = data->icon_mask; wm_hints->flags |= IconPixmapHint | IconMaskHint; } + + TRACE( "window %p/%lx requesting WM_HINTS flags %#lx, serial %lu\n", data->hwnd, + data->whole_window, wm_hints->flags, NextRequest( data->display ) ); XSetWMHints( data->display, data->whole_window, wm_hints ); XFree( wm_hints ); }
if (data->icon_bits) + { + TRACE( "window %p/%lx requesting _NET_WM_ICON, serial %lu\n", data->hwnd, + data->whole_window, NextRequest( data->display ) ); XChangeProperty( data->display, data->whole_window, x11drv_atom(_NET_WM_ICON), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data->icon_bits, data->icon_size ); + } else + { + TRACE( "window %p/%lx deleting _NET_WM_ICON, serial %lu\n", data->hwnd, + data->whole_window, NextRequest( data->display ) ); XDeleteProperty( data->display, data->whole_window, x11drv_atom(_NET_WM_ICON) ); + }
}
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index c6ef4ab7d9d..fcd89a8f7e0 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1194,8 +1194,16 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) } }
+static BOOL window_needs_config_change_delay( struct x11drv_win_data *data ) +{ + static const UINT fullscreen_mask = (1 << NET_WM_STATE_MAXIMIZED) | (1 << NET_WM_STATE_FULLSCREEN); + if (data->pending_state.wm_state != NormalState || !data->net_wm_state_serial) return FALSE; + return (data->pending_state.net_wm_state ^ data->current_state.net_wm_state) & fullscreen_mask; +} + static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_state ) { + static const UINT fullscreen_mask = (1 << NET_WM_STATE_MAXIMIZED) | (1 << NET_WM_STATE_FULLSCREEN); UINT i, count, old_state = data->pending_state.net_wm_state;
new_state &= x11drv_thread_data()->net_wm_state_mask; @@ -1205,6 +1213,13 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat /* we ignore and override previous _NET_WM_STATE update requests */ if (old_state == new_state) return; /* states are the same, nothing to update */
+ if (window_needs_config_change_delay( data )) + { + /* another maximized/fullscreen NET_WM_STATE update is pending, wait for it to complete as we might have delayed our config request */ + WARN( "window %p/%lx is entering/exiting maximize/fullscreen, delaying request\n", data->hwnd, data->whole_window ); + return; + } + if (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */ if (data->pending_state.wm_state == WithdrawnState) /* set the _NET_WM_STATE atom directly */ { @@ -1242,6 +1257,7 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat for (i = 0; i < NB_NET_WM_STATES; i++) { if (!((old_state ^ new_state) & (1 << i))) continue; + if (data->configure_serial && ((1 << i) & fullscreen_mask)) continue; /* another config request is pending, wait for it to complete */
xev.xclient.data.l[0] = (new_state & (1 << i)) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; xev.xclient.data.l[1] = X11DRV_Atoms[net_wm_state_atoms[i] - FIRST_XATOM]; @@ -1262,7 +1278,6 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above ) { - static const UINT fullscreen_mask = (1 << NET_WM_STATE_MAXIMIZED) | (1 << NET_WM_STATE_FULLSCREEN); UINT style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), mask = 0; const RECT *old_rect = &data->pending_state.rect; XWindowChanges changes; @@ -1271,15 +1286,13 @@ static void window_set_config( struct x11drv_win_data *data, const RECT *new_rec 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->pending_state.wm_state == NormalState && data->net_wm_state_serial && - !(data->pending_state.net_wm_state & fullscreen_mask) && - (data->current_state.net_wm_state & fullscreen_mask)) + if (window_needs_config_change_delay( data )) { /* Some window managers are sending a ConfigureNotify event with the fullscreen size when - * exiting a fullscreen window, with a serial that we cannot predict. Handling that event - * will override the Win32 window size and make the window fullscreen again. + * entering/exiting a maximized/fullscreen window, with a serial that we cannot predict. + * Handling that event will override the Win32 window size and make the window fullscreen again. */ - WARN( "window %p/%lx is exiting maximize/fullscreen, delaying request\n", data->hwnd, data->whole_window ); + WARN( "window %p/%lx is entering/exiting maximize/fullscreen, delaying request\n", data->hwnd, data->whole_window ); return; }