summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2012-03-01 14:09:44 +0200
committerKristian Høgsberg <krh@bitplanet.net>2012-03-01 17:33:51 -0500
commitc5fb9a7de99e43c8133bfee5b5f9cd68c3241dd4 (patch)
tree9afbab32b3647ae40460b04e6b8ef98ef17194d7
parent3be2ce9e494aa371b4ab37d7c6afd9d235b64bd6 (diff)
compositor: fix crash when a drag surface is destroyed during the drag
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.
-rw-r--r--src/compositor.c17
-rw-r--r--src/compositor.h1
2 files changed, 18 insertions, 0 deletions
diff --git a/src/compositor.c b/src/compositor.c
index 95513da..fe94523 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1832,6 +1832,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);
@@ -1868,6 +1880,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);
}
@@ -1902,6 +1916,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;
@@ -1913,6 +1928,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 d0b7206..6f46249 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -107,6 +107,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;