From 0510c3a62149d5897c9f04f67614cce4d65153af Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 30 Sep 2014 17:01:43 +0200 Subject: [PATCH] wayland: Keep track of the origin surface and drag point on DnD Keeping track of the surface will be necessary in case it is destroyed during DnD, and the coordinates will be useful when figuring out the snap back coordinates. --- src/wayland/meta-wayland-data-device.c | 48 +++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index ed2e4f85e..ffa8d7d28 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -177,6 +177,11 @@ struct _MetaWaylandDragGrab { MetaWaylandDataSource *drag_data_source; struct wl_listener drag_data_source_listener; + + MetaWaylandSurface *drag_origin; + struct wl_listener drag_origin_listener; + + int drag_start_x, drag_start_y; }; static void @@ -262,6 +267,12 @@ drag_grab_motion (MetaWaylandPointerGrab *grab, static void data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab) { + if (drag_grab->drag_origin) + { + drag_grab->drag_origin = NULL; + wl_list_remove (&drag_grab->drag_origin_listener.link); + } + if (drag_grab->drag_surface) { drag_grab->drag_surface = NULL; @@ -303,6 +314,16 @@ static const MetaWaylandPointerGrabInterface drag_grab_interface = { drag_grab_button, }; +static void +destroy_data_device_origin (struct wl_listener *listener, void *data) +{ + MetaWaylandDragGrab *drag_grab = + wl_container_of (listener, drag_grab, drag_origin_listener); + + drag_grab->drag_origin = NULL; + data_device_end_drag_grab (drag_grab); +} + static void destroy_data_device_source (struct wl_listener *listener, void *data) { @@ -331,12 +352,20 @@ data_device_start_drag (struct wl_client *client, { MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource); MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); + MetaWaylandSurface *surface = NULL; MetaWaylandDragGrab *drag_grab; + ClutterPoint pos; - if ((seat->pointer.button_count == 0 || - seat->pointer.grab_serial != serial || - !seat->pointer.focus_surface || - seat->pointer.focus_surface != wl_resource_get_user_data (origin_resource))) + if (origin_resource) + surface = wl_resource_get_user_data (origin_resource); + + if (!surface) + return; + + if (seat->pointer.button_count == 0 || + seat->pointer.grab_serial != serial || + !seat->pointer.focus_surface || + seat->pointer.focus_surface != surface) return; /* FIXME: Check that the data source type array isn't empty. */ @@ -353,6 +382,17 @@ data_device_start_drag (struct wl_client *client, drag_grab->drag_client = client; drag_grab->seat = seat; + drag_grab->drag_origin = surface; + drag_grab->drag_origin_listener.notify = destroy_data_device_origin; + wl_resource_add_destroy_listener (origin_resource, + &drag_grab->drag_origin_listener); + + clutter_input_device_get_coords (seat->pointer.device, NULL, &pos); + clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)), + pos.x, pos.y, &pos.x, &pos.y); + drag_grab->drag_start_x = pos.x; + drag_grab->drag_start_y = pos.y; + if (source_resource) { drag_grab->drag_data_source = wl_resource_get_user_data (source_resource);