[PATCH weston 2/5] data-device: Implement DnD actions

Carlos Garnacho carlosg at gnome.org
Wed Dec 16 07:26:56 PST 2015


Hey,

On Wed, Dec 16, 2015 at 3:37 AM, Jonas Ã…dahl <jadahl at gmail.com> wrote:
> On Tue, Dec 15, 2015 at 06:56:23PM +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 set_actions requests on both wl_data_source and
>> wl_data_offer, weston now will emit the newly added "action" events
>> notifying both source and dest of the chosen action.
>>
>> The "dnd" client has been updated too (although minimally), so it
>> notifies the compositor of a "move" action on both sides.
>>
>> Changes since v3:
>>   - Put data_source.action to use in the dnd client, now updates
>>     the dnd surface like data_source.target events do.
>>
>> Changes since v2:
>>   - Split from DnD progress notification changes.
>>
>> Changes since v1:
>>   - Updated to v2 of DnD actions protocol changes, implement
>>     wl_data_offer.source_actions.
>>   - Fixed coding style issues.
>>
>> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
>> Reviewed-by: Michael Catanzaro <mcatanzaro at igalia.com>
>> ---
>>  clients/dnd.c     | 32 ++++++++++++++++++++----
>>  clients/window.c  | 25 +++++++++++++++++++
>>  src/compositor.h  |  4 +++
>>  src/data-device.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
>>  4 files changed, 128 insertions(+), 8 deletions(-)
>>
>> diff --git a/clients/dnd.c b/clients/dnd.c
>> index 6c2ed57..4a046b1 100644
>> --- a/clients/dnd.c
>> +++ b/clients/dnd.c
>> @@ -72,6 +72,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;
>> @@ -266,16 +267,13 @@ dnd_get_item(struct dnd *dnd, int32_t x, int32_t y)
>>  }
>>
>>  static void
>> -data_source_target(void *data,
>> -                struct wl_data_source *source, const char *mime_type)
>> +dnd_drag_update_surface(struct dnd_drag *dnd_drag)
>>  {
>> -     struct dnd_drag *dnd_drag = data;
>>       struct dnd *dnd = dnd_drag->dnd;
>>       cairo_surface_t *surface;
>>       struct wl_buffer *buffer;
>>
>> -     dnd_drag->mime_type = mime_type;
>> -     if (mime_type)
>> +     if (dnd_drag->mime_type && dnd_drag->dnd_action)
>>               surface = dnd_drag->opaque;
>>       else
>>               surface = dnd_drag->translucent;
>> @@ -288,6 +286,16 @@ data_source_target(void *data,
>>  }
>>
>>  static void
>> +data_source_target(void *data,
>> +                struct wl_data_source *source, const char *mime_type)
>> +{
>> +     struct dnd_drag *dnd_drag = data;
>> +
>> +     dnd_drag->mime_type = mime_type;
>> +     dnd_drag_update_surface(dnd_drag);
>> +}
>> +
>> +static void
>>  data_source_send(void *data, struct wl_data_source *source,
>>                const char *mime_type, int32_t fd)
>>  {
>> @@ -360,12 +368,22 @@ data_source_drag_finished(void *data, struct wl_data_source *source)
>>       destroy_dnd_drag(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;
>> +     dnd_drag_update_surface(dnd_drag);
>> +}
>> +
>>  static const struct wl_data_source_listener data_source_listener = {
>>       data_source_target,
>>       data_source_send,
>>       data_source_cancelled,
>>       data_source_drop_performed,
>>       data_source_drag_finished,
>> +     data_source_action,
>>  };
>>
>>  static cairo_surface_t *
>> @@ -428,6 +446,8 @@ create_drag_source(struct dnd *dnd,
>>               dnd_drag->item = item;
>>               dnd_drag->x_offset = x - item->x;
>>               dnd_drag->y_offset = y - item->y;
>> +             dnd_drag->dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
>
> This made me think of another issue. Here we default to the "move"
> action. Are we guaranteed to always receive an wl_data_source.action
> event before the drop is performed? What if the sides don't have enough
> time to set their supported actions, what will we always get a "none"
> action sent?

The first wl_data_source.set_actions call should happen before or
together with .start_drag(), and the first wl_data_offer.set_actions
should happen in response to wl_data_device.enter, AFAICT there's no
room for that to happen, either the surface doesn't have the pointer
focus yet, or it was focused and has acknowledged a set of actions. As
a side effect, an .action event on both sides is expected to happen
soon after the data device enters a surface.

But yes, if either side fails to report the allowed actions, the
resulting effect should be "none" because (source_actions &
dest_actions) == 0

>
> I guess this should be specified in the protocol, and reflected here. I
> assume "move" is the default for version < 3 objects though.

Yup, exactly. I'll make it apply to <3 only, now that I'm at versioning.

Cheers,
  Carlos


More information about the wayland-devel mailing list