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:
parent
3b6e68e2c1
commit
f942b73a1c
@ -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;
|
||||
@ -56,6 +57,20 @@ static void exposay_set_state(struct desktop_shell *shell,
|
||||
struct weston_seat *seat);
|
||||
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)
|
||||
{
|
||||
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user