From 287343a0d36de3cef67d9527f15d968b01a37544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 7 Dec 2010 14:58:57 -0500 Subject: [PATCH] Use a grab object for drag and drop --- compositor/compositor.c | 85 +++++++++++++++++++++++----------------- compositor/compositor.h | 13 ------ wayland/wayland-server.h | 15 ++++++- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/compositor/compositor.c b/compositor/compositor.c index cea88c9b..5c94d325 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -571,7 +571,7 @@ move_grab_motion(struct wl_grab *grab, } static void -move_grab_end(struct wl_grab *grab) +move_grab_end(struct wl_grab *grab, uint32_t time) { free(grab); } @@ -655,7 +655,7 @@ resize_grab_motion(struct wl_grab *grab, } static void -resize_grab_end(struct wl_grab *grab) +resize_grab_end(struct wl_grab *grab, uint32_t time) { free(grab); } @@ -894,17 +894,6 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y) time, x, y, sx, sy); break; - case WLSC_DEVICE_GRAB_DRAG: - es = pick_surface(device, &sx, &sy); - wl_drag_set_pointer_focus(device->drag, - &es->surface, time, x, y, sx, sy); - if (es) - wl_client_post_event(es->surface.client, - &device->drag->drag_offer.object, - WL_DRAG_OFFER_MOTION, - time, x, y, sx, sy); - break; - default: /* Other grabs are handled as grab objects. */ break; @@ -920,26 +909,16 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y) static void wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time) { - struct wl_drag *drag = device->drag; struct wlsc_surface *es; const struct wl_grab_interface *interface; int32_t sx, sy; if (device->grab_object) { interface = device->grab_object->interface; - interface->end(device->grab_object); + interface->end(device->grab_object, time); device->grab_object = NULL; } - switch (device->grab) { - case WLSC_DEVICE_GRAB_DRAG: - wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0); - device->drag = NULL; - break; - default: - break; - } - wl_list_remove(&device->grab_listener.link); device->grab = WLSC_DEVICE_GRAB_NONE; es = pick_surface(device, &sx, &sy); @@ -954,7 +933,6 @@ notify_button(struct wlsc_input_device *device, { struct wlsc_surface *surface; struct wlsc_compositor *compositor = device->ec; - struct wl_drag *drag = device->drag; surface = (struct wlsc_surface *) device->input_device.pointer_focus; if (!surface) @@ -1000,11 +978,6 @@ notify_button(struct wlsc_input_device *device, } else if (!state && device->grab != WLSC_DEVICE_GRAB_NONE && device->grab_button == button) { - drag = device->drag; - if (drag && drag->target) - wl_client_post_event(drag->target, - &drag->drag_offer.object, - WL_DRAG_OFFER_DROP); wlsc_input_device_end_grab(device, time); } } @@ -1209,6 +1182,43 @@ drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type) wl_client_post_no_memory(client); } +static void +drag_grab_motion(struct wl_grab *grab, + uint32_t time, int32_t x, int32_t y) +{ + struct wl_drag *drag = container_of(grab, struct wl_drag, grab); + struct wlsc_input_device *device = + (struct wlsc_input_device *) grab->input_device; + struct wlsc_surface *es; + int32_t sx, sy; + + es = pick_surface(device, &sx, &sy); + wl_drag_set_pointer_focus(drag, &es->surface, time, x, y, sx, sy); + if (es) + wl_client_post_event(es->surface.client, + &drag->drag_offer.object, + WL_DRAG_OFFER_MOTION, + time, x, y, sx, sy); +} + +static void +drag_grab_end(struct wl_grab *grab, uint32_t time) +{ + struct wl_drag *drag = container_of(grab, struct wl_drag, grab); + + if (drag->target) + wl_client_post_event(drag->target, + &drag->drag_offer.object, + WL_DRAG_OFFER_DROP); + + wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0); +} + +static const struct wl_grab_interface drag_grab_interface = { + drag_grab_motion, + drag_grab_end +}; + static void drag_activate(struct wl_client *client, struct wl_drag *drag, @@ -1225,8 +1235,11 @@ drag_activate(struct wl_client *client, surface, time) < 0) return; + device->grab_object = &drag->grab; + drag->grab.interface = &drag_grab_interface; + drag->grab.input_device = input_device; + drag->source = surface; - drag->input_device = input_device; drag->drag_offer.object.interface = &wl_drag_offer_interface; drag->drag_offer.object.implementation = @@ -1234,17 +1247,16 @@ drag_activate(struct wl_client *client, wl_display_add_object(display, &drag->drag_offer.object); - device->drag = drag; target = pick_surface(device, &sx, &sy); - wl_drag_set_pointer_focus(device->drag, &target->surface, time, + wl_drag_set_pointer_focus(drag, &target->surface, time, device->x, device->y, sx, sy); } static void -drag_cancel(struct wl_client *client, struct wl_drag *drag) +drag_destroy(struct wl_client *client, struct wl_drag *drag) { struct wlsc_input_device *device = - (struct wlsc_input_device *) drag->input_device; + (struct wlsc_input_device *) drag->grab.input_device; uint32_t time; if (drag->source == NULL || drag->source->client != client) @@ -1252,12 +1264,13 @@ drag_cancel(struct wl_client *client, struct wl_drag *drag) time = get_time(); wlsc_input_device_end_grab(device, time); + wl_resource_destroy(&drag->resource, client); } static const struct wl_drag_interface drag_interface = { drag_offer, drag_activate, - drag_cancel, + drag_destroy, }; void diff --git a/compositor/compositor.h b/compositor/compositor.h index 74eea004..28f2ed1a 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -81,18 +81,6 @@ enum wlsc_pointer_type { WLSC_POINTER_IBEAM, }; -struct wl_grab; -struct wl_grab_interface { - void (*motion)(struct wl_grab *grab, - uint32_t time, int32_t x, int32_t y); - void (*end)(struct wl_grab *grab); -}; - -struct wl_grab { - const struct wl_grab_interface *interface; - struct wl_input_device *input_device; -}; - struct wlsc_input_device { struct wl_input_device input_device; int32_t x, y; @@ -110,7 +98,6 @@ struct wlsc_input_device { int32_t grab_width, grab_height; int32_t grab_dx, grab_dy; uint32_t grab_button; - struct wl_drag *drag; struct wl_listener grab_listener; }; diff --git a/wayland/wayland-server.h b/wayland/wayland-server.h index 3369a532..40f68870 100644 --- a/wayland/wayland-server.h +++ b/wayland/wayland-server.h @@ -144,18 +144,31 @@ struct wl_visual { struct wl_object object; }; +struct wl_grab; +struct wl_grab_interface { + void (*motion)(struct wl_grab *grab, + uint32_t time, int32_t x, int32_t y); + void (*end)(struct wl_grab *grab, uint32_t time); +}; + +struct wl_grab { + const struct wl_grab_interface *interface; + struct wl_input_device *input_device; +}; + + struct wl_drag_offer { struct wl_object object; }; struct wl_drag { struct wl_resource resource; + struct wl_grab grab; struct wl_drag_offer drag_offer; struct wl_surface *source; struct wl_surface *drag_focus; struct wl_client *target; int32_t x, y, sx, sy; - struct wl_input_device *input_device; struct wl_array types; const char *type; uint32_t pointer_focus_time;