[PATCH wayland] protocol: Improve data source notification around DnD progress

Jonas Ådahl jadahl at gmail.com
Thu Oct 29 21:51:12 PDT 2015


On Thu, Oct 29, 2015 at 05:51:04PM +0100, Carlos Garnacho wrote:
> Hey Jonas!,
> 
> On Thu, Oct 29, 2015 at 9:37 AM, Jonas Ådahl <jadahl at gmail.com> wrote:
> > Hey Carlos,
> >
> > Finally had a look at this one.
> 
> Cheers :)
> 
> >
> > On Wed, Sep 30, 2015 at 10:45:39PM +0200, Carlos Garnacho wrote:
> >> Currently, there's no means for the DnD origin to know whether the
> >> destination is actually finished with the DnD transaction, short of
> >> finalizing it after the first transfer finishes, or leaking it forever.
> >>
> >> But this poses other interoperation problems, drag destinations might
> >> be requesting several mimetypes at once, might be just poking to find
> >> out the most suitable format, might want to defer the action to a popup,
> >> might be poking contents early before the selection was dropped...
> >>
> >> In addition, data_source.cancelled is suitable for the situations where
> >> the DnD operation fails (not on a drop target, no matching mimetypes,
> >> etc..), but seems undocumented for that use (and unused in weston's DnD).
> >>
> >> In order to improve the situation, the drag source should be notified
> >> of all stages of DnD. In addition to documenting the "cancelled" event
> >> for DnD purposes, The following 2 events have been added:
> >>
> >> - wl_data_source.drop_performed: Happens when the operation has been
> >>   physically finished (eg. the button is released), it could be the right
> >>   place to reset the pointer cursor back and undo any other state resulting
> >>   from the initial button press.
> >> - wl_data_source.drag_finished: Happens when the destination side destroys
> >>   the wl_data_offer, at this point the source can just forget all data
> >>   related to the DnD selection as well, plus optionally deleting the data
> >>   on move operations.
> >>
> >> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
> >> ---
> >>  protocol/wayland.xml | 34 +++++++++++++++++++++++++++++-----
> >>  1 file changed, 29 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/protocol/wayland.xml b/protocol/wayland.xml
> >> index 42c9309..1ee143f 100644
> >> --- a/protocol/wayland.xml
> >> +++ b/protocol/wayland.xml
> >> @@ -408,7 +408,7 @@
> >>    </interface>
> >>
> >>
> >> -  <interface name="wl_data_offer" version="1">
> >> +  <interface name="wl_data_offer" version="3">
> >>      <description summary="offer to transfer data">
> >>        A wl_data_offer represents a piece of data offered for transfer
> >>        by another client (the source client).  It is used by the
> >> @@ -463,7 +463,7 @@
> >>      </event>
> >>    </interface>
> >>
> >> -  <interface name="wl_data_source" version="1">
> >> +  <interface name="wl_data_source" version="3">
> >>      <description summary="offer to transfer data">
> >>        The wl_data_source object is the source side of a wl_data_offer.
> >>        It is created by the source client in a data transfer and
> >> @@ -510,14 +510,38 @@
> >>
> >>      <event name="cancelled">
> >>        <description summary="selection was cancelled">
> >> -     This data source has been replaced by another data source.
> >> +     This data source is no longer valid. There are several reasons why
> >> +     this could happen:
> >> +
> >> +     - The data source has been replaced by another data source.
> >> +     - The drop operation finished, but the drop destination did not
> >> +       accept any of the mimetypes offered through data_source.target.
> >> +     - The drop operation finished but didn't happen over a DnD target.
> >
> > That the "operation finished" sounds like the transfer was done as well.
> > "The drop was performed" maybe is better?
> 
> Right, plus the name matches with the event that you'd be expecting otherwise.
> 
> >
> >> +
> >>       The client should clean up and destroy this data source.
> >>        </description>
> >>      </event>
> >>
> >> +    <!-- Version 3 additions -->
> >> +
> >> +    <event name="drop_performed" since="3">
> >> +      <description summary="the drag-and-drop operation physically finished">
> >> +     The user dropped this data onto an accepting destination. Note
> >> +     that the data_source will be used further in the future and should
> >> +     not be destroyed here.
> >> +      </description>
> >> +    </event>
> >
> > I too would like some clarifications why this is needed. The cursor and
> > button state, I assume, could be reset on the next enter or by
> > cancelled/finished, but that the client may want update its UI in some
> > way.
> 
> Yeah, I think that's nice to have, the drag source might enter some
> special UI mode on DnD that has to be reverted after the operation is
> done.
> 
> But this is admittedly non essential information on wayland clients
> done from the ground up. You might consider this similar to how window
> dragging is implemented, where you don't get anything after the button
> press, however there's a difference with DnD face to the traditional
> toolkits: window dragging was already WM territory, toolkits were
> already taught to give up on the implicit grab and let the WM take
> one, but DnD was purely application territory.
> 
> In hindsight (I can just talk for GTK+ tbh) much of the DnD machinery
> should have been hidden at the lowest levels, reality is that DnD is
> driven from a quite high level, more namely the active pointer grab
> used, around which everything revolves for XDND (lifetime included).
> Obviously the longer term goal is to refactor this functionality to a
> lower level, although I'm still scratching my head about how to do in
> a compatible way, and would certainly need assistance to avoid
> breaking other backends than x11/wayland.
> 
> So this x11-style "grab" still happens before start_drag on the
> compositor, all it currently does face to the wayland compositor is
> updating the pointer cursor, but client-side it brings the usual
> grabby effects, input still taken "elsewhere", etc. However, we don't
> have a place to finish this grab, waiting for the next enter event
> strikes me as too late, plus this enter event might be
> undistinguishable from a not-after-dnd one at the windowing layer. It
> is similar for drag_finished, an "ask" action (as per the other patch)
> could trigger a popup, which would mess with this grab state if
> source==dest.

As long as there needs to be no UI/behavioural changes as a result of
ending this grab, ending it at the next 'enter' I guess would be just
fine, but as long as UI needs to react to the drop immediately, it seems
necessary.

> 
> I nonetheless consider this event a nicety to have, not part of the
> basic scaffolding, but IMHO conveys information that may be useful
> besides greedy gtk+ reasons.

Yea, I think that adding protocol for fixable historical toolkit
reasons is undesirable, but I can see why this event may be useful
regardless, so I have no objections.

> 
> >
> > This also, as discussed in another part of this thread, adds
> > requirements on the destination "accepting" an offer. It'd also be good
> > with clarifications about what would happen if a offer accepted an
> > offer at one position, but the drop was performed on another, where the
> > destination do not accept. Would one still get a cancelled then?
> 
> Hmm, I guess there could be a race condition if drag_motion and drop
> happen before the client could accept() in response to drag_motion.
> Emitting cancelled after drop_performed should be in place if we end
> up with accept(null) in the end, this would also be a desirable
> outcome when cancelling popup menus triggered by "ask" actions. I'll
> try to make that clearer in docs.

Should we even always emit the "performed" event, before every cancelled
or finished? Otherwise it'd be a bit undeterministic when to expect it
(depending on the race you described).

> 
> >
> > Maybe also add a paragraph to wl_data_offer.accept?
> 
> Indeed.
> 
> >
> >> +
> >> +    <event name="drag_finished" since="3">
> >> +      <description summary="the drag-and-drop operation finished">
> >> +     The drop destination finished interoperating with this data
> >> +     source, the client is now free to destroy this data source and
> >> +     free all associated data.
> >> +      </description>
> >> +    </event>
> >>    </interface>
> >
> > "drag_" finished sounds a bit odd to me. I guess its meant to namespace
> > the event as a drag-and-drop event?
> 
> Yeah mainly...
> 
> >
> > Correct me if I'm wrong, but this event is meant to be sent after a
> > destination has read all the data it needs, meaning we could effectively
> > send this for regular clipboard sources as well? Then just call it
> > "finished".
> 
> Clipboard offers have a different lifetime, which is "as long as the
> client is focused, or until the focused client replaces the
> clipboard". You could be reusing the same offer multiple times there,
> this is only true to an extent in DnD (which drag_finished precisely
> signals the end for, operations on the DnD offer should only endure
> for a limited time after the drop was performed).

True, so it doesn't make sense because the source is reusable for a
selection, but not for a dnd.

As for nitpicking/bikeshedding, should we just put the drag and drop
specific events behind some "dnd_" prefix, instead of having multiple
prefixes?

dnd_performed I'd read as drag and drop both happened; drop_performed
implicitly means the drag happened as well.

dnd_finished I'd read the same as dnd_performed except that the whole
thing including data transfer has finished, but drag_finished I'd read
as the *drag* finished, whatever that means (finger/pointer stopped?).


Jonas

> 
> >
> > Thats all I have now.
> 
> Thanks :),
>   Carlos


More information about the wayland-devel mailing list