[PATCH weston] exposay: don't crash if a view goes away

Emilio Pozuelo Monfort pochu27 at gmail.com
Mon Feb 10 05:23:04 PST 2014


From: Emilio Pozuelo Monfort <emilio.pozuelo at collabora.co.uk>

When a view was destroyed while we were on exposay, we didn't
remove it from the list of views, and so when leaving exposay
we were trying to animate (and sometimes activate) a
non-existent view, causing a crash.

Signed-off-by: Emilio Pozuelo Monfort <emilio.pozuelo at collabora.co.uk>
---
 desktop-shell/exposay.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c
index b7e32c9..ca36358 100644
--- a/desktop-shell/exposay.c
+++ b/desktop-shell/exposay.c
@@ -33,6 +33,7 @@ struct exposay_surface {
 	struct exposay_output *eoutput;
 	struct weston_surface *surface;
 	struct weston_view *view;
+	struct wl_listener view_destroy_listener;
 	struct wl_list link;
 
 	int x;
@@ -57,6 +58,20 @@ static void exposay_set_state(struct desktop_shell *shell,
 static void exposay_check_state(struct desktop_shell *shell);
 
 static void
+exposay_surface_destroy(struct exposay_surface *esurface)
+{
+	wl_list_remove(&esurface->link);
+	wl_list_remove(&esurface->view_destroy_listener.link);
+
+	if (esurface->shell->exposay.focus_current == esurface->view)
+		esurface->shell->exposay.focus_current = NULL;
+	if (esurface->shell->exposay.focus_prev == esurface->view)
+		esurface->shell->exposay.focus_prev = NULL;
+
+	free(esurface);
+}
+
+static void
 exposay_in_flight_inc(struct desktop_shell *shell)
 {
 	shell->exposay.in_flight++;
@@ -110,8 +125,7 @@ exposay_animate_out_done(struct weston_view_animation *animation, void *data)
 	struct exposay_surface *esurface = data;
 	struct desktop_shell *shell = esurface->shell;
 
-	wl_list_remove(&esurface->link);
-	free(esurface);
+	exposay_surface_destroy(esurface);
 
 	exposay_in_flight_dec(shell);
 }
@@ -176,6 +190,16 @@ exposay_pick(struct desktop_shell *shell, int x, int y)
 	}
 }
 
+static void
+handle_view_destroy(struct wl_listener *listener, void *data)
+{
+	struct exposay_surface *esurface = container_of(listener,
+						 struct exposay_surface,
+						 view_destroy_listener);
+
+	exposay_surface_destroy(esurface);
+}
+
 /* Pretty lame layout for now; just tries to make a square.  Should take
  * aspect ratio into account really.  Also needs to be notified of surface
  * addition and removal and adjust layout/animate accordingly. */
@@ -267,6 +291,9 @@ exposay_layout(struct desktop_shell *shell, struct shell_output *shell_output)
 		esurface->eoutput = eoutput;
 		esurface->view = view;
 
+		esurface->view_destroy_listener.notify = handle_view_destroy;
+		wl_signal_add(&view->destroy_signal, &esurface->view_destroy_listener);
+
 		esurface->row = i / eoutput->grid_size;
 		esurface->column = i % eoutput->grid_size;
 
-- 
1.9.rc1



More information about the wayland-devel mailing list