core: Fix multiple reparent requests handling

If window decoration is modified within a short period of time, mutter
sometimes starts processing the second request before the first
UnmapNotify event has been received. In this situation, it considers
that the window is not mapped and does not expect another UnmapNotify /
MapNotify event sequence to happen.

This adds a separate counter to keep track of the pending reparents. The
input focus is then restored when MapNotify event is received iff all
the expected pending ReparentNotify events have been received.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>

https://gitlab.gnome.org/GNOME/mutter/merge_requests/657
This commit is contained in:
Rémi Bernon 2019-06-24 15:10:22 +02:00
parent 36a14e65c2
commit 8f242f8bf0
4 changed files with 11 additions and 1 deletions

View File

@ -107,6 +107,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->xwindow,
frame->child_x,
frame->child_y);
window->reparents_pending += 1;
/* FIXME handle this error */
meta_x11_error_trap_pop (x11_display);
@ -206,6 +207,7 @@ meta_window_destroy_frame (MetaWindow *window)
*/
window->frame->rect.x + borders.invisible.left,
window->frame->rect.y + borders.invisible.top);
window->reparents_pending += 1;
}
meta_x11_error_trap_pop (x11_display);

View File

@ -462,6 +462,10 @@ struct _MetaWindow
*/
int unmaps_pending;
/* Number of XReparentWindow requests that we have queued.
*/
int reparents_pending;
/* See docs for meta_window_get_stable_sequence() */
guint32 stable_sequence;

View File

@ -1080,6 +1080,7 @@ _meta_window_shared_new (MetaDisplay *display,
window->disable_sync = FALSE;
window->unmaps_pending = 0;
window->reparents_pending = 0;
window->mwm_decorated = TRUE;
window->mwm_border_only = FALSE;

View File

@ -1392,7 +1392,8 @@ handle_other_xevent (MetaX11Display *x11_display,
window = meta_window_x11_new (display, event->xmap.window,
FALSE, META_COMP_EFFECT_CREATE);
}
else if (window && window->restore_focus_on_map)
else if (window && window->restore_focus_on_map &&
window->reparents_pending == 0)
{
meta_window_focus (window,
meta_display_get_current_time_roundtrip (display));
@ -1436,6 +1437,8 @@ handle_other_xevent (MetaX11Display *x11_display,
break;
case ReparentNotify:
{
if (window->reparents_pending > 0)
window->reparents_pending -= 1;
if (event->xreparent.event == x11_display->xroot)
meta_stack_tracker_reparent_event (display->stack_tracker,
&event->xreparent);