summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocol/wayland.xml22
-rw-r--r--src/data-device.c31
-rw-r--r--src/wayland-server.h1
3 files changed, 35 insertions, 19 deletions
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index a33c1d3..45e860a 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -277,18 +277,24 @@
<interface name="wl_data_device" version="1">
<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 timestamp. 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="surface" type="object" interface="wl_surface"/>
+ <arg name="origin" type="object" interface="wl_surface"/>
+ <arg name="icon" type="object" interface="wl_surface"/>
<arg name="time" type="uint"/>
</request>
- <request name="attach">
- <arg name="time" type="uint"/>
- <arg name="buffer" type="object" interface="wl_buffer"/>
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- </request>
-
<request name="set_selection">
<arg name="source" type="object" interface="wl_data_source"/>
<arg name="time" type="uint"/>
diff --git a/src/data-device.c b/src/data-device.c
index 95b1a9d..6c254c7 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -240,7 +240,20 @@ drag_grab_button(struct wl_grab *grab,
if (device->button_count == 0 && state == 0) {
wl_input_device_end_grab(device, time);
+
+ if (device->drag_surface) {
+ struct wl_resource *surface_resource =
+ &device->drag_surface->resource;
+ struct wl_surface_interface *implementation =
+ (struct wl_surface_interface *)
+ surface_resource->object.implementation;
+
+ implementation->attach(surface_resource->client,
+ surface_resource, NULL, 0, 0);
+ }
+
device->drag_data_source = NULL;
+ device->drag_surface = NULL;
}
}
@@ -253,26 +266,23 @@ static const struct wl_grab_interface drag_grab_interface = {
static void
data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
struct wl_resource *source_resource,
- struct wl_resource *surface_resource, uint32_t time)
+ struct wl_resource *origin_resource,
+ struct wl_resource *icon_resource, uint32_t time)
{
struct wl_input_device *device = resource->data;
- /* FIXME: Check that client has implicit grab on the surface
- * that matches the given time. */
+ /* FIXME: Check that client has implicit grab on the origin
+ * surface that matches the given time. */
/* FIXME: Check that the data source type array isn't empty. */
device->drag_grab.interface = &drag_grab_interface;
device->drag_data_source = source_resource->data;
- wl_input_device_start_grab(device, &device->drag_grab, time);
-}
+ if (icon_resource)
+ device->drag_surface = icon_resource->data;
-static void
-data_device_attach(struct wl_client *client, struct wl_resource *resource,
- uint32_t time,
- struct wl_resource *buffer, int32_t x, int32_t y)
-{
+ wl_input_device_start_grab(device, &device->drag_grab, time);
}
static void
@@ -347,7 +357,6 @@ data_device_set_selection(struct wl_client *client,
static const struct wl_data_device_interface data_device_interface = {
data_device_start_drag,
- data_device_attach,
data_device_set_selection,
};
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 53f918c..0bc6c7a 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -212,6 +212,7 @@ struct wl_input_device {
struct wl_resource *drag_focus_resource;
struct wl_listener drag_focus_listener;
struct wl_grab drag_grab;
+ struct wl_surface *drag_surface;
struct wl_data_source *selection_data_source;
struct wl_listener selection_data_source_listener;