[PATCH wayland 2/2] protocol: Add DnD actions
Carlos Garnacho
carlosg at gnome.org
Tue Dec 22 03:20:35 PST 2015
Hey!,
On Tue, Dec 22, 2015 at 4:12 AM, Jonas Ådahl <jadahl at gmail.com> wrote:
> On Tue, Dec 22, 2015 at 02:33:33AM +0100, Carlos Garnacho wrote:
>> These 2 requests have been added:
>>
>> - wl_data_source.set_actions: Notifies the compositor of the available
>> actions on the data source.
>> - wl_data_offer.set_actions: Notifies the compositor of the available
>> actions on the destination side, plus the preferred action.
>>
>> Out of the data from these requests, the compositor can determine the action
>> both parts agree on (and let the user play a role through eg. keyboard
>> modifiers). The chosen option will be notified to both parties
>> through the following two requests:
>>
>> - wl_data_source.action
>> - wl_data_offer.action
>>
>> In addition, the destination side can peek the source side actions through
>> wl_data_offer.source_actions.
>>
>> Compared to the XDND protocol, there's two notable changes:
>>
>> - XDND lets the source suggest an action, whereas wl_data_device lets
>> the destination prefer a given action. The difference is subtle here,
>> it comes off as convenience because it is the drag destination which
>> receives the motion events (unlike in X) and can perform action updates.
>>
>> The drag destination seems also in a better position to update the
>> preferred action based on things like the data being transferred, the
>> place being dropped, and whether the drag is client-local.
>>
>> - That same source-side preferred action is used in XDND to convey the
>> modifier-induced action to the drag destination, which would then ack
>> it, or reply with another action that's accepted (or none), this makes
>> the XdndPosition/XdndStatus messaging very verbose, and synchronous
>> because the drag source always needs to know the latest status/action
>> for every position+action sent.
>>
>> Here it's the compositor which takes care of modifiers and matching
>> available/accepted actions, this allows for the signaling to happen
>> only whenever the actions/modifiers change for real.
>>
>> Roughly based on previous work by Giulio Camuffo <giuliocamuffo at gmail.com>
>>
>> Changes since v5:
>> - Applied rewording suggestions from Jonas Ådahl. Dropped slot reservation
>> scheme for actions. Fixed indentation and other minor formatting issues.
>>
>> Changes since v4:
>> - Minor rewording.
>>
>> Changes since v3:
>> - Splitted from DnD progress notification changes.
>> - Further rationales in commit log.
>>
>> Changes since v2:
>> - Renamed notify_actions to set_actions on both sides, seems more consistent
>> with the rest of the protocol.
>> - Spelled out better which events may be triggered on the compositor side
>> by the requests, the circumstances in which events are emitted, and
>> what are events useful for in clients.
>> - Defined a minimal common ground wrt compositor-side action picking and
>> keybindings.
>> - Acknowledge the possibility of compositor/toolkit defined actions, even
>> though none are used at the moment.
>> Changes since v1:
>> - Added wl_data_offer.source_actions to let know of the actions offered
>> by a data source.
>> - Renamed wl_data_source.finished to "drag_finished" for clarity
>> - Improved wording as suggested by Bryce
>>
>> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
>> Reviewed-by: Michael Catanzaro <mcatanzaro at igalia.com>
>> Reviewed-by: Mike Blumenkrantz <zmike at samsung.com>
>
>
>
>> ---
>> protocol/wayland.xml | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 122 insertions(+)
>>
>> diff --git a/protocol/wayland.xml b/protocol/wayland.xml
>> index ae5ef21..001d811 100644
>> --- a/protocol/wayland.xml
>> +++ b/protocol/wayland.xml
>> @@ -486,6 +486,55 @@
>> wl_data_offer.destroy after this one.
>> </description>
>> </request>
>> +
>> + <request name="set_actions" since="3">
>> + <description summary="set the available/preferred drag-and-drop actions">
>> + Sets the actions that the destination side client supports for
>> + this operation. This request may trigger the emission of
>> + wl_data_source.action and wl_data_offer.action events if the compositor
>> + needs changing the selected action.
>> +
>> + This request can be called multiple times throughout the
>> + drag-and-drop operation, typically in response to wl_data_device.enter
>> + or wl_data_device.motion events.
>> +
>> + This request determines the final result of the drag-and-drop
>> + operation. If the end result is that no action is accepted,
>> + the drag source will receive wl_drag_source.cancelled.
>> + </description>
>> + <arg name="dnd_actions" type="uint"/>
>> + <arg name="preferred_action" type="uint"/>
>> + </request>
>> +
>> + <event name="source_actions" since="3">
>> + <description summary="notify the source-side available actions">
>> + This event indicates the actions offered by the data source. It
>> + will be sent right after wl_data_device.enter, or anytime the source
>> + side changes its offered actions through wl_data_source.set_actions.
>> + </description>
>> + <arg name="source_actions" type="uint"/>
>> + </event>
>> +
>> + <event name="action" since="3">
>> + <description summary="notify the selected action">
>> + This event indicates the action selected by the compositor after
>> + matching the source/destination side actions. Only one action (or
>> + none) will be offered here.
>> +
>> + This event can be emitted multiple times during the drag-and-drop
>> + operation, mainly in response to source side changes (through
>> + wl_data_source.set_actions), destination side changes (through
>> + wl_data_offer.set_actions), and as the pointer enters/leaves
>> + surfaces.
>> +
>> + Compositors may also change the selected action on the fly, mainly
>> + in response to keyboard modifier changes during the drag-and-drop
>> + operation.
>> +
>> + The most recent action received is always the valid one.
>
> How can we describe this more precisely? "most recent" is ambigous, and
> it makes it seem possible to have the destination and client o have
> different ideas of what action is actually used.
>
> I suppose it is a bit problematic. For "move"/"copy" it's simpler,
> because no changes will be made after wl_data_device.drop and that
> event could act as a barrier, but for "ask" it is tricky.
>
> When "ask" is used, I assume the destination will call
> wl_data_offer.set_actions to something other than "ask" (this doesn't
> seem spelled out anywhere btw, should probably describe what "ask"
> actually is). After this is done, should the compositor reply with the
> actual action after having made sure the source supports the newly set
> action, with the client waiting for a reply. Or should the destination
> make sure to choose from one of the "source_actions" actions (while the
> compositor would terminate any client choosing an unavailable action)?
>
>> + </description>
>> + <arg name="dnd_action" type="uint"/>
>> + </event>
>> </interface>
>>
>> <interface name="wl_data_source" version="3">
>> @@ -542,6 +591,9 @@
>> - The drag-and-drop operation was performed, but the drop destination
>> did not accept any of the mimetypes offered through
>> wl_data_source.target.
>> + - The drag-and-drop operation was performed, but the drop destination
>> + did not select any action present in the mask offered through
>> + wl_data_source.action.
>> - The drag-and-drop operation was performed but didn't happen over a
>> surface.
>> - The compositor cancelled the drag-and-drop operation (e.g. compositor
>> @@ -557,6 +609,16 @@
>>
>> <!-- Version 3 additions -->
>>
>> + <request name="set_actions" since="3">
>> + <description summary="set the available drag-and-drop actions">
>> + Sets the actions that the source side client supports for this
>> + operation. This request may trigger a wl_data_source.action event and
>> + wl_data_offer.action events if the compositor needs changing the
>> + selected action.
>> + </description>
>> + <arg name="dnd_actions" type="uint"/>
>> + </request>
>> +
>> <event name="dnd_drop_performed" since="3">
>> <description summary="the drag-and-drop operation physically finished">
>> The user performed the drop action. This event does not indicate
>> @@ -576,8 +638,34 @@
>> The drop destination finished interoperating with this data
>> source, the client is now free to destroy this data source and
>> free all associated data.
>> +
>> + If the action used to perform the operation was "move", the
>> + source can now delete the transferred data.
>> </description>
>> </event>
>> +
>> + <event name="action" since="3">
>> + <description summary="notify the selected action">
>> + This event indicates the action selected by the compositor after
>> + matching the source/destination side actions. Only one action (or
>> + none) will be offered here.
>> +
>> + This event can be emitted multiple times during the drag-and-drop
>> + operation, mainly in response to source side changes (through
>> + wl_data_source.set_actions), destination side changes (through
>> + wl_data_offer.set_actions), and as pointer enters/leaves surfaces.
>> +
>> + Compositors may also change the selected action on the fly, mainly
>> + in response to keyboard modifier changes during the drag-and-drop
>> + operation.
>> +
>> + The most recent action received is always the valid one.
>
> Here as well I'd still like to see something more like "the last action
> received before X" to describe what will be the final action. I guess
> it's the last .action event emitted before .send (or .finished if no
> data transfer was made for some odd reason)?
Oh, right, this didn't get much more verbosity... Right, since the
action is to take effect in wl_data_source.dnd_finished, it would be
the last one received at that point, so if a drag-and-drop operation
starts as "ask", and the user selects "move", the action that must
take effect on .dnd_finished is indeed "move".
I've locally added the following blurb to wl_data_source.action:
The most recent action received is always the valid one. The chosen
action may change alongside negotiation (e.g. an "ask" action can turn
into a "move" operation), so the effects of the final action must be
always applied in wl_data_offer.dnd_finished.
And this one to wl_data_offer.action:
The most recent action received is always the valid one. Prior to
receiving wl_data_device.drop, the chosen action may change (e.g.
due to keyboard modifiers being pressed). At the time of receiving
wl_data_device.drop the drag-and-drop destination must honor the
last action received.
Action changes may still happen after wl_data_device.drop,
especially on "ask" actions, where the drag-and-drop destination
may choose another action afterwards. Action changes happening
at this stage are always the result of inter-client negotiation, the
compositor shall no longer be able to induce a different action.
Cheers,
Carlos
More information about the wayland-devel
mailing list