diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2012-05-29 10:58:26 +0300 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-05-29 09:58:13 -0400 |
commit | 75a5f7476ad1a84c9bee0f11a90e66a8e93dab27 (patch) | |
tree | a09f787b97f64436c4ce934383dfece389153904 | |
parent | d422a733b4c20a65748c8d9e811f672a2d744218 (diff) |
data-device: implement drags with no data source for self-dnd
Properly handle a drag with no data source, i.e., don't crash and send
events only to the client that initiated the drag. This way a client can
do self drag and drop without offering anything to other clients.
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | protocol/wayland.xml | 26 | ||||
-rw-r--r-- | src/data-device.c | 58 | ||||
-rw-r--r-- | src/wayland-server.h | 1 |
4 files changed, 55 insertions, 34 deletions
@@ -78,10 +78,6 @@ EWMH - window move and resize functionality for kb and touch. - - dnd loose ends: self-dnd: initiate dnd with a null data-source, - compositor will not offer to other clients, client has to know - internally what's offered and how to transfer data. no fd passing. - - Protocol for specifying title bar rectangle (for moving unresponsive apps). Rectangle for close button, so we can popup force-close dialog if application doesn't respond to ping event diff --git a/protocol/wayland.xml b/protocol/wayland.xml index 8f5f6af..3979d97 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -317,15 +317,23 @@ <request name="start_drag"> <description summary="start drag and drop operation"> This request asks the compositor to start a drag and drop - operation on behalf of the client. The source argument is the - data source that provides the data for the eventual data - transfer. The origin surface is the surface where the drag - originates and the client must have an active implicit grab - that matches the serial. The icon surface is an optional - (can be nil) surface that provides an icon to be moved around - with the cursor. Initially, the top-left corner of the icon - surface is placed at the cursor hotspot, but subsequent - surface.attach request can move the relative position. + operation on behalf of the client. + + The source argument is the data source that provides the data + for the eventual data transfer. If source is NULL, enter, leave + and motion events are sent only to the client that initiated the + drag and the client is expected to handle the data passing + internally. + + The origin surface is the surface where the drag originates and + the client must have an active implicit grab that matches the + serial. + + The icon surface is an optional (can be nil) surface that + provides an icon to be moved around with the cursor. Initially, + the top-left corner of the icon surface is placed at the cursor + hotspot, but subsequent surface.attach request can move the + relative position. </description> <arg name="source" type="object" interface="wl_data_source"/> <arg name="origin" type="object" interface="wl_surface"/> diff --git a/src/data-device.c b/src/data-device.c index a7fc6d2..a6d465f 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -180,7 +180,7 @@ drag_grab_focus(struct wl_pointer_grab *grab, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) { struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab); - struct wl_resource *resource, *offer; + struct wl_resource *resource, *offer = NULL; struct wl_display *display; uint32_t serial; @@ -191,26 +191,34 @@ drag_grab_focus(struct wl_pointer_grab *grab, seat->drag_focus = NULL; } - if (surface) - resource = find_resource(&seat->drag_resource_list, - surface->resource.client); - if (surface && resource) { - display = wl_client_get_display(resource->client); - serial = wl_display_next_serial(display); + if (!surface) + return; + + if (!seat->drag_data_source && + surface->resource.client != seat->drag_client) + return; + + resource = find_resource(&seat->drag_resource_list, + surface->resource.client); + if (!resource) + return; + display = wl_client_get_display(resource->client); + serial = wl_display_next_serial(display); + + if (seat->drag_data_source) offer = wl_data_source_send_offer(seat->drag_data_source, resource); - wl_data_device_send_enter(resource, serial, &surface->resource, - x, y, offer); + wl_data_device_send_enter(resource, serial, &surface->resource, + x, y, offer); - seat->drag_focus = surface; - seat->drag_focus_listener.notify = destroy_drag_focus; - wl_signal_add(&resource->destroy_signal, - &seat->drag_focus_listener); - seat->drag_focus_resource = resource; - grab->focus = surface; - } + seat->drag_focus = surface; + seat->drag_focus_listener.notify = destroy_drag_focus; + wl_signal_add(&resource->destroy_signal, + &seat->drag_focus_listener); + seat->drag_focus_resource = resource; + grab->focus = surface; } static void @@ -247,6 +255,7 @@ data_device_end_drag_grab(struct wl_seat *seat) seat->drag_data_source = NULL; seat->drag_surface = NULL; + seat->drag_client = NULL; } static void @@ -261,7 +270,8 @@ drag_grab_button(struct wl_pointer_grab *grab, if (seat->pointer->button_count == 0 && state == 0) { data_device_end_drag_grab(seat); - wl_list_remove(&seat->drag_data_source_listener.link); + if (seat->drag_data_source) + wl_list_remove(&seat->drag_data_source_listener.link); } } @@ -304,10 +314,16 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource, seat->drag_grab.interface = &drag_grab_interface; - seat->drag_data_source = source_resource->data; - seat->drag_data_source_listener.notify = destroy_data_device_source; - wl_signal_add(&source_resource->destroy_signal, - &seat->drag_data_source_listener); + seat->drag_client = client; + seat->drag_data_source = NULL; + + if (source_resource) { + seat->drag_data_source = source_resource->data; + seat->drag_data_source_listener.notify = + destroy_data_device_source; + wl_signal_add(&source_resource->destroy_signal, + &seat->drag_data_source_listener); + } if (icon_resource) { seat->drag_surface = icon_resource->data; diff --git a/src/wayland-server.h b/src/wayland-server.h index 31f6fe5..731be00 100644 --- a/src/wayland-server.h +++ b/src/wayland-server.h @@ -297,6 +297,7 @@ struct wl_seat { struct wl_signal selection_signal; struct wl_list drag_resource_list; + struct wl_client *drag_client; struct wl_data_source *drag_data_source; struct wl_listener drag_data_source_listener; struct wl_surface *drag_focus; |