When sending a ping event to a surface using the wl_shell interface,
if that surface is destroyed before we receive the pong we will never
receive it, even if the client is actually responsive, since the
interface does not exist anymore. So when the surface if destroyed
pretend it's a pong and reset the ping state.

Signed-off-by: Giulio Camuffo <giuliocamu...@gmail.com>
---

v3: store the ping serial in the surface instead of the client wrapper
v4: removed leftover change

 libweston-desktop/wl-shell.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/libweston-desktop/wl-shell.c b/libweston-desktop/wl-shell.c
index 399139c..f75b022 100644
--- a/libweston-desktop/wl-shell.c
+++ b/libweston-desktop/wl-shell.c
@@ -57,6 +57,7 @@ struct weston_desktop_wl_shell_surface {
        struct weston_desktop_seat *popup_seat;
        enum weston_desktop_wl_shell_surface_state state;
        struct wl_listener wl_surface_resource_destroy_listener;
+       uint32_t ping_serial;
 };
 
 static void
@@ -112,6 +113,7 @@ weston_desktop_wl_shell_surface_ping(struct 
weston_desktop_surface *dsurface,
 {
        struct weston_desktop_wl_shell_surface *surface = user_data;
 
+       surface->ping_serial = serial;
        wl_shell_surface_send_ping(surface->resource, serial);
 }
 
@@ -181,11 +183,27 @@ weston_desktop_wl_shell_change_state(struct 
weston_desktop_wl_shell_surface *sur
 }
 
 static void
+pong_client(struct weston_desktop_wl_shell_surface *surface)
+{
+       struct weston_desktop_client *client =
+               weston_desktop_surface_get_client(surface->surface);
+
+       weston_desktop_client_pong(client, surface->ping_serial);
+       surface->ping_serial = 0;
+}
+
+static void
 weston_desktop_wl_shell_surface_destroy(struct weston_desktop_surface 
*dsurface,
                                        void *user_data)
 {
        struct weston_desktop_wl_shell_surface *surface = user_data;
 
+       /* If the surface being destroyed was the one that was pinged before
+        * we need to fake a pong here, because it cannot answer the ping 
anymore,
+        * even if the client is responsive. */
+       if (surface->ping_serial != 0)
+               pong_client(surface);
+
        wl_list_remove(&surface->wl_surface_resource_destroy_listener.link);
 
        weston_desktop_wl_shell_surface_maybe_ungrab(surface);
@@ -203,8 +221,10 @@ weston_desktop_wl_shell_surface_protocol_pong(struct 
wl_client *wl_client,
                                              uint32_t serial)
 {
        struct weston_desktop_surface *surface = 
wl_resource_get_user_data(resource);
+       struct weston_desktop_wl_shell_surface *wls =
+               weston_desktop_surface_get_implementation_data(surface);
 
-       weston_desktop_client_pong(weston_desktop_surface_get_client(surface), 
serial);
+       pong_client(wls);
 }
 
 static void
-- 
2.10.2

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to