diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2012-03-01 14:09:42 +0200 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-03-01 11:52:05 -0500 |
commit | e7f6c509e2bc6437c858f95b37effee619bdfe17 (patch) | |
tree | c23428b9aa754a68a0500ed426023f00f27ac7b4 | |
parent | cb3e102620a4c8c1599b6e98fb1a37989f16f2ae (diff) |
Fix server crash when a client dies during a drag with an icon
If a client dies during a drag that it started using an icon surface,
the server could crash because the icon surface is not valid anymore.
Fix this by using a destroy listener to reset device->drag_surface to
nil when the surface is destroyed.
-rw-r--r-- | src/data-device.c | 19 | ||||
-rw-r--r-- | src/wayland-server.h | 1 |
2 files changed, 19 insertions, 1 deletions
diff --git a/src/data-device.c b/src/data-device.c index 0c7fa65..f0f6baa 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -253,6 +253,7 @@ drag_grab_button(struct wl_pointer_grab *grab, implementation->attach(surface_resource->client, surface_resource, NULL, 0, 0); + wl_list_remove(&device->drag_icon_listener.link); } device->drag_data_source = NULL; @@ -267,6 +268,18 @@ static const struct wl_pointer_grab_interface drag_grab_interface = { }; static void +destroy_data_device_icon(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time) +{ + struct wl_input_device *device; + + device = container_of(listener, struct wl_input_device, + drag_icon_listener); + + device->drag_surface = NULL; +} + +static void data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource, @@ -282,8 +295,12 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource, device->drag_grab.interface = &drag_grab_interface; device->drag_data_source = source_resource->data; - if (icon_resource) + if (icon_resource) { device->drag_surface = icon_resource->data; + device->drag_icon_listener.func = destroy_data_device_icon; + wl_list_insert(icon_resource->destroy_listener_list.prev, + &device->drag_icon_listener.link); + } wl_input_device_start_pointer_grab(device, &device->drag_grab, time); } diff --git a/src/wayland-server.h b/src/wayland-server.h index 2a21111..49ab5b1 100644 --- a/src/wayland-server.h +++ b/src/wayland-server.h @@ -232,6 +232,7 @@ struct wl_input_device { struct wl_listener drag_focus_listener; struct wl_pointer_grab drag_grab; struct wl_surface *drag_surface; + struct wl_listener drag_icon_listener; struct wl_data_source *selection_data_source; struct wl_listener selection_data_source_listener; |