[PATCH v4] protocol: Add DnD actions

Carlos Garnacho carlosg at gnome.org
Fri Oct 30 13:57:05 PDT 2015


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 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>
---
 protocol/wayland.xml | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 477ef55..80e1140 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -463,6 +463,56 @@
 
       <arg name="mime_type" type="string"/>
     </event>
+
+    <!-- Version 3 additions -->
+
+    <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 data_device.enter, or anytime the source
+	side changes its offered actions through 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
+	data_source.set_actions), destination side changes (through
+	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.
+      </description>
+      <arg name="dnd_action" type="uint"/>
+    </event>
+
+    <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
+	data_source.action and 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 data_device.enter
+	or data_device.motion events.
+
+	This request mandates the final result of the drag-and-drop
+	operation. If the end result is that no action is accepted,
+	the drag source will receive drag_source.cancelled.
+      </description>
+      <arg name="dnd_actions" type="uint"/>
+      <arg name="preferred_action" type="uint"/>
+    </request>
   </interface>
 
   <interface name="wl_data_source" version="3">
@@ -519,6 +569,9 @@
 	- The drag-and-drop operation was performed, but the drop destination
           did not accept any of the mimetypes offered through
           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
+	  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
@@ -548,8 +601,44 @@
 	The drop destination finished interoperating with this data
 	source, the client is now free to destroy this data source and
 	free all associated data.
+
+	Clients can also trigger the deletion of source-side data on
+	"move" drag-and-drop operations.
+      </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
+        data_source.set_actions), destination side changes (through
+        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.
+
+        Clients can trigger cursor surface changes from this point, so
+        they reflect the current action.
       </description>
+      <arg name="dnd_action" type="uint"/>
     </event>
+
+    <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 data_source.action event and
+        data_offer.action events if the compositor needs changing the
+        selected action.
+      </description>
+      <arg name="dnd_actions" type="uint"/>
+    </request>
   </interface>
 
   <interface name="wl_data_device" version="3">
@@ -717,6 +806,46 @@
       <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" since="3">
+      <description summary="drag and drop actions">
+        This is a bitmask of the available/preferred actions in a
+        drag-and-drop operation.
+
+        The current reserved ranges are:
+
+        0x0000 - 0x00FF: Reserved for the wayland core protocol.
+        0x01FF - 0xFFFF: Reserved for future toolkit-specific use. Slots
+                         may be reserved.
+
+        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 & dest_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 (eg. "ask", or an hypothetical toolkit-specific action).
+      </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



More information about the wayland-devel mailing list