[mutter/wayland] Update to new xdg-shell pinging standards



commit f27f6aab78e2964953e224e744d6aa14e57e7831
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sat Feb 15 10:26:43 2014 -0500

    Update to new xdg-shell pinging standards

 protocol/xdg-shell.xml             |   56 +++++++++--------------
 src/wayland/meta-wayland-surface.c |   87 ++++++++++++++++++++++++------------
 2 files changed, 81 insertions(+), 62 deletions(-)
---
diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml
index f0d04aa..ef755b7 100644
--- a/protocol/xdg-shell.xml
+++ b/protocol/xdg-shell.xml
@@ -43,7 +43,7 @@
        Use this enum to check the protocol version, and it will be updated
        automatically.
       </description>
-      <entry name="current" value="1" summary="Always the latest version"/>
+      <entry name="current" value="2" summary="Always the latest version"/>
     </enum>
 
 
@@ -84,6 +84,28 @@
       <arg name="y" type="int"/>
       <arg name="flags" type="uint"/>
     </request>
+
+    <event name="ping">
+      <description summary="check if the client is alive">
+        The ping event asks the client if it's still alive. Pass the
+        serial specified in the event back to the compositor by sending
+        a "pong" request back with the specified serial.
+
+        Compositors can use this to determine if the client is still
+        alive. It's unspecified what will happen if the client doesn't
+        respond to the ping request, or in what timeframe. Clients should
+        try to respond in a reasonable amount of time.
+      </description>
+      <arg name="serial" type="uint" summary="pass this to the callback"/>
+    </event>
+
+    <request name="pong">
+      <description summary="respond to a ping event">
+       A client must respond to a ping event with a pong request or
+       the client may be deemed unresponsive.
+      </description>
+      <arg name="serial" type="uint" summary="serial of the ping event"/>
+    </request>
   </interface>
 
   <interface name="xdg_surface" version="1">
@@ -176,22 +198,6 @@
       <arg name="app_id" type="string"/>
     </request>
 
-    <request name="pong">
-      <description summary="respond to a ping event">
-       A client must respond to a ping event with a pong request or
-       the client may be deemed unresponsive.
-      </description>
-      <arg name="serial" type="uint" summary="serial of the ping event"/>
-    </request>
-
-    <event name="ping">
-      <description summary="ping client">
-       Ping a client to check if it is receiving events and sending
-       requests. A client is expected to reply with a pong request.
-      </description>
-      <arg name="serial" type="uint"/>
-    </event>
-
     <request name="move">
       <description summary="start an interactive move">
        Start a pointer-driven move of the surface.
@@ -447,22 +453,6 @@
       </description>
     </request>
 
-    <request name="pong">
-      <description summary="respond to a ping event">
-       A client must respond to a ping event with a pong request or
-       the client may be deemed unresponsive.
-      </description>
-      <arg name="serial" type="uint" summary="serial of the ping event"/>
-    </request>
-
-    <event name="ping">
-      <description summary="ping client">
-       Ping a client to check if it is receiving events and sending
-       requests. A client is expected to reply with a pong request.
-      </description>
-      <arg name="serial" type="uint"/>
-    </event>
-
     <event name="popup_done">
       <description summary="popup interaction is done">
        The popup_done event is sent out when a popup grab is broken,
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 42f937c..f19cc5c 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -718,6 +718,16 @@ xdg_shell_use_unstable_version (struct wl_client *client,
 }
 
 static void
+xdg_shell_pong (struct wl_client *client,
+                struct wl_resource *resource,
+                uint32_t serial)
+{
+  MetaDisplay *display = meta_get_display ();
+
+  meta_display_pong_for_serial (display, serial);
+}
+
+static void
 xdg_surface_destructor (struct wl_resource *resource)
 {
   MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
@@ -792,17 +802,6 @@ xdg_surface_set_app_id (struct wl_client *client,
   meta_window_set_wm_class (surface->window, app_id, app_id);
 }
 
-static void
-xdg_surface_pong (struct wl_client *client,
-                  struct wl_resource *resource,
-                  guint32 serial)
-{
-  MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
-  MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
-
-  meta_display_pong_for_serial (surface->window->display, serial);
-}
-
 static gboolean
 begin_grab_op_on_surface (MetaWaylandSurface *surface,
                           MetaWaylandSeat    *seat,
@@ -958,7 +957,6 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = {
   xdg_surface_set_margin,
   xdg_surface_set_title,
   xdg_surface_set_app_id,
-  xdg_surface_pong,
   xdg_surface_move,
   xdg_surface_resize,
   xdg_surface_set_output,
@@ -1009,20 +1007,8 @@ xdg_popup_destroy (struct wl_client *client,
   wl_resource_destroy (resource);
 }
 
-static void
-xdg_popup_pong (struct wl_client *client,
-                struct wl_resource *resource,
-                uint32_t serial)
-{
-  MetaWaylandSurfaceExtension *xdg_popup = wl_resource_get_user_data (resource);
-  MetaWaylandSurface *surface = wl_container_of (xdg_popup, surface, xdg_popup);
-
-  meta_display_pong_for_serial (surface->window->display, serial);
-}
-
 static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = {
   xdg_popup_destroy,
-  xdg_popup_pong,
 };
 
 static void
@@ -1076,8 +1062,37 @@ static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = {
   xdg_shell_use_unstable_version,
   xdg_shell_get_xdg_surface,
   xdg_shell_get_xdg_popup,
+  xdg_shell_pong,
 };
 
+typedef struct {
+  struct wl_resource *resource;
+  struct wl_listener client_destroy_listener;
+} XdgShell;
+
+static void
+xdg_shell_handle_client_destroy (struct wl_listener *listener, void *data)
+{
+  XdgShell *xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener);
+  g_slice_free (XdgShell, data);
+}
+
+static struct wl_resource *
+get_xdg_shell_for_client (struct wl_client *client)
+{
+  struct wl_listener *listener;
+  XdgShell *xdg_shell;
+
+  listener = wl_client_get_destroy_listener (client, xdg_shell_handle_client_destroy);
+
+  /* No xdg_shell has been bound for this client */
+  if (listener == NULL)
+    return NULL;
+
+  xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener);
+  return xdg_shell->resource;
+}
+
 static void
 bind_xdg_shell (struct wl_client *client,
                 void *data,
@@ -1085,6 +1100,7 @@ bind_xdg_shell (struct wl_client *client,
                 guint32 id)
 {
   struct wl_resource *resource;
+  XdgShell *xdg_shell;
 
   if (version != 1)
     {
@@ -1092,8 +1108,15 @@ bind_xdg_shell (struct wl_client *client,
       return;
     }
 
+  xdg_shell = g_slice_new (XdgShell);
+
   resource = wl_resource_create (client, &xdg_shell_interface, 1, id);
   wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL);
+  xdg_shell->resource = wl_resource_create (client, &xdg_shell_interface, 1, id);
+  wl_resource_set_implementation (xdg_shell->resource, &meta_wayland_xdg_shell_interface, data, NULL);
+
+  xdg_shell->client_destroy_listener.notify = xdg_shell_handle_client_destroy;
+  wl_client_add_destroy_listener (client, &xdg_shell->client_destroy_listener);
 }
 
 static void
@@ -1514,12 +1537,18 @@ meta_wayland_surface_focused_unset (MetaWaylandSurface *surface)
 
 void
 meta_wayland_surface_ping (MetaWaylandSurface *surface,
-                           guint32             timestamp)
+                           guint32             serial)
 {
-  if (surface->xdg_surface.resource)
-    xdg_surface_send_ping (surface->xdg_surface.resource, timestamp);
-  else if (surface->xdg_popup.resource)
-    xdg_popup_send_ping (surface->xdg_popup.resource, timestamp);
+  struct wl_client *client = wl_resource_get_client (surface->resource);
+  struct wl_resource *xdg_shell = get_xdg_shell_for_client (client);
+
+  if (xdg_shell == NULL)
+    {
+      g_warning ("Trying to ping a surface without an xdg_shell bound. How does this happen?");
+      return;
+    }
+
+  xdg_shell_send_ping (xdg_shell, serial);
 }
 
 void


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