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 <giuliocamu...@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 <carl...@gnome.org> > Reviewed-by: Michael Catanzaro <mcatanz...@igalia.com> > Reviewed-by: Mike Blumenkrantz <zm...@samsung.com>
Looks good to me; this is Reviewed-by: Jonas Ådahl <jad...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel