[mutter] core: Fix multiple reparent requests handling



commit 8f242f8bf00607e4b9d78fcb1b3b9a0bc60a9715
Author: Rémi Bernon <rbernon codeweavers com>
Date:   Mon Jun 24 15:10:22 2019 +0200

    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

 src/core/frame.c          | 2 ++
 src/core/window-private.h | 4 ++++
 src/core/window.c         | 1 +
 src/x11/events.c          | 5 ++++-
 4 files changed, 11 insertions(+), 1 deletion(-)
---
diff --git a/src/core/frame.c b/src/core/frame.c
index dd837ec87..57225d554 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -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);
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 916827119..dd89fdc90 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -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;
 
diff --git a/src/core/window.c b/src/core/window.c
index caf447fbf..34eae494d 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -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;
diff --git a/src/x11/events.c b/src/x11/events.c
index 31a9b7151..e6f8ac884 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]