[PATCH weston] data-device: Implement DnD actions
Marek Chalupa
mchqwerty at gmail.com
Thu Mar 19 00:24:10 PDT 2015
Just a cosmetic: there are mixed coding styles like 'function(...)' and
'function (...)' (space between name function and the parenthesis). It
should be unified, preferably to weston (wayland) coding style (no space)
Cheers,
Marek
On Wed, Mar 18, 2015 at 8:20 PM, Bryce Harrington <bryce at osg.samsung.com>
wrote:
> On Mon, Feb 16, 2015 at 04:37:35PM +0100, Carlos Garnacho wrote:
> > The policy in weston in order to determine the chosen DnD action is
> > deliberately simple, and is probably the minimals that any compositor
> > should be doing here.
> >
> > Besides honoring the notify_actions requests on both wl_data_source
> > and wl_data_offer, weston now emits the newly added events notifying
> > both source and dest sides of the chosen action and operation progress.
> >
> > The "dnd" client has been updated too (although minimally), so it
> > notifies the compositor of a "move" action on both sides.
> >
> > Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
>
> Seems like a reasonable implementation of the proposed protocol.
>
> Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
>
> > ---
> > clients/dnd.c | 26 +++++++++++++++-
> > clients/window.c | 17 ++++++++++-
> > src/compositor.h | 5 +++
> > src/data-device.c | 91
> ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> > 4 files changed, 130 insertions(+), 9 deletions(-)
> >
> > diff --git a/clients/dnd.c b/clients/dnd.c
> > index e893d36..c9da1d0 100644
> > --- a/clients/dnd.c
> > +++ b/clients/dnd.c
> > @@ -70,6 +70,7 @@ struct dnd_drag {
> > struct item *item;
> > int x_offset, y_offset;
> > int width, height;
> > + uint32_t dnd_action;
> > const char *mime_type;
> >
> > struct wl_surface *drag_surface;
> > @@ -337,10 +338,31 @@ data_source_cancelled(void *data, struct
> wl_data_source *source)
> > free(dnd_drag);
> > }
> >
> > +static void
> > +data_source_action(void *data, struct wl_data_source *source, uint32_t
> dnd_action)
> > +{
> > + struct dnd_drag *dnd_drag = data;
> > +
> > + dnd_drag->dnd_action = dnd_action;
> > +}
> > +
> > +static void
> > +data_source_drop_performed(void *data, struct wl_data_source *source)
> > +{
> > +}
> > +
> > +static void
> > +data_source_finished(void *data, struct wl_data_source *source)
> > +{
> > +}
> > +
> > static const struct wl_data_source_listener data_source_listener = {
> > data_source_target,
> > data_source_send,
> > - data_source_cancelled
> > + data_source_cancelled,
> > + data_source_action,
> > + data_source_drop_performed,
> > + data_source_finished
> > };
> >
> > static cairo_surface_t *
> > @@ -436,6 +458,8 @@ create_drag_source(struct dnd *dnd,
> >
> window_get_wl_surface(dnd->window),
> > dnd_drag->drag_surface,
> > serial);
> > + wl_data_source_notify_actions (dnd_drag->data_source,
> > +
> WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE);
> >
> > dnd_drag->opaque =
> > create_drag_icon(dnd_drag, item, x, y, 1);
> > diff --git a/clients/window.c b/clients/window.c
> > index c5082ba..fa654df 100644
> > --- a/clients/window.c
> > +++ b/clients/window.c
> > @@ -3320,6 +3320,7 @@ struct data_offer {
> > int fd;
> > data_func_t func;
> > int32_t x, y;
> > + uint32_t dnd_action;
> > void *user_data;
> > };
> >
> > @@ -3333,8 +3334,17 @@ data_offer_offer(void *data, struct wl_data_offer
> *wl_data_offer, const char *ty
> > *p = strdup(type);
> > }
> >
> > +static void
> > +data_offer_action(void *data, struct wl_data_offer *wl_data_offer,
> uint32_t dnd_action)
> > +{
> > + struct data_offer *offer = data;
> > +
> > + offer->dnd_action = dnd_action;
> > +}
> > +
> > static const struct wl_data_offer_listener data_offer_listener = {
> > data_offer_offer,
> > + data_offer_action
> > };
> >
> > static void
> > @@ -3398,6 +3408,11 @@ data_device_enter(void *data, struct
> wl_data_device *data_device,
> > *p = NULL;
> >
> > types_data = input->drag_offer->types.data;
> > + wl_data_offer_notify_actions (offer,
> > +
> WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
> > +
> WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE,
> > +
> WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
> > +
> > } else {
> > input->drag_offer = NULL;
> > types_data = NULL;
> > @@ -5277,7 +5292,7 @@ registry_handle_global(void *data, struct
> wl_registry *registry, uint32_t id,
> > d->shm = wl_registry_bind(registry, id, &wl_shm_interface,
> 1);
> > wl_shm_add_listener(d->shm, &shm_listener, d);
> > } else if (strcmp(interface, "wl_data_device_manager") == 0) {
> > - d->data_device_manager_version = MIN(version, 2);
> > + d->data_device_manager_version = MIN(version, 3);
> > d->data_device_manager =
> > wl_registry_bind(registry, id,
> > &wl_data_device_manager_interface,
> > diff --git a/src/compositor.h b/src/compositor.h
> > index 5c0ea74..0adcde6 100644
> > --- a/src/compositor.h
> > +++ b/src/compositor.h
> > @@ -298,12 +298,17 @@ struct weston_data_offer {
> > struct wl_resource *resource;
> > struct weston_data_source *source;
> > struct wl_listener source_destroy_listener;
> > + uint32_t dnd_actions;
> > + uint32_t preferred_dnd_action;
> > };
> >
> > struct weston_data_source {
> > struct wl_resource *resource;
> > struct wl_signal destroy_signal;
> > struct wl_array mime_types;
> > + struct weston_data_offer *offer;
> > + uint32_t dnd_actions;
> > + uint32_t current_dnd_action;
> >
> > void (*accept)(struct weston_data_source *source,
> > uint32_t serial, const char *mime_type);
> > diff --git a/src/data-device.c b/src/data-device.c
> > index a0913a2..e5fa128 100644
> > --- a/src/data-device.c
> > +++ b/src/data-device.c
> > @@ -84,10 +84,57 @@ data_offer_destroy(struct wl_client *client, struct
> wl_resource *resource)
> > wl_resource_destroy(resource);
> > }
> >
> > +static uint32_t
> > +data_offer_choose_action (struct weston_data_offer *offer)
> > +{
> > + uint32_t available_actions;
> > +
> > + available_actions = offer->dnd_actions &
> offer->source->dnd_actions;
> > +
> > + if (!available_actions)
> > + return 0;
> > +
> > + /* If the dest side has a preferred DnD action, use it */
> > + if ((offer->preferred_dnd_action & available_actions) != 0)
> > + return offer->preferred_dnd_action;
> > +
> > + /* Use the first found action, in bit order */
> > + return 1 << (ffs (available_actions) - 1);
> > +}
> > +
> > +static void
> > +data_offer_update_action (struct weston_data_offer *offer)
> > +{
> > + uint32_t action;
> > +
> > + action = data_offer_choose_action (offer);
> > +
> > + if (offer->source->current_dnd_action == action)
> > + return;
> > +
> > + offer->source->current_dnd_action = action;
> > + wl_data_source_send_action (offer->source->resource, action);
> > + wl_data_offer_send_action (offer->resource, action);
> > +}
> > +
> > +static void
> > +data_offer_notify_actions (struct wl_client *client,
> > + struct wl_resource *resource,
> > + uint32_t dnd_actions,
> > + uint32_t preferred_action)
> > +{
> > + struct weston_data_offer *offer =
> wl_resource_get_user_data(resource);
> > +
> > + offer->dnd_actions = dnd_actions;
> > + offer->preferred_dnd_action = preferred_action;
> > + data_offer_update_action (offer);
> > +}
> > +
> > static const struct wl_data_offer_interface data_offer_interface = {
> > data_offer_accept,
> > data_offer_receive,
> > data_offer_destroy,
> > + data_offer_notify_actions
> > };
> >
> > static void
> > @@ -95,8 +142,14 @@ destroy_data_offer(struct wl_resource *resource)
> > {
> > struct weston_data_offer *offer =
> wl_resource_get_user_data(resource);
> >
> > - if (offer->source)
> > + if (offer->source) {
> > + if (offer->source->offer == offer) {
> > +
> wl_data_source_send_finished(offer->source->resource);
> > + offer->source->offer = NULL;
> > + }
> > +
> > wl_list_remove(&offer->source_destroy_listener.link);
> > + }
> > free(offer);
> > }
> >
> > @@ -124,7 +177,7 @@ weston_data_source_send_offer(struct
> weston_data_source *source,
> >
> > offer->resource =
> > wl_resource_create(wl_resource_get_client(target),
> > - &wl_data_offer_interface, 1, 0);
> > + &wl_data_offer_interface, 3, 0);
> > if (offer->resource == NULL) {
> > free(offer);
> > return NULL;
> > @@ -143,6 +196,9 @@ weston_data_source_send_offer(struct
> weston_data_source *source,
> > wl_array_for_each(p, &source->mime_types)
> > wl_data_offer_send_offer(offer->resource, *p);
> >
> > + data_offer_update_action (offer);
> > + source->offer = offer;
> > +
> > return offer->resource;
> > }
> >
> > @@ -168,9 +224,24 @@ data_source_destroy(struct wl_client *client,
> struct wl_resource *resource)
> > wl_resource_destroy(resource);
> > }
> >
> > +static void
> > +data_source_notify_actions (struct wl_client *client,
> > + struct wl_resource *resource,
> > + uint32_t dnd_actions)
> > +{
> > + struct weston_data_source *source =
> > + wl_resource_get_user_data(resource);
> > +
> > + source->dnd_actions = dnd_actions;
> > +
> > + if (source->offer)
> > + data_offer_update_action (source->offer);
> > +}
> > +
> > static struct wl_data_source_interface data_source_interface = {
> > data_source_offer,
> > - data_source_destroy
> > + data_source_destroy,
> > + data_source_notify_actions
> > };
> >
> > static void
> > @@ -395,8 +466,14 @@ drag_grab_button(struct weston_pointer_grab *grab,
> >
> > if (drag->base.focus_resource &&
> > pointer->grab_button == button &&
> > - state == WL_POINTER_BUTTON_STATE_RELEASED)
> > - wl_data_device_send_drop(drag->base.focus_resource);
> > + state == WL_POINTER_BUTTON_STATE_RELEASED) {
> > + if (drag->base.data_source->current_dnd_action) {
> > +
> wl_data_device_send_drop(drag->base.focus_resource);
> > +
> wl_data_source_send_drop_performed(drag->base.data_source->resource);
> > + } else if (drag->base.data_source) {
> > +
> wl_data_source_send_cancelled(drag->base.data_source->resource);
> > + }
> > + }
> >
> > if (pointer->button_count == 0 &&
> > state == WL_POINTER_BUTTON_STATE_RELEASED) {
> > @@ -851,7 +928,7 @@ create_data_source(struct wl_client *client,
> > wl_array_init(&source->mime_types);
> >
> > source->resource =
> > - wl_resource_create(client, &wl_data_source_interface, 1,
> id);
> > + wl_resource_create(client, &wl_data_source_interface, 3,
> id);
> > wl_resource_set_implementation(source->resource,
> &data_source_interface,
> > source, destroy_data_source);
> > }
> > @@ -937,7 +1014,7 @@ WL_EXPORT int
> > wl_data_device_manager_init(struct wl_display *display)
> > {
> > if (wl_global_create(display,
> > - &wl_data_device_manager_interface, 2,
> > + &wl_data_device_manager_interface, 3,
> > NULL, bind_manager) == NULL)
> > return -1;
> >
> > --
> > 2.1.0
> >
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20150319/7ec7d12a/attachment-0001.html>
More information about the wayland-devel
mailing list