[PATCH wayland v8 2/2] protocol: Add DnD actions

Jonas Ådahl jadahl at gmail.com
Mon Jan 11 00:12:12 PST 2016


On Thu, Dec 24, 2015 at 03:21:11AM +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 v7:
> - Misc changes after updating the progress notification patch.
> 
> Changes since v6:
> - Further explanations on wl_data_source/offer.set_actions, including a
>   description of "ask" actions. Added protocol errors for unknown action
>   values.
> 
> 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>

Looks good to me; this is Reviewed-by: Jonas Ådahl <jadahl at gmail.com>
now. I have one comment asking for clarifications inline, and a few
style nits.

> ---
>  protocol/wayland.xml | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 162 insertions(+), 1 deletion(-)
> 
> diff --git a/protocol/wayland.xml b/protocol/wayland.xml
> index fb81542..4690e0e 100644
> --- a/protocol/wayland.xml
> +++ b/protocol/wayland.xml
> @@ -421,6 +421,10 @@
>      <enum name="error">
>        <entry name="invalid_finish" value="0"
>  	     summary="finish request was called untimely"/>
> +      <entry name="invalid_action_mask" value="1"
> +	     summary="action mask contains invalid values"/>
> +      <entry name="invalid_action" value="2"
> +	     summary="action argument has an invalid value"/>
>      </enum>
>  
>      <request name="accept">
> @@ -495,9 +499,81 @@
>  	It is a client error to perform other requests than
>  	wl_data_offer.destroy after this one. It is also an error to perform
>  	this request after a NULL mime type has been set in
> -	wl_data_offer.accept.
> +	wl_data_offer.accept or no action was received through
> +	wl_data_offer.action.
>        </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.
> +
> +	The dnd_actions argument must contain only values expressed in the
> +	wl_data_device_manager.dnd_actions enum, and the preferred_action
> +	argument must only contain one of those values set, otherwise it
> +	will result in a protocol error.
> +      </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. 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.
> +
> +	Upon "ask" actions, the drag-and-drop destination is expected to
> +	possibly choose different a different action and/or mime type,
> +	based on wl_data_offer.source_actions and finally chosen by the
> +	user (e.g. popping up a menu with the available options). The
> +	final wl_data_offer.set_action and wl_data_offer.accept requests

s/set_action/set_actions/. I think it should be pointed out that only a
single action must be set via set_action at this point and that no more
wl_data_offer.action event will be emitted, but wl_data_source.action
will be, for that change.

> +	must happen before the call to wl_data_offer.finish.
> +      </description>
> +      <arg name="dnd_action" type="uint"/>
> +    </event>
>    </interface>
>  
>    <interface name="wl_data_source" version="3">
> @@ -508,6 +584,11 @@
>        to requests to transfer the data.
>      </description>
>  
> +    <enum name="error">
> +      <entry name="invalid_action_mask" value="0"
> +	     summary="action mask contains invalid values"/>
> +    </enum>
> +
>      <request name="offer">
>        <description summary="add an offered mime type">
>  	This request adds a mime type to the set of mime types
> @@ -554,6 +635,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
> @@ -569,6 +653,20 @@
>  
>      <!-- 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.

s/        /\t/

> +
> +	The dnd_actions argument must contain only values expressed in the
> +	wl_data_device_manager.dnd_actions enum, otherwise it will result
> +	in a protocol error.
> +      </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
> @@ -588,7 +686,36 @@
>  	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. 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.
> +
> +	Clients can trigger cursor surface changes from this point, so
> +	they reflect the current action.
>        </description>
> +      <arg name="dnd_action" type="uint"/>
>      </event>
>    </interface>
>  
> @@ -757,6 +884,40 @@
>        <arg name="id" type="new_id" interface="wl_data_device"/>
>        <arg name="seat" type="object" interface="wl_seat"/>
>      </request>
> +
> +    <!-- Version 3 additions -->
> +
> +    <enum name="dnd_action" bitfield="true" since="3">
> +      <description summary="drag and drop actions">
> +        This is a bitmask of the available/preferred actions in a
> +        drag-and-drop operation.
> +
> +        In the compositor, the selected action comes out as a result of
> +        matching the actions offered by the source and destination sides.
> +        "action" events with a "none" action will be sent to both source
> +        and destination if there is no match. All further checks will
> +        effectively happen on (source actions ∩ destination actions).
> +
> +        In addition, compositors may also pick different actions in
> +        reaction to key modifiers being pressed, one common ground that
> +        has been present in major toolkits (and the behavior recommended
> +        for compositors) is:
> +
> +        - If no modifiers are pressed, the first match (in bit order)
> +          will be used.
> +        - Pressing Shift selects "move", if enabled in the mask.
> +        - Pressing Control selects "copy", if enabled in the mask.
> +
> +        Behavior beyond that is considered implementation-dependent.
> +        Compositors may for example bind other modifiers (like Alt/Meta)
> +        or drags initiated with other buttons than BTN_LEFT to specific
> +        actions (e.g. "ask").

This <description> uses spaces, while the others use tabs.


Jonas

> +      </description>
> +      <entry name="none" value="0"/>
> +      <entry name="copy" value="1"/>
> +      <entry name="move" value="2"/>
> +      <entry name="ask" value="4"/>
> +    </enum>
>    </interface>
>  
>    <interface name="wl_shell" version="1">
> -- 
> 2.5.0
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list