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

Jonas Ådahl jadahl at gmail.com
Sat Jan 16 00:37:20 PST 2016


On Fri, Jan 15, 2016 at 02:49:33PM -0800, Bryce Harrington wrote:
> On Fri, Jan 15, 2016 at 09:11:40PM +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 v10:
> > - Narrow down the situations where wl_data_source/offer.accept requests
> >   are supposed to happen.
> > 
> > Changes since v9:
> > - Deferred the protocol errors to .finish after some IRC chat with Jonas,
> >   added further errors if actions API is used on selection sources/offers.
> > 
> > Changes since v8:
> > - Defined further the expected behavior on "ask", described the protocol
> >   errors that may happen. Fix more spaces vs tabs issues.
> > 
> > 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>
> > Reviewed-by: Jonas Ådahl <jadahl at gmail.com>
> 
> Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>

I have now landed the two protocol patches after having fixed the grammar
nitpicks. Carlos, it'd be good if you could just double check I did the
right choices where there were options.

I'm waiting with the weston patches until Monday or so, so they can get
some more review.


Jonas

> 
> (Again, optional grammar nitpicks below, ok to land as follow up post-alpha.)
> 
> > ---
> >  protocol/wayland.xml | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 204 insertions(+), 1 deletion(-)
> > 
> > diff --git a/protocol/wayland.xml b/protocol/wayland.xml
> > index dc05993..cea65e9 100644
> > --- a/protocol/wayland.xml
> > +++ b/protocol/wayland.xml
> > @@ -421,6 +421,12 @@
> >      <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"/>
> > +      <entry name="invalid_offer" value="3"
> > +	     summary="offer doesn't accept this request"/>
> >      </enum>
> >  
> >      <request name="accept">
> > @@ -495,9 +501,98 @@
> >  	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.
> 
> needs to change
> 
> > +	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.
> > +
> > +	While managing an "ask" action, the destination drag-and-drop client
> > +	may perform further wl_data_offer.receive requests, and is expected
> > +	to perform one last wl_data_offer.set_actions request with a preferred
> > +	action other than "ask" (and optionally wl_data_offer.accept) before
> > +	requesting wl_data_offer.finish, in order to convey the action selected
> > +	by the user. If the preferred action is not in the
> > +	wl_data_offer.source_actions mask, an error will be raised.
> > +
> > +	If the "ask" action is dismissed (e.g. user cancellation), the client
> > +	is expected to perform wl_data_offer.destroy right away.
> > +
> > +	This request can only be made on drag-and-drop offers, a protocol error
> > +	will be raised otherwise.
> > +      </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 in response to destination side action changes through
> > +	wl_data_offer.set_actions.
> > +
> > +	This event will no longer be emitted after wl_data_device.drop
> > +	happened on the drag-and-drop destination, the client must
> > +	honor the last action received, or the last preferred one set
> > +	through wl_data_offer.set_actions when handling an "ask" action.
> > +
> > +	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,
> 
> possibly choose a different action
> 
> Aside: "...expected to possibly choose..." seems grammatically odd,
> since "expected" indicates there is a required choice but "possibly"
> suggests optional choices.  Would the following preserve the meaning but
> with clearer phrasing?
> 
> 	Upon "ask" actions, it is expected that the drag-and-drop destination may
> 	potentially 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_actions and wl_data_offer.accept requests
> > +	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 +603,13 @@
> >        to requests to transfer the data.
> >      </description>
> >  
> > +    <enum name="error">
> > +      <entry name="invalid_action_mask" value="0"
> > +	     summary="action mask contains invalid values"/>
> > +      <entry name="invalid_source" value="1"
> > +	     summary="source doesn't accept this request"/>
> > +    </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 +656,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.
> 
> did not select any of the actions present in the mask
> 
> >  	- 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 +674,25 @@
> >  
> >      <!-- 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.
> 
> This request may trigger wl_data_source.action and wl_data_offer.action
> events if the compositor needs to change the selected action.
> 
> Do both events always get fired together if there is a change?  If not,
> then use "and/or" instead of "and" in the above.
> 
> > +	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.
> > +
> > +	This request has to be made once, and can only be made on sources
> 
> It's unclear if this is saying the request is to be made exactly once,
> or at least once.  So I think this should be either:
> 
> This request must be made once only, and can only be made on sources
> 
> or
> 
> This request must be made at least once, and can only be made on sources
> 
> 
> > +	used in drag-and-drop, so it must be performed before
> > +	wl_data_device.start_drag. Attempting to use the source other than
> > +	for drag-and-drop will raise 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 +712,41 @@
> >  	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 destination side changes through
> > +	wl_data_offer.set_actions, and as the data device enters/leaves
> > +	surfaces.
> > +
> > +	It is only possible to receive this event after
> > +	wl_data_source.dnd_drop_performed if the drag-and-drop operation
> > +	ended in an "ask" action, in which case the final wl_data_source.action
> > +	event will happen immediately before wl_data_source.dnd_finished.
> > +
> > +	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.
> 
> final action must always be applied
> 
> > +
> > +	Clients can trigger cursor surface changes from this point, so
> > +	they reflect the current action.
> >        </description>
> > +      <arg name="dnd_action" type="uint"/>
> >      </event>
> >    </interface>
> >  
> > @@ -705,6 +863,17 @@
> >        <description summary="end drag-and-drag session successfully">
> >  	The event is sent when a drag-and-drop operation is ended
> >  	because the implicit grab is removed.
> > +
> > +	The drag-and-drop destination is expected to honor the last action
> > +	received through wl_data_offer.action, if the resulting action is
> > +	"copy" or "move", the destination can still perform
> > +	wl_data_offer.receive requests, and is expected to end all
> > +	transfers with a wl_data_offer.finish request.
> > +
> > +	If the resulting action is "ask", the action will not be considered
> > +	final. The drag-and-drop destination is expected to perform one last
> > +	wl_data_offer.set_actions request, or wl_data_offer.destroy in order
> > +	to cancel the operation.
> >        </description>
> >      </event>
> >  
> > @@ -757,6 +926,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.
> 
> "comes out" seems a bit colloquial, but perhaps unnecessary anyway?
> 
> 	In the compositor, the selected action is 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
> 
> one common design that is used in major toolkits
> 
> > +	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").
> > +      </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
> _______________________________________________
> 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