[PATCH 5/9] input: Don't send leave events to destroyed views
Emilio Pozuelo Monfort
pochu27 at gmail.com
Tue Nov 19 02:37:15 PST 2013
If a view which has focus is destroyed, we would send a leave
event while changing focus, causing a segfault. Prevent this
by listening to the view's destroy signal and removing it from
the pointer focus.
Signed-off-by: Emilio Pozuelo Monfort <emilio.pozuelo at collabora.co.uk>
---
src/compositor.h | 1 +
src/input.c | 27 ++++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/compositor.h b/src/compositor.h
index a8504af..b84289a 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -308,6 +308,7 @@ struct weston_pointer {
struct wl_list focus_resource_list;
struct weston_view *focus;
uint32_t focus_serial;
+ struct wl_listener focus_listener;
struct wl_signal focus_signal;
struct wl_signal motion_signal;
diff --git a/src/input.c b/src/input.c
index fc93f88..7480374 100644
--- a/src/input.c
+++ b/src/input.c
@@ -395,8 +395,9 @@ weston_pointer_create(struct weston_seat *seat)
seat->compositor->default_pointer_grab);
pointer->default_grab.pointer = pointer;
pointer->grab = &pointer->default_grab;
- wl_signal_init(&pointer->focus_signal);
wl_signal_init(&pointer->motion_signal);
+ wl_signal_init(&pointer->focus_signal);
+ wl_list_init(&pointer->focus_listener.link);
pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
@@ -503,6 +504,23 @@ seat_send_updated_caps(struct weston_seat *seat)
}
}
+static void
+destroy_pointer_focus(struct wl_listener *listener, void *data)
+{
+ struct weston_pointer *pointer;
+
+ pointer = container_of(listener, struct weston_pointer,
+ focus_listener);
+
+ pointer->focus = NULL;
+ move_resources(&pointer->resource_list, &pointer->focus_resource_list);
+
+ wl_list_remove(&pointer->focus_listener.link);
+ wl_list_init(&pointer->focus_listener.link);
+
+ wl_signal_emit(&pointer->focus_signal, pointer);
+}
+
WL_EXPORT void
weston_pointer_set_focus(struct weston_pointer *pointer,
struct weston_view *view,
@@ -559,7 +577,14 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
pointer->focus_serial = serial;
}
+ if (!wl_list_empty(&pointer->focus_listener.link)) {
+ wl_list_remove(&pointer->focus_listener.link);
+ wl_list_init(&pointer->focus_listener.link);
+ }
pointer->focus = view;
+ pointer->focus_listener.notify = destroy_pointer_focus;
+ if (view)
+ wl_signal_add(&view->destroy_signal, &pointer->focus_listener);
wl_signal_emit(&pointer->focus_signal, pointer);
}
--
1.8.4.rc3
More information about the wayland-devel
mailing list