exposay: don't crash if a view goes away
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@collabora.co.uk>
This commit is contained in:
committed by
Kristian Høgsberg
parent
3b6e68e2c1
commit
f942b73a1c
+29
-2
@@ -33,6 +33,7 @@ struct exposay_surface {
|
|||||||
struct exposay_output *eoutput;
|
struct exposay_output *eoutput;
|
||||||
struct weston_surface *surface;
|
struct weston_surface *surface;
|
||||||
struct weston_view *view;
|
struct weston_view *view;
|
||||||
|
struct wl_listener view_destroy_listener;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
@@ -56,6 +57,20 @@ static void exposay_set_state(struct desktop_shell *shell,
|
|||||||
struct weston_seat *seat);
|
struct weston_seat *seat);
|
||||||
static void exposay_check_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
|
static void
|
||||||
exposay_in_flight_inc(struct desktop_shell *shell)
|
exposay_in_flight_inc(struct desktop_shell *shell)
|
||||||
{
|
{
|
||||||
@@ -110,8 +125,7 @@ exposay_animate_out_done(struct weston_view_animation *animation, void *data)
|
|||||||
struct exposay_surface *esurface = data;
|
struct exposay_surface *esurface = data;
|
||||||
struct desktop_shell *shell = esurface->shell;
|
struct desktop_shell *shell = esurface->shell;
|
||||||
|
|
||||||
wl_list_remove(&esurface->link);
|
exposay_surface_destroy(esurface);
|
||||||
free(esurface);
|
|
||||||
|
|
||||||
exposay_in_flight_dec(shell);
|
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
|
/* 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
|
* aspect ratio into account really. Also needs to be notified of surface
|
||||||
* addition and removal and adjust layout/animate accordingly. */
|
* 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->eoutput = eoutput;
|
||||||
esurface->view = view;
|
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->row = i / eoutput->grid_size;
|
||||||
esurface->column = i % eoutput->grid_size;
|
esurface->column = i % eoutput->grid_size;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user