Use a grab object for drag and drop

dev
Kristian Høgsberg 14 years ago
parent 6d65d5f4d4
commit 287343a0d3
  1. 85
      compositor/compositor.c
  2. 13
      compositor/compositor.h
  3. 15
      wayland/wayland-server.h

@ -571,7 +571,7 @@ move_grab_motion(struct wl_grab *grab,
} }
static void static void
move_grab_end(struct wl_grab *grab) move_grab_end(struct wl_grab *grab, uint32_t time)
{ {
free(grab); free(grab);
} }
@ -655,7 +655,7 @@ resize_grab_motion(struct wl_grab *grab,
} }
static void static void
resize_grab_end(struct wl_grab *grab) resize_grab_end(struct wl_grab *grab, uint32_t time)
{ {
free(grab); 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); time, x, y, sx, sy);
break; 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: default:
/* Other grabs are handled as grab objects. */ /* Other grabs are handled as grab objects. */
break; break;
@ -920,26 +909,16 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
static void static void
wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time) wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time)
{ {
struct wl_drag *drag = device->drag;
struct wlsc_surface *es; struct wlsc_surface *es;
const struct wl_grab_interface *interface; const struct wl_grab_interface *interface;
int32_t sx, sy; int32_t sx, sy;
if (device->grab_object) { if (device->grab_object) {
interface = device->grab_object->interface; interface = device->grab_object->interface;
interface->end(device->grab_object); interface->end(device->grab_object, time);
device->grab_object = NULL; 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); wl_list_remove(&device->grab_listener.link);
device->grab = WLSC_DEVICE_GRAB_NONE; device->grab = WLSC_DEVICE_GRAB_NONE;
es = pick_surface(device, &sx, &sy); es = pick_surface(device, &sx, &sy);
@ -954,7 +933,6 @@ notify_button(struct wlsc_input_device *device,
{ {
struct wlsc_surface *surface; struct wlsc_surface *surface;
struct wlsc_compositor *compositor = device->ec; struct wlsc_compositor *compositor = device->ec;
struct wl_drag *drag = device->drag;
surface = (struct wlsc_surface *) device->input_device.pointer_focus; surface = (struct wlsc_surface *) device->input_device.pointer_focus;
if (!surface) if (!surface)
@ -1000,11 +978,6 @@ notify_button(struct wlsc_input_device *device,
} else if (!state && } else if (!state &&
device->grab != WLSC_DEVICE_GRAB_NONE && device->grab != WLSC_DEVICE_GRAB_NONE &&
device->grab_button == button) { 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); 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); 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 static void
drag_activate(struct wl_client *client, drag_activate(struct wl_client *client,
struct wl_drag *drag, struct wl_drag *drag,
@ -1225,8 +1235,11 @@ drag_activate(struct wl_client *client,
surface, time) < 0) surface, time) < 0)
return; return;
device->grab_object = &drag->grab;
drag->grab.interface = &drag_grab_interface;
drag->grab.input_device = input_device;
drag->source = surface; drag->source = surface;
drag->input_device = input_device;
drag->drag_offer.object.interface = &wl_drag_offer_interface; drag->drag_offer.object.interface = &wl_drag_offer_interface;
drag->drag_offer.object.implementation = drag->drag_offer.object.implementation =
@ -1234,17 +1247,16 @@ drag_activate(struct wl_client *client,
wl_display_add_object(display, &drag->drag_offer.object); wl_display_add_object(display, &drag->drag_offer.object);
device->drag = drag;
target = pick_surface(device, &sx, &sy); 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); device->x, device->y, sx, sy);
} }
static void 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 *device =
(struct wlsc_input_device *) drag->input_device; (struct wlsc_input_device *) drag->grab.input_device;
uint32_t time; uint32_t time;
if (drag->source == NULL || drag->source->client != client) 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(); time = get_time();
wlsc_input_device_end_grab(device, time); wlsc_input_device_end_grab(device, time);
wl_resource_destroy(&drag->resource, client);
} }
static const struct wl_drag_interface drag_interface = { static const struct wl_drag_interface drag_interface = {
drag_offer, drag_offer,
drag_activate, drag_activate,
drag_cancel, drag_destroy,
}; };
void void

@ -81,18 +81,6 @@ enum wlsc_pointer_type {
WLSC_POINTER_IBEAM, 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 wlsc_input_device {
struct wl_input_device input_device; struct wl_input_device input_device;
int32_t x, y; int32_t x, y;
@ -110,7 +98,6 @@ struct wlsc_input_device {
int32_t grab_width, grab_height; int32_t grab_width, grab_height;
int32_t grab_dx, grab_dy; int32_t grab_dx, grab_dy;
uint32_t grab_button; uint32_t grab_button;
struct wl_drag *drag;
struct wl_listener grab_listener; struct wl_listener grab_listener;
}; };

@ -144,18 +144,31 @@ struct wl_visual {
struct wl_object object; 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_drag_offer {
struct wl_object object; struct wl_object object;
}; };
struct wl_drag { struct wl_drag {
struct wl_resource resource; struct wl_resource resource;
struct wl_grab grab;
struct wl_drag_offer drag_offer; struct wl_drag_offer drag_offer;
struct wl_surface *source; struct wl_surface *source;
struct wl_surface *drag_focus; struct wl_surface *drag_focus;
struct wl_client *target; struct wl_client *target;
int32_t x, y, sx, sy; int32_t x, y, sx, sy;
struct wl_input_device *input_device;
struct wl_array types; struct wl_array types;
const char *type; const char *type;
uint32_t pointer_focus_time; uint32_t pointer_focus_time;

Loading…
Cancel
Save