[metacity/argb-frame: 1/7] window: track pending unmaps using serials



commit fd696d43b37859ca999680252835ff9b34d192ee
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Fri Feb 28 18:32:14 2020 +0200

    window: track pending unmaps using serials

 src/core/display.c        |  8 +++---
 src/core/frame.c          | 14 +++++-----
 src/core/stack.c          |  2 +-
 src/core/window-private.h | 15 ++++++++---
 src/core/window.c         | 65 ++++++++++++++++++++++++++++++++++++++++-------
 src/ui/select-workspace.c |  2 +-
 6 files changed, 82 insertions(+), 24 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index adec7758..679b1a89 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2308,7 +2308,7 @@ event_callback (XEvent   *event,
 
           if (!frame_was_receiver)
             {
-              if (window->unmaps_pending == 0)
+              if (!meta_window_remove_pending_unmap (window, event->xany.serial))
                 {
                   meta_topic (META_DEBUG_WINDOW_STATE,
                               "Window %s withdrawn\n",
@@ -2321,10 +2321,9 @@ event_callback (XEvent   *event,
                 }
               else
                 {
-                  window->unmaps_pending -= 1;
                   meta_topic (META_DEBUG_WINDOW_STATE,
                               "Received pending unmap, %d now pending\n",
-                              window->unmaps_pending);
+                              g_list_length (window->unmaps_pending));
                 }
             }
         }
@@ -2371,6 +2370,9 @@ event_callback (XEvent   *event,
       break;
     case ReparentNotify:
       {
+        if (window)
+          meta_window_remove_pending_unmap (window, event->xany.serial);
+
         if (event->xreparent.event == screen->xroot)
           meta_stack_tracker_reparent_event (screen->stack_tracker,
                                              &event->xreparent);
diff --git a/src/core/frame.c b/src/core/frame.c
index c166b865..8a2a6bc4 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -126,9 +126,6 @@ meta_window_ensure_frame (MetaWindow *window)
       window->mapped = FALSE; /* the reparent will unmap the window,
                                * we don't want to take that as a withdraw
                                */
-      meta_topic (META_DEBUG_WINDOW_STATE,
-                  "Incrementing unmaps_pending on %s for reparent\n", window->desc);
-      window->unmaps_pending += 1;
     }
   /* window was reparented to this position */
   window->rect.x = 0;
@@ -138,6 +135,10 @@ meta_window_ensure_frame (MetaWindow *window)
                                     window->xwindow,
                                     XNextRequest (window->display->xdisplay));
 
+  meta_window_add_pending_unmap (window,
+                                 NextRequest (window->display->xdisplay),
+                                 "reparent");
+
   XReparentWindow (window->display->xdisplay,
                    window->xwindow,
                    frame->xwindow,
@@ -200,15 +201,16 @@ meta_window_destroy_frame (MetaWindow *window)
                                * can identify a withdraw initiated
                                * by the client.
                                */
-      meta_topic (META_DEBUG_WINDOW_STATE,
-                  "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
-      window->unmaps_pending += 1;
     }
 
   meta_stack_tracker_record_add (window->screen->stack_tracker,
                                  window->xwindow,
                                  XNextRequest (window->display->xdisplay));
 
+  meta_window_add_pending_unmap (window,
+                                 NextRequest (window->display->xdisplay),
+                                 "reparent back to root");
+
   XReparentWindow (window->display->xdisplay,
                    window->xwindow,
                    window->screen->xroot,
diff --git a/src/core/stack.c b/src/core/stack.c
index 8ca11cde..92a25809 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -1237,7 +1237,7 @@ get_default_focus_window (MetaStack     *stack,
       if (window == not_this_one)
         continue;
 
-      if (window->unmaps_pending > 0)
+      if (window->unmaps_pending != NULL)
         continue;
 
       if (window->unmanaging)
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 6bb47f2b..48f9e47b 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -367,11 +367,11 @@ struct _MetaWindow
   /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
   XSyncAlarm sync_request_alarm;
 
-  /* Number of UnmapNotify that are caused by us, if
-   * we get UnmapNotify with none pending then the client
-   * is withdrawing the window.
+  /* List with UnmapNotify serials that are caused by us, if we get
+   * UnmapNotify with serial that is not in pending list then the
+   * client is withdrawing the window.
    */
-  int unmaps_pending;
+  GList *unmaps_pending;
 
   /* set to the most recent user-interaction event timestamp that we
      know about for this window */
@@ -727,6 +727,13 @@ void meta_window_update_shape_region (MetaWindow *window);
 
 void meta_window_reframe (MetaWindow *window);
 
+void meta_window_add_pending_unmap (MetaWindow *window,
+                                    gulong      serial,
+                                    const char *reason);
+
+gboolean meta_window_remove_pending_unmap (MetaWindow *window,
+                                           gulong      serial);
+
 G_END_DECLS
 
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index c2d294ac..c8dd297c 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -529,7 +529,7 @@ meta_window_new (MetaDisplay    *display,
   window->opaque_region = None;
   window->opacity = 0xffffffff;
 
-  window->unmaps_pending = 0;
+  window->unmaps_pending = NULL;
 
   window->mwm_decorated = TRUE;
   window->mwm_border_only = FALSE;
@@ -1267,6 +1267,9 @@ meta_window_unmanage (MetaWindow *window,
 
   meta_error_trap_pop (window->display);
 
+  g_list_free_full (window->unmaps_pending, g_free);
+  window->unmaps_pending = NULL;
+
   g_object_unref (window);
 }
 
@@ -2321,12 +2324,11 @@ meta_window_show (MetaWindow *window)
         {
           meta_topic (META_DEBUG_WINDOW_STATE,
                       "%s actually needs unmap (shaded)\n", window->desc);
-          meta_topic (META_DEBUG_WINDOW_STATE,
-                      "Incrementing unmaps_pending on %s for shade\n",
-                      window->desc);
           window->mapped = FALSE;
-          window->unmaps_pending += 1;
           meta_error_trap_push (window->display);
+          meta_window_add_pending_unmap (window,
+                                         NextRequest (window->display->xdisplay),
+                                         "shade");
           XUnmapWindow (window->display->xdisplay, window->xwindow);
           meta_error_trap_pop (window->display);
         }
@@ -2472,12 +2474,11 @@ meta_window_hide (MetaWindow *window)
     {
       meta_topic (META_DEBUG_WINDOW_STATE,
                   "%s actually needs unmap\n", window->desc);
-      meta_topic (META_DEBUG_WINDOW_STATE,
-                  "Incrementing unmaps_pending on %s for hide\n",
-                  window->desc);
       window->mapped = FALSE;
-      window->unmaps_pending += 1;
       meta_error_trap_push (window->display);
+      meta_window_add_pending_unmap (window,
+                                     NextRequest (window->display->xdisplay),
+                                     "hide");
       XUnmapWindow (window->display->xdisplay, window->xwindow);
       meta_error_trap_pop (window->display);
       did_hide = TRUE;
@@ -9456,3 +9457,49 @@ meta_window_reframe (MetaWindow *window)
 
   window->reframe_id = g_idle_add (reframe_cb, window);
 }
+
+void
+meta_window_add_pending_unmap (MetaWindow *window,
+                               gulong      serial,
+                               const char *reason)
+{
+  gulong *pending_unmap;
+
+  pending_unmap = g_new (gulong, 1);
+  *pending_unmap = serial;
+
+  meta_topic (META_DEBUG_WINDOW_STATE,
+              "Adding pending unmap on %s for %s\n",
+              window->desc,
+              reason);
+
+  window->unmaps_pending = g_list_append (window->unmaps_pending,
+                                          pending_unmap);
+}
+
+gboolean
+meta_window_remove_pending_unmap (MetaWindow *window,
+                                  gulong      serial)
+{
+  gboolean removed;
+  GList *l;
+
+  removed = FALSE;
+
+  for (l = window->unmaps_pending; l != NULL; l = l->next)
+    {
+      gulong *pending_unmap;
+
+      pending_unmap = l->data;
+
+      if (*pending_unmap == serial)
+        {
+          removed = TRUE;
+          window->unmaps_pending = g_list_remove_link (window->unmaps_pending, l);
+          g_list_free_full (l, g_free);
+          break;
+        }
+    }
+
+  return removed;
+}
diff --git a/src/ui/select-workspace.c b/src/ui/select-workspace.c
index 20390fc0..cead65b2 100644
--- a/src/ui/select-workspace.c
+++ b/src/ui/select-workspace.c
@@ -101,7 +101,7 @@ meta_select_workspace_draw (GtkWidget *widget,
 
       if (window->skip_pager ||
           !meta_window_showing_on_its_workspace (window) ||
-          window->unmaps_pending ||
+          window->unmaps_pending != NULL ||
           ignoreable_sticky)
         {
           --n_windows;


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