[PATCH weston 4/5] compositor: fix crash when a drag surface is destroyed during the drag

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Thu Mar 1 04:09:44 PST 2012


This can happen for instance if the client that started the drag
crashes. Weston would crash because of the invalid surface pointed by
device->drag_surface.

Fix this by reseting the drag surface to nil on a destroy listener.
---
 src/compositor.c |   17 +++++++++++++++++
 src/compositor.h |    1 +
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 74c40da..4b607d0 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1850,6 +1850,18 @@ const static struct wl_input_device_interface input_device_interface = {
 	input_device_attach,
 };
 
+static void
+handle_drag_surface_destroy(struct wl_listener *listener,
+			    struct wl_resource *resource, uint32_t time)
+{
+	struct weston_input_device *device;
+
+	device = container_of(listener, struct weston_input_device,
+			      drag_surface_destroy_listener);
+
+	device->drag_surface = NULL;
+}
+
 static void unbind_input_device(struct wl_resource *resource)
 {
 	wl_list_remove(&resource->link);
@@ -1886,6 +1898,8 @@ weston_input_device_init(struct weston_input_device *device,
 	device->modifier_state = 0;
 	device->num_tp = 0;
 
+	device->drag_surface_destroy_listener.func = handle_drag_surface_destroy;
+
 	wl_list_insert(ec->input_device_list.prev, &device->link);
 }
 
@@ -1920,6 +1934,7 @@ weston_input_update_drag_surface(struct wl_input_device *input_device,
 
 	if (!input_device->drag_surface || surface_changed) {
 		undef_region(&device->drag_surface->input);
+		wl_list_remove(&device->drag_surface_destroy_listener.link);
 		device->drag_surface = NULL;
 		if (!surface_changed)
 			return;
@@ -1931,6 +1946,8 @@ weston_input_update_drag_surface(struct wl_input_device *input_device,
 
 		weston_surface_set_position(device->drag_surface,
 					    input_device->x, input_device->y);
+		wl_list_insert(device->drag_surface->surface.resource.destroy_listener_list.prev,
+			       &device->drag_surface_destroy_listener.link);
 	}
 
 	if (device->drag_surface->output == NULL &&
diff --git a/src/compositor.h b/src/compositor.h
index dd9cb20..ab881c5 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -93,6 +93,7 @@ struct weston_input_device {
 	struct weston_compositor *compositor;
 	struct weston_surface *sprite;
 	struct weston_surface *drag_surface;
+	struct wl_listener drag_surface_destroy_listener;
 	int32_t hotspot_x, hotspot_y;
 	struct wl_list link;
 	uint32_t modifier_state;
-- 
1.7.4.1



More information about the wayland-devel mailing list