libweston-desktop: destroy wl_shell_surface after the wl_surface is destroyed

The wl_shell_surface spec says that it is destroyed automatically by the
server when the wl_surface is destroyed, and indeed it does not have a
destroy request. So, do that.

Signed-off-by: Giulio Camuffo <giuliocamuffo@gmail.com>
Reviewed-by: Quentin Glidic <sardemff7+git@sardemff7.net>
diff --git a/libweston-desktop/wl-shell.c b/libweston-desktop/wl-shell.c
index 695b4a3..399139c 100644
--- a/libweston-desktop/wl-shell.c
+++ b/libweston-desktop/wl-shell.c
@@ -56,6 +56,7 @@
 	bool added;
 	struct weston_desktop_seat *popup_seat;
 	enum weston_desktop_wl_shell_surface_state state;
+	struct wl_listener wl_surface_resource_destroy_listener;
 };
 
 static void
@@ -185,6 +186,8 @@
 {
 	struct weston_desktop_wl_shell_surface *surface = user_data;
 
+	wl_list_remove(&surface->wl_surface_resource_destroy_listener.link);
+
 	weston_desktop_wl_shell_surface_maybe_ungrab(surface);
 	weston_desktop_surface_unset_relative_to(surface->surface);
 	if (surface->added)
@@ -404,6 +407,19 @@
 };
 
 static void
+wl_surface_resource_destroyed(struct wl_listener *listener,
+					     void *data)
+{
+	struct weston_desktop_wl_shell_surface *surface =
+		wl_container_of(listener, surface,
+				wl_surface_resource_destroy_listener);
+
+	/* the wl_shell_surface spec says that wl_shell_surfaces are to be
+	 * destroyed automatically when the wl_surface is destroyed. */
+	weston_desktop_surface_destroy(surface->surface);
+}
+
+static void
 weston_desktop_wl_shell_protocol_get_shell_surface(struct wl_client *wl_client,
 						   struct wl_resource *resource,
 						   uint32_t id,
@@ -435,6 +451,11 @@
 		return;
 	}
 
+	surface->wl_surface_resource_destroy_listener.notify =
+		wl_surface_resource_destroyed;
+	wl_resource_add_destroy_listener(wsurface->resource,
+					 &surface->wl_surface_resource_destroy_listener);
+
 	surface->resource =
 		weston_desktop_surface_add_resource(surface->surface,
 						    &wl_shell_surface_interface,