[mutter] Rework timestamp pinging



commit 4053c92abf16ef8cc8d067868b717c4d896d203d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue May 20 14:48:08 2014 -0400

    Rework timestamp pinging
    
    If a window temporarily goes unresponsive, and then returns later, we
    should hide the kill dialog that we showed to the user.

 src/core/delete.c          |  123 +++++++++++++++++++++++---------------------
 src/core/display-private.h |   15 ++----
 src/core/display.c         |   63 +++++++---------------
 src/core/window-private.h  |    5 ++-
 4 files changed, 92 insertions(+), 114 deletions(-)
---
diff --git a/src/core/delete.c b/src/core/delete.c
index 759c103..2f3e62d 100644
--- a/src/core/delete.c
+++ b/src/core/delete.c
@@ -39,35 +39,58 @@
 
 #include "wayland/meta-wayland-surface.h"
 
-static void meta_window_present_delete_dialog (MetaWindow *window,
-                                               guint32     timestamp);
-
 static void
-delete_ping_reply_func (MetaWindow  *window,
-                        guint32      timestamp,
-                        void        *user_data)
+dialog_exited (GPid pid, int status, gpointer user_data)
 {
-  meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
+  MetaWindow *window = user_data;
+
+  window->dialog_pid = -1;
 
-  /* we do nothing */
+  /* exit status of 1 means the user pressed "Force Quit" */
+  if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
+    meta_window_kill (window);
 }
 
 static void
-dialog_exited (GPid pid, int status, gpointer user_data)
+present_existing_delete_dialog (MetaWindow *window,
+                                guint32     timestamp)
 {
-  MetaWindow *ours = (MetaWindow*) user_data;
+  meta_topic (META_DEBUG_PING,
+              "Presenting existing ping dialog for %s\n",
+              window->desc);
 
-  ours->dialog_pid = -1;
+  if (window->dialog_pid >= 0)
+    {
+      GSList *windows;
+      GSList *tmp;
 
-  /* exit status of 1 means the user pressed "Force Quit" */
-  if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
-    meta_window_kill (ours);
+      /* Activate transient for window that belongs to
+       * mutter-dialog
+       */
+
+      windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
+      tmp = windows;
+      while (tmp != NULL)
+        {
+          MetaWindow *w = tmp->data;
+
+          if (w->transient_for == window && w->res_class &&
+              g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
+            {
+              meta_window_activate (w, timestamp);
+              break;
+            }
+
+          tmp = tmp->next;
+        }
+
+      g_slist_free (windows);
+    }
 }
 
 static void
-delete_ping_timeout_func (MetaWindow  *window,
-                          guint32      timestamp,
-                          void        *user_data)
+show_delete_dialog (MetaWindow *window,
+                    guint32     timestamp)
 {
   char *window_title;
   gchar *window_content, *tmp;
@@ -79,7 +102,7 @@ delete_ping_timeout_func (MetaWindow  *window,
 
   if (window->dialog_pid >= 0)
     {
-      meta_window_present_delete_dialog (window, timestamp);
+      present_existing_delete_dialog (window, timestamp);
       return;
     }
 
@@ -128,15 +151,33 @@ delete_ping_timeout_func (MetaWindow  *window,
   g_child_watch_add (dialog_pid, dialog_exited, window);
 }
 
+static void
+kill_delete_dialog (MetaWindow *window)
+{
+  if (window->dialog_pid > -1)
+    kill (window->dialog_pid, SIGTERM);
+}
+
+void
+meta_window_set_alive (MetaWindow *window,
+                       gboolean    is_alive)
+{
+  if (window->is_alive == is_alive)
+    return;
+
+  window->is_alive = is_alive;
+
+  if (window->is_alive)
+    kill_delete_dialog (window);
+  else
+    show_delete_dialog (window, CurrentTime);
+}
+
 void
 meta_window_check_alive (MetaWindow *window,
                          guint32     timestamp)
 {
-  meta_display_ping_window (window,
-                            timestamp,
-                            delete_ping_reply_func,
-                            delete_ping_timeout_func,
-                            NULL);
+  meta_display_ping_window (window, timestamp);
 }
 
 void
@@ -191,39 +232,3 @@ meta_window_free_delete_dialog (MetaWindow *window)
       window->dialog_pid = -1;
     }
 }
-
-static void
-meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
-{
-  meta_topic (META_DEBUG_PING,
-              "Presenting existing ping dialog for %s\n",
-              window->desc);
-
-  if (window->dialog_pid >= 0)
-    {
-      GSList *windows;
-      GSList *tmp;
-
-      /* Activate transient for window that belongs to
-       * mutter-dialog
-       */
-
-      windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
-      tmp = windows;
-      while (tmp != NULL)
-        {
-          MetaWindow *w = tmp->data;
-
-          if (w->transient_for == window && w->res_class &&
-              g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
-            {
-              meta_window_activate (w, timestamp);
-              break;
-            }
-
-          tmp = tmp->next;
-        }
-
-      g_slist_free (windows);
-    }
-}
diff --git a/src/core/display-private.h b/src/core/display-private.h
index b63ca0d..8dc4825 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -53,10 +53,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
 
 typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
 
-typedef void (* MetaWindowPingFunc) (MetaWindow  *window,
-                                     guint32      timestamp,
-                                     gpointer     user_data);
-
 typedef enum {
   META_LIST_DEFAULT                   = 0,      /* normal windows */
   META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
@@ -393,13 +389,10 @@ const char* meta_event_detail_to_string (int d);
 void meta_display_queue_retheme_all_windows (MetaDisplay *display);
 void meta_display_retheme_all (void);
 
-void meta_display_ping_window      (MetaWindow         *window,
-                                    guint32             timestamp,
-                                    MetaWindowPingFunc  ping_reply_func,
-                                    MetaWindowPingFunc  ping_timeout_func,
-                                    void               *user_data);
-void meta_display_pong_for_serial  (MetaDisplay        *display,
-                                    guint32             serial);
+void meta_display_ping_window      (MetaWindow  *window,
+                                    guint32      serial);
+void meta_display_pong_for_serial  (MetaDisplay *display,
+                                    guint32      serial);
 
 int meta_resize_gravity_from_grab_op (MetaGrabOp op);
 
diff --git a/src/core/display.c b/src/core/display.c
index 1935672..7432250 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -98,12 +98,9 @@
  */
 typedef struct
 {
-  MetaWindow  *window;
-  guint32      timestamp;
-  MetaWindowPingFunc ping_reply_func;
-  MetaWindowPingFunc ping_timeout_func;
-  void        *user_data;
-  guint        ping_timeout_id;
+  MetaWindow *window;
+  guint32     serial;
+  guint       ping_timeout_id;
 } MetaPingData;
 
 G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
@@ -2303,15 +2300,16 @@ static gboolean
 meta_display_ping_timeout (gpointer data)
 {
   MetaPingData *ping_data = data;
-  MetaDisplay *display = ping_data->window->display;
+  MetaWindow *window = ping_data->window;
+  MetaDisplay *display = window->display;
+
+  meta_window_set_alive (window, FALSE);
 
   ping_data->ping_timeout_id = 0;
 
   meta_topic (META_DEBUG_PING,
               "Ping %u on window %s timed out\n",
-              ping_data->timestamp, ping_data->window->desc);
-
-  (* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data);
+              ping_data->serial, ping_data->window->desc);
 
   display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
   ping_data_free (ping_data);
@@ -2325,11 +2323,6 @@ meta_display_ping_timeout (gpointer data)
  * @window: The #MetaWindow to send the ping to
  * @timestamp: The timestamp of the ping. Used for uniqueness.
  *             Cannot be CurrentTime; use a real timestamp!
- * @ping_reply_func: The callback to call if we get a response.
- * @ping_timeout_func: The callback to call if we don't get a response.
- * @user_data: Arbitrary data that will be passed to the callback
- *             function. (In practice it's often a pointer to
- *             the window.)
  *
  * Sends a ping request to a window. The window must respond to
  * the request within a certain amount of time. If it does, we
@@ -2341,35 +2334,24 @@ meta_display_ping_timeout (gpointer data)
  * the callbacks will be called from the event loop.
  */
 void
-meta_display_ping_window (MetaWindow        *window,
-                         guint32            timestamp,
-                         MetaWindowPingFunc ping_reply_func,
-                         MetaWindowPingFunc ping_timeout_func,
-                         gpointer           user_data)
+meta_display_ping_window (MetaWindow *window,
+                         guint32     serial)
 {
   MetaDisplay *display = window->display;
   MetaPingData *ping_data;
 
-  if (timestamp == CurrentTime)
+  if (serial == 0)
     {
-      meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
+      meta_warning ("Tried to ping a window with a bad serial! Not allowed.\n");
       return;
     }
 
   if (!window->can_ping)
-    {
-      if (ping_reply_func)
-        (* ping_reply_func) (window, timestamp, user_data);
-
-      return;
-    }
+    return;
 
   ping_data = g_new (MetaPingData, 1);
   ping_data->window = window;
-  ping_data->timestamp = timestamp;
-  ping_data->ping_reply_func = ping_reply_func;
-  ping_data->ping_timeout_func = ping_timeout_func;
-  ping_data->user_data = user_data;
+  ping_data->serial = serial;
   ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
                                              meta_display_ping_timeout,
                                              ping_data);
@@ -2378,10 +2360,10 @@ meta_display_ping_window (MetaWindow        *window,
   display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
 
   meta_topic (META_DEBUG_PING,
-              "Sending ping with timestamp %u to window %s\n",
-              timestamp, window->desc);
+              "Sending ping with serial %u to window %s\n",
+              serial, window->desc);
 
-  META_WINDOW_GET_CLASS (window)->ping (window, timestamp);
+  META_WINDOW_GET_CLASS (window)->ping (window, serial);
 }
 
 /**
@@ -2405,11 +2387,11 @@ meta_display_pong_for_serial (MetaDisplay    *display,
     {
       MetaPingData *ping_data = tmp->data;
 
-      if (serial == ping_data->timestamp)
+      if (serial == ping_data->serial)
         {
           meta_topic (META_DEBUG_PING,
                       "Matching ping found for pong %u\n",
-                      ping_data->timestamp);
+                      ping_data->serial);
 
           /* Remove the ping data from the list */
           display->pending_pings = g_slist_remove (display->pending_pings,
@@ -2422,13 +2404,8 @@ meta_display_pong_for_serial (MetaDisplay    *display,
               ping_data->ping_timeout_id = 0;
             }
 
-          /* Call callback */
-          (* ping_data->ping_reply_func) (ping_data->window,
-                                          ping_data->timestamp,
-                                          ping_data->user_data);
-
+          meta_window_set_alive (ping_data->window, TRUE);
           ping_data_free (ping_data);
-
           break;
         }
     }
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 14f4a67..cf26b7f 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -441,8 +441,9 @@ struct _MetaWindow
   MetaStackLayer layer;
   int stack_position; /* see comment in stack.h */
 
-  /* Current dialog open for this window */
+  /* Managed by delete.c */
   int dialog_pid;
+  guint is_alive : 1;
 
   /* maintained by group.c */
   MetaGroup *group;
@@ -739,4 +740,6 @@ void meta_window_move_resize_internal (MetaWindow          *window,
 void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
 void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
 
+void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
+
 #endif


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