[mutter/wayland] Move window pings to MetaWindow



commit aa3643cdde4277a26e5730a0f6335c76a1a22d4f
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Nov 21 14:01:40 2013 -0500

    Move window pings to MetaWindow
    
    This will make it possible to use on Wayland as well...

 src/core/delete.c          |   22 +--
 src/core/display-private.h |   16 +--
 src/core/display.c         |  306 ++------------------------------------------
 src/core/window-private.h  |   14 ++
 src/core/window.c          |  213 ++++++++++++++++++++++++++++++
 5 files changed, 245 insertions(+), 326 deletions(-)
---
diff --git a/src/core/delete.c b/src/core/delete.c
index bd4e96e..90a35f3 100644
--- a/src/core/delete.c
+++ b/src/core/delete.c
@@ -43,14 +43,11 @@ static void meta_window_present_delete_dialog (MetaWindow *window,
                                                guint32     timestamp);
 
 static void
-delete_ping_reply_func (MetaDisplay *display,
-                        Window       xwindow,
+delete_ping_reply_func (MetaWindow  *window,
                         guint32      timestamp,
                         void        *user_data)
 {
-  meta_topic (META_DEBUG_PING,
-              "Got reply to delete ping for %s\n",
-              ((MetaWindow*)user_data)->desc);
+  meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
 
   /* we do nothing */
 }
@@ -68,12 +65,10 @@ dialog_exited (GPid pid, int status, gpointer user_data)
 }
 
 static void
-delete_ping_timeout_func (MetaDisplay *display,
-                          Window       xwindow,
+delete_ping_timeout_func (MetaWindow  *window,
                           guint32      timestamp,
                           void        *user_data)
 {
-  MetaWindow *window = user_data;
   char *window_title;
   gchar *window_content, *tmp;
   GPid dialog_pid;
@@ -137,12 +132,11 @@ void
 meta_window_check_alive (MetaWindow *window,
                          guint32     timestamp)
 {
-  meta_display_ping_window (window->display,
-                            window,
-                            timestamp,
-                            delete_ping_reply_func,
-                            delete_ping_timeout_func,
-                            window);
+  meta_window_ping (window,
+                    timestamp,
+                    delete_ping_reply_func,
+                    delete_ping_timeout_func,
+                    NULL);
 }
 
 void
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 79d281b..169682e 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -57,11 +57,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
 
 typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
 
-typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
-                                    Window       xwindow,
-                                    guint32      timestamp,
-                                    gpointer     user_data);
-
 typedef enum {
   META_LIST_DEFAULT                   = 0,      /* normal windows */
   META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
@@ -182,7 +177,7 @@ struct _MetaDisplay
   guint32 window_sequence_counter;
 
   /* Pings which we're waiting for a reply from */
-  GSList     *pending_pings;
+  GHashTable *pending_pings;
 
   /* Pending focus change */
   guint       focus_timeout_id;
@@ -448,15 +443,6 @@ void meta_display_retheme_all (void);
 void meta_display_set_cursor_theme (const char *theme, 
                                    int         size);
 
-void meta_display_ping_window      (MetaDisplay        *display,
-                                    MetaWindow         *window,
-                                    guint32             timestamp,
-                                    MetaWindowPingFunc  ping_reply_func,
-                                    MetaWindowPingFunc  ping_timeout_func,
-                                    void               *user_data);
-gboolean meta_display_window_has_pending_pings (MetaDisplay        *display,
-                                               MetaWindow         *window);
-
 int meta_resize_gravity_from_grab_op (MetaGrabOp op);
 
 gboolean meta_grab_op_is_moving   (MetaGrabOp op);
diff --git a/src/core/display.c b/src/core/display.c
index 6d1b245..2989648 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -83,41 +83,6 @@
          g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK   ||  \
          g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP)
 
-/*
- * SECTION:pings
- *
- * Sometimes we want to see whether a window is responding,
- * so we send it a "ping" message and see whether it sends us back a "pong"
- * message within a reasonable time. Here we have a system which lets us
- * nominate one function to be called if we get the pong in time and another
- * function if we don't. The system is rather more complicated than it needs
- * to be, since we only ever use it to destroy windows which are asked to
- * close themselves and don't do so within a reasonable amount of time, and
- * therefore we always use the same callbacks. It's possible that we might
- * use it for other things in future, or on the other hand we might decide
- * that we're never going to do so and simplify it a bit.
- */
-
-/**
- * MetaPingData:
- *
- * Describes a ping on a window. When we send a ping to a window, we build
- * one of these structs, and it eventually gets passed to the timeout function
- * or to the function which handles the response from the window. If the window
- * does or doesn't respond to the ping, we use this information to deal with
- * these facts; we have a handler function for each.
- */
-typedef struct 
-{
-  MetaDisplay *display;
-  Window       xwindow;
-  guint32      timestamp;
-  MetaWindowPingFunc ping_reply_func;
-  MetaWindowPingFunc ping_timeout_func;
-  void        *user_data;
-  guint        ping_timeout_id;
-} MetaPingData;
-
 G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
 
 /* Signals */
@@ -172,8 +137,6 @@ static guint32 event_get_time           (MetaDisplay    *display,
                                          XEvent         *event);
 static void    process_request_frame_extents (MetaDisplay    *display,
                                               XEvent         *event);
-static void    process_pong_message     (MetaDisplay    *display,
-                                         XEvent         *event);
 static void    process_selection_request (MetaDisplay   *display,
                                           XEvent        *event);
 static void    process_selection_clear   (MetaDisplay   *display,
@@ -321,62 +284,6 @@ meta_display_class_init (MetaDisplayClass *klass)
                                                         G_PARAM_READABLE));
 }
 
-
-/**
- * ping_data_free:
- *
- * Destructor for #MetaPingData structs. Will destroy the
- * event source for the struct as well.
- */
-static void
-ping_data_free (MetaPingData *ping_data)
-{
-  /* Remove the timeout */
-  if (ping_data->ping_timeout_id != 0)
-    g_source_remove (ping_data->ping_timeout_id);
-
-  g_free (ping_data);
-}
-
-/**
- * remove_pending_pings_for_window:
- * @display: The display the window appears on
- * @xwindow: The X ID of the window whose pings we should remove
- *
- * Frees every pending ping structure for the given X window on the
- * given display. This means that we also destroy the timeouts.
- */
-static void
-remove_pending_pings_for_window (MetaDisplay *display, Window xwindow)
-{
-  GSList *tmp;
-  GSList *dead;
-
-  /* could obviously be more efficient, don't care */
-  
-  /* build list to be removed */
-  dead = NULL;
-  for (tmp = display->pending_pings; tmp; tmp = tmp->next)
-    {
-      MetaPingData *ping_data = tmp->data;
-
-      if (ping_data->xwindow == xwindow)
-        dead = g_slist_prepend (dead, ping_data);
-    }
-
-  /* remove what we found */
-  for (tmp = dead; tmp; tmp = tmp->next)
-    {
-      MetaPingData *ping_data = tmp->data;
-
-      display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
-      ping_data_free (ping_data);
-    }
-
-  g_slist_free (dead);
-}
-
-
 #ifdef HAVE_STARTUP_NOTIFICATION
 static void
 sn_error_trap_push (SnDisplay *sn_display,
@@ -528,7 +435,6 @@ meta_display_open (void)
   the_display->server_grab_count = 0;
   the_display->display_opening = TRUE;
 
-  the_display->pending_pings = NULL;
   the_display->autoraise_timeout_id = 0;
   the_display->autoraise_window = NULL;
   the_display->focus_window = NULL;
@@ -600,6 +506,8 @@ meta_display_open (void)
 
   the_display->xids = g_hash_table_new (meta_unsigned_long_hash,
                                         meta_unsigned_long_equal);
+  the_display->pending_pings = g_hash_table_new (meta_unsigned_long_hash,
+                                                 meta_unsigned_long_equal);
   the_display->wayland_windows = g_hash_table_new (NULL, NULL);
 
   i = 0;
@@ -2887,7 +2795,13 @@ handle_other_xevent (MetaDisplay *display,
 
                   if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING)
                     {
-                      process_pong_message (display, event);
+                      guint32 timestamp = event->xclient.data.l[1];
+                      window = g_hash_table_lookup (display->pending_pings, &timestamp);
+
+                      if (window)
+                        meta_window_pong (window, timestamp);
+                      else
+                        meta_verbose ("Received invalid _NET_WM_PING for unknown timestamp %d\n", timestamp);
 
                       /* We don't want ping reply events going into
                        * the GTK+ event loop because gtk+ will treat
@@ -3794,9 +3708,6 @@ meta_display_unregister_x_window (MetaDisplay *display,
   g_return_if_fail (g_hash_table_lookup (display->xids, &xwindow) != NULL);
 
   g_hash_table_remove (display->xids, &xwindow);
-
-  /* Remove any pending pings */
-  remove_pending_pings_for_window (display, xwindow);
 }
 
 void
@@ -4644,120 +4555,6 @@ meta_set_syncing (gboolean setting)
     }
 }
 
-/*
- * How long, in milliseconds, we should wait after pinging a window
- * before deciding it's not going to get back to us.
- */
-#define PING_TIMEOUT_DELAY 5000
-
-/**
- * meta_display_ping_timeout:
- * @data: All the information about this ping. It is a #MetaPingData
- *        cast to a #gpointer in order to be passable to a timeout function.
- *        This function will also free this parameter.
- *
- * Does whatever it is we decided to do when a window didn't respond
- * to a ping. We also remove the ping from the display's list of
- * pending pings. This function is called by the event loop when the timeout
- * times out which we created at the start of the ping.
- *
- * Returns: Always returns %FALSE, because this function is called as a
- *          timeout and we don't want to run the timer again.
- */
-static gboolean
-meta_display_ping_timeout (gpointer data)
-{
-  MetaPingData *ping_data;
-
-  ping_data = data;
-
-  ping_data->ping_timeout_id = 0;
-
-  meta_topic (META_DEBUG_PING,
-              "Ping %u on window %lx timed out\n",
-              ping_data->timestamp, ping_data->xwindow);
-  
-  (* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow,
-                                    ping_data->timestamp, ping_data->user_data);
-
-  ping_data->display->pending_pings =
-    g_slist_remove (ping_data->display->pending_pings,
-                    ping_data);
-  ping_data_free (ping_data);
-  
-  return FALSE;
-}
-
-/**
- * meta_display_ping_window:
- * @display: The #MetaDisplay that the window is on
- * @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
- * will call one callback; if the time passes and we haven't had
- * a response, we call a different callback. The window must have
- * the hint showing that it can respond to a ping; if it doesn't,
- * we call the "got a response" callback immediately and return.
- * This function returns straight away after setting things up;
- * the callbacks will be called from the event loop.
- *
- * FIXME: This should probably be a method on windows, rather than displays
- *        for one of their windows.
- *
- */
-void
-meta_display_ping_window (MetaDisplay       *display,
-                         MetaWindow        *window,
-                         guint32            timestamp,
-                         MetaWindowPingFunc ping_reply_func,
-                         MetaWindowPingFunc ping_timeout_func,
-                         gpointer           user_data)
-{
-  MetaPingData *ping_data;
-
-  if (timestamp == CurrentTime)
-    {
-      meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
-      return;
-    }
-
-  if (!window->net_wm_ping)
-    {
-      if (ping_reply_func)
-        (* ping_reply_func) (display, window->xwindow, timestamp, user_data);
-
-      return;
-    }
-  
-  ping_data = g_new (MetaPingData, 1);
-  ping_data->display = display;
-  ping_data->xwindow = window->xwindow;
-  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->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
-                                             meta_display_ping_timeout,
-                                             ping_data);
-  
-  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);
-  meta_window_send_icccm_message (window,
-                                  display->atom__NET_WM_PING,
-                                  timestamp);
-}
-
 static void
 process_request_frame_extents (MetaDisplay    *display,
                                XEvent         *event)
@@ -4818,91 +4615,6 @@ process_request_frame_extents (MetaDisplay    *display,
   meta_XFree (hints);
 }
 
-/**
- * process_pong_message:
- * @display: the display we got the pong from
- * @event: the #XEvent which is a pong; we can tell which
- *         ping it corresponds to because it bears the
- *         same timestamp.
- *
- * Process the pong (the response message) from the ping we sent
- * to the window. This involves removing the timeout, calling the
- * reply handler function, and freeing memory.
- */
-static void
-process_pong_message (MetaDisplay    *display,
-                      XEvent         *event)
-{
-  GSList *tmp;
-  guint32 timestamp = event->xclient.data.l[1];
-
-  meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n",
-              timestamp);
-  
-  for (tmp = display->pending_pings; tmp; tmp = tmp->next)
-    {
-      MetaPingData *ping_data = tmp->data;
-                         
-      if (timestamp == ping_data->timestamp)
-        {
-          meta_topic (META_DEBUG_PING,
-                      "Matching ping found for pong %u\n", 
-                      ping_data->timestamp);
-
-          /* Remove the ping data from the list */
-          display->pending_pings = g_slist_remove (display->pending_pings,
-                                                   ping_data);
-
-          /* Remove the timeout */
-          if (ping_data->ping_timeout_id != 0)
-            {
-              g_source_remove (ping_data->ping_timeout_id);
-              ping_data->ping_timeout_id = 0;
-            }
-          
-          /* Call callback */
-          (* ping_data->ping_reply_func) (display, 
-                                          ping_data->xwindow,
-                                          ping_data->timestamp, 
-                                          ping_data->user_data);
-                             
-          ping_data_free (ping_data);
-
-          break;
-        }
-    }
-}
-
-/**
- * meta_display_window_has_pending_pings:
- * @display: The #MetaDisplay of the window.
- * @window: The #MetaWindow whose pings we want to know about.
- *
- * Finds whether a window has any pings waiting on it.
- *
- * FIXME: This should probably be a method on windows, rather than displays
- *        for one of their windows.
- *
- * Returns: %TRUE if there is at least one ping which has been sent
- *          to the window without getting a response; %FALSE otherwise.
- */
-gboolean
-meta_display_window_has_pending_pings (MetaDisplay *display,
-                                      MetaWindow  *window)
-{
-  GSList *tmp;
-
-  for (tmp = display->pending_pings; tmp; tmp = tmp->next)
-    {
-      MetaPingData *ping_data = tmp->data;
-
-      if (ping_data->xwindow == window->xwindow) 
-        return TRUE;
-    }
-
-  return FALSE;
-}
-
 MetaGroup*
 get_focussed_group (MetaDisplay *display)
 {
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 49dbfc7..d67af67 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -466,6 +466,8 @@ struct _MetaWindow
 
   /* Bypass compositor hints */
   guint bypass_compositor;
+
+  GSList *pending_pings;
 };
 
 struct _MetaWindowClass
@@ -747,4 +749,16 @@ void meta_window_handle_enter (MetaWindow  *window,
 void meta_window_set_surface_mapped (MetaWindow *window,
                                      gboolean    surface_mapped);
 
+typedef void (* MetaWindowPingFunc) (MetaWindow  *window,
+                                    guint32      timestamp,
+                                    gpointer     user_data);
+
+void meta_window_ping (MetaWindow         *window,
+                       guint32             timestamp,
+                       MetaWindowPingFunc  ping_reply_func,
+                       MetaWindowPingFunc  ping_timeout_func,
+                       void               *user_data);
+void meta_window_pong (MetaWindow *window,
+                       guint32     timestamp);
+
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index f8823b6..532ae0c 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -73,6 +73,26 @@
 
 static int destroying_windows_disallowed = 0;
 
+/**
+ * MetaPingData:
+ *
+ * Describes a ping on a window. When we send a ping to a window, we build
+ * one of these structs, and it eventually gets passed to the timeout function
+ * or to the function which handles the response from the window. If the window
+ * does or doesn't respond to the ping, we use this information to deal with
+ * these facts; we have a handler function for each.
+ */
+typedef struct
+{
+  MetaWindow  *window;
+  guint32      timestamp;
+  MetaWindowPingFunc ping_reply_func;
+  MetaWindowPingFunc ping_timeout_func;
+  void        *user_data;
+  guint        ping_timeout_id;
+} MetaPingData;
+
+static void ping_data_free (MetaPingData *ping_data);
 
 static void     update_sm_hints           (MetaWindow     *window);
 static void     update_net_frame_extents  (MetaWindow     *window);
@@ -2051,6 +2071,8 @@ meta_window_unmanage (MetaWindow  *window,
   if (window->surface)
     meta_wayland_surface_free (window->surface);
 
+  g_slist_free_full (window->pending_pings, (GDestroyNotify) ping_data_free);
+
   meta_prefs_remove_listener (prefs_changed_callback, window);
 
   meta_screen_queue_check_fullscreen (window->screen);
@@ -11960,3 +11982,194 @@ meta_window_set_surface_mapped (MetaWindow *window,
   window->surface_mapped = surface_mapped;
   meta_window_queue (window, META_QUEUE_CALC_SHOWING);
 }
+
+/*
+ * SECTION:pings
+ *
+ * Sometimes we want to see whether a window is responding,
+ * so we send it a "ping" message and see whether it sends us back a "pong"
+ * message within a reasonable time. Here we have a system which lets us
+ * nominate one function to be called if we get the pong in time and another
+ * function if we don't. The system is rather more complicated than it needs
+ * to be, since we only ever use it to destroy windows which are asked to
+ * close themselves and don't do so within a reasonable amount of time, and
+ * therefore we always use the same callbacks. It's possible that we might
+ * use it for other things in future, or on the other hand we might decide
+ * that we're never going to do so and simplify it a bit.
+ */
+
+/**
+ * ping_data_free:
+ *
+ * Destructor for #MetaPingData structs. Will destroy the
+ * event source for the struct as well.
+ */
+static void
+ping_data_free (MetaPingData *ping_data)
+{
+  MetaWindow *window = ping_data->window;
+  MetaDisplay *display = window->display;
+
+  /* Remove the timeout */
+  if (ping_data->ping_timeout_id != 0)
+    g_source_remove (ping_data->ping_timeout_id);
+
+  g_hash_table_remove (display->pending_pings, &ping_data->timestamp);
+
+  g_free (ping_data);
+}
+
+/**
+ * meta_window_pong:
+ * @window: the window we got the pong on
+ * @timestamp: the timestamp that the client sent back
+ *
+ * Process the pong (the response message) from the ping we sent
+ * to the window. This involves removing the timeout, calling the
+ * reply handler function, and freeing memory.
+ */
+void
+meta_window_pong (MetaWindow *window,
+                  guint32     timestamp)
+{
+  GSList *tmp;
+
+  meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n",
+              timestamp);
+
+  for (tmp = window->pending_pings; tmp; tmp = tmp->next)
+    {
+      MetaPingData *ping_data = tmp->data;
+
+      if (timestamp == ping_data->timestamp)
+        {
+          meta_topic (META_DEBUG_PING,
+                      "Matching ping found for pong %u\n",
+                      ping_data->timestamp);
+
+          /* Remove the ping data from the list */
+          window->pending_pings = g_slist_remove (window->pending_pings, ping_data);
+
+          /* Remove the timeout */
+          if (ping_data->ping_timeout_id != 0)
+            {
+              g_source_remove (ping_data->ping_timeout_id);
+              ping_data->ping_timeout_id = 0;
+            }
+
+          /* Call callback */
+          (* ping_data->ping_reply_func) (window,
+                                          ping_data->timestamp,
+                                          ping_data->user_data);
+
+          /* Remove the ping data from the list */
+          window->pending_pings = g_slist_remove (window->pending_pings, ping_data);
+
+          ping_data_free (ping_data);
+
+          break;
+        }
+    }
+}
+
+/*
+ * How long, in milliseconds, we should wait after pinging a window
+ * before deciding it's not going to get back to us.
+ */
+#define PING_TIMEOUT_DELAY 5000
+
+/**
+ * ping_timeout:
+ * @data: All the information about this ping. It is a #MetaPingData
+ *        cast to a #gpointer in order to be passable to a timeout function.
+ *        This function will also free this parameter.
+ *
+ * Does whatever it is we decided to do when a window didn't respond
+ * to a ping. We also remove the ping from the display's list of
+ * pending pings. This function is called by the event loop when the timeout
+ * times out which we created at the start of the ping.
+ *
+ * Returns: Always returns %FALSE, because this function is called as a
+ *          timeout and we don't want to run the timer again.
+ */
+static gboolean
+ping_timeout (gpointer data)
+{
+  MetaPingData *ping_data;
+
+  ping_data = data;
+
+  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_free (ping_data);
+
+  return FALSE;
+}
+
+/**
+ * meta_window_ping:
+ * @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
+ * will call one callback; if the time passes and we haven't had
+ * a response, we call a different callback. The window must have
+ * the hint showing that it can respond to a ping; if it doesn't,
+ * we call the "got a response" callback immediately and return.
+ * This function returns straight away after setting things up;
+ * the callbacks will be called from the event loop.
+ */
+void
+meta_window_ping (MetaWindow        *window,
+                  guint32            timestamp,
+                  MetaWindowPingFunc ping_reply_func,
+                  MetaWindowPingFunc ping_timeout_func,
+                  gpointer           user_data)
+{
+  MetaPingData *ping_data;
+  MetaDisplay *display = window->display;
+
+  if (timestamp == CurrentTime)
+    {
+      meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
+      return;
+    }
+
+  if (!window->net_wm_ping)
+    {
+      if (ping_reply_func)
+        (* ping_reply_func) (window, timestamp, user_data);
+
+      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->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, ping_timeout, ping_data);
+
+  g_hash_table_insert (display->pending_pings, &ping_data->timestamp, window);
+
+  meta_topic (META_DEBUG_PING,
+              "Sending ping with timestamp %u to window %s\n",
+              timestamp, window->desc);
+  meta_window_send_icccm_message (window,
+                                  display->atom__NET_WM_PING,
+                                  timestamp);
+}


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