<div dir="ltr"><div>I think everybody is waiting for an explanation as to why one of the clients cannot choose the action, and instead the compositor does it.<br><br></div><div>You are defining a function f(S,D,M) that takes three inputs and returns a selected action. The three inputs are the set of actions from the source (S), the set of actions from the destination (D), and the modifiers (M). The design you are proposing is:<br><br></div><div> Source sends S to compositor<br></div><div> Dest sends D to compositor<br></div><div> Compositor knows M and performs A=f(S,D,M)<br></div><div> Compositor sends A to source<br></div><div> Compositor sends D to dest<br><br></div><div>What I propose is:<br><br></div><div> Source sends S to compositor<br></div><div> Compositor sends S to dest<br></div><div> Compositor sends M to dest (probably by giving it keyboard focus)<br></div><div> Dest knows D and performs A=f(S,D,M)<br></div><div> Dest sends A to compositor<br></div><div> Compositor sends A to source<br><br></div><div>I believe this is what most everybody here is proposing, though I think some are considering the source doing the work instead.<br><br></div><div>I really dislike the idea that the definition of f(S,D,M) is in the compositor. It should be in the clients.<br><br>Can you please give an example of why you think this is absolutely 
necessary. There are some vague indications that you feel this is required to emulate XDND but I really don't see it, as any necessary logic can be in the XWayland "client" (ie what is between an X client and the Wayland compositor). XDND may dictate what parts are done by the source and dest but I cannot see any reason it could dictate that the compositor has to do it.<br><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 9, 2015 at 9:55 AM, Carlos Garnacho <span dir="ltr"><<a href="mailto:carlosg@gnome.org" target="_blank">carlosg@gnome.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">These 2 requests have been added:<br>
<br>
</span>- wl_data_source.set_actions: Notifies the compositor of the available<br>
<span class="">  actions on the data source.<br>
</span>- wl_data_offer.set_actions: Notifies the compositor of the available<br>
<span class="">  actions on the destination side, plus the preferred action.<br>
<br>
Out of the data from these requests, the compositor can determine the action<br>
</span>both parts agree on (and let the user play a role through eg. keyboard<br>
<span class="">modifiers). The chosen option will be notified to both parties<br>
</span><span class="">through the following two requests:<br>
<br>
- wl_data_source.action<br>
- wl_data_offer.action<br>
<br>
</span>In addition, the destination side can peek the source side actions through<br>
wl_data_offer.source_actions.<br>
<br>
In order to complete the information about the DnD progress on the source<br>
side, the following 2 wl_data_source events have been added too:<br>
<br>
- wl_data_source.drop_performed: Received when the operation physically<br>
  finishes (eg. the button is released), this can be used to undo any<br>
  state resulting from the initial button press.<br>
- wl_data_source.drag_finished: Received when the destination side<br>
  destroys the wl_data_offer, at which point the source can just ditch<br>
  all related data as well.<br>
<br>
As a result of all of this, the semantics of wl_data_source.cancelled<br>
have been defined better, so it is clearer when this needs to be emitted.<br>
<span class=""><br>
Compared to the XDND protocol, there is one notable change: XDND lets the<br>
source suggest an action, whereas wl_data_device lets the destination<br>
prefer a given action. The difference is subtle here, it comes off as<br>
convenience because it is the drag destination which receives the motion<br>
events (unlike in X) and can perform action updates.<br>
<br>
The drag destination seems also in a better position to update the<br>
preferred action based on things like the data being transferred, the<br>
place being dropped, and whether the drag is client-local.<br>
<br>
</span><span class="">Roughly based on previous work by Giulio Camuffo <<a href="mailto:giuliocamuffo@gmail.com">giuliocamuffo@gmail.com</a>><br>
<br>
</span>Changes since v2:<br>
- Renamed notify_actions to set_actions on both sides, seems more consistent<br>
  with the rest of the protocol.<br>
- Spelled out better which events may be triggered on the compositor side<br>
  by the requests, the circumstances in which events are emitted, and<br>
  what are events useful for in clients.<br>
- Defined a minimal common ground wrt compositor-side action picking and<br>
  keybindings.<br>
- Acknowledge the possibility of compositor/toolkit defined actions, even<br>
  though none are used at the moment.<br>
<span class="">Changes since v1:<br>
- Added wl_data_offer.source_actions to let know of the actions offered<br>
  by a data source.<br>
- Renamed wl_data_source.finished to "drag_finished" for clarity<br>
- Improved wording as suggested by Bryce<br>
<br>
Signed-off-by: Carlos Garnacho <<a href="mailto:carlosg@gnome.org">carlosg@gnome.org</a>><br>
---<br>
</span> protocol/wayland.xml | 161 +++++++++++++++++++++++++++++++++++++++++++++++++--<br>
 1 file changed, 155 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/protocol/wayland.xml b/protocol/wayland.xml<br>
index f52677f..c3b8ae4 100644<br>
<span class="">--- a/protocol/wayland.xml<br>
+++ b/protocol/wayland.xml<br>
@@ -408,7 +408,7 @@<br>
   </interface><br>
<br>
<br>
-  <interface name="wl_data_offer" version="1"><br>
+  <interface name="wl_data_offer" version="3"><br>
     <description summary="offer to transfer data"><br>
       A wl_data_offer represents a piece of data offered for transfer<br>
       by another client (the source client).  It is used by the<br>
</span>@@ -461,9 +461,55 @@<br>
<span class=""><br>
       <arg name="mime_type" type="string"/><br>
     </event><br>
+<br>
+    <!-- Version 3 additions --><br>
+<br>
+    <event name="source_actions" since="3"><br>
+      <description summary="notify the source-side available actions"><br>
</span>+        This event indicates the actions offered by the data source. It<br>
+        will be sent right after data_device.enter, or anytime the source<br>
+        side changes its offered actions through data_source.set_actions.<br>
<span class="">+      </description><br>
+      <arg name="source_actions" type="uint"/><br>
+    </event><br>
+<br>
+    <event name="action" since="3"><br>
+      <description summary="notify the selected action"><br>
</span>+        This event indicates the action selected by the compositor after<br>
+        matching the source/destination side actions. Only one action (or<br>
+        none) will be offered here.<br>
+<br>
+        This event can be emitted multiple times during the drag-and-drop<br>
+        operation, mainly in response to source side changes (through<br>
+        data_source.set_actions), destination side changes (through<br>
+        data_offer.set_actions), and as pointer enters/leaves surfaces.<br>
+<br>
+        Compositors may also change the selected action on the fly, mainly<br>
+        in response to keyboard modifier changes during the drag-and-drop<br>
+        operation.<br>
+<br>
<span class="">+        The most recent action received is always the valid one.<br>
+      </description><br>
+      <arg name="dnd_action" type="uint"/><br>
+    </event><br>
+<br>
</span>+    <request name="set_actions" since="3"><br>
+      <description summary="set the available/preferred drag-and-drop actions"><br>
+        Sets the actions that the destination side client supports for<br>
+        this operation. This request may trigger the emission of<br>
+        data_source.action and data_offer.action events if the compositor<br>
+        needs changing the selected action.<br>
+<br>
+        This request can be called multiple times throughout the<br>
+        drag-and-drop operation, typically in response to data_device.enter<br>
+        or data_device.motion events.<br>
<span class="">+      </description><br>
+      <arg name="dnd_actions" type="uint"/><br>
+      <arg name="preferred_action" type="uint"/><br>
+    </request><br>
   </interface><br>
<br>
-  <interface name="wl_data_source" version="1"><br>
+  <interface name="wl_data_source" version="3"><br>
     <description summary="offer to transfer data"><br>
       The wl_data_source object is the source side of a wl_data_offer.<br>
       It is created by the source client in a data transfer and<br>
</span>@@ -510,14 +556,77 @@<br>
<span class=""><br>
     <event name="cancelled"><br>
       <description summary="selection was cancelled"><br>
-       This data source has been replaced by another data source.<br>
-       The client should clean up and destroy this data source.<br>
+        This data source is no longer valid. There are several reasons why<br>
</span>+        this could happen:<br>
<span class="">+<br>
+        - The data source has been replaced by another data source.<br>
+        - The drop operation finished, but the drop destination did not<br>
</span>+          accept any of the mimetypes offered through data_source.target.<br>
<span class="">+        - The drop operation finished, but the drop destination did not<br>
</span>+          select any action present in the mask offered through<br>
<span class="">+          data_source.action.<br>
+<br>
+        The client should clean up and destroy this data source.<br>
       </description><br>
     </event><br>
<br>
+    <!-- Version 3 additions --><br>
+<br>
+    <event name="action" since="3"><br>
+      <description summary="notify the selected action"><br>
</span>+        This event indicates the action selected by the compositor after<br>
+        matching the source/destination side actions. Only one action (or<br>
+        none) will be offered here.<br>
+<br>
+        This event can be emitted multiple times during the drag-and-drop<br>
+        operation, mainly in response to source side changes (through<br>
+        data_source.set_actions), destination side changes (through<br>
+        data_offer.set_actions), and as pointer enters/leaves surfaces.<br>
+<br>
+        Compositors may also change the selected action on the fly, mainly<br>
+        in response to keyboard modifier changes during the drag-and-drop<br>
+        operation.<br>
+<br>
<span class="">+        The most recent action received is always the valid one.<br>
+<br>
</span>+        Clients can trigger cursor surface changes from this point, so<br>
+        they reflect the current action.<br>
+      </description><br>
<span class="">+      <arg name="dnd_action" type="uint"/><br>
+    </event><br>
+<br>
</span>+    <request name="set_actions" since="3"><br>
+      <description summary="set the available drag-and-drop actions"><br>
+        Sets the actions that the source side client supports for this<br>
+        operation. This request may trigger a data_source.action event and<br>
+        data_offer.action events if the compositor needs changing the<br>
+        selected action.<br>
<span class="">+      </description><br>
+      <arg name="dnd_actions" type="uint"/><br>
+    </request><br>
+<br>
+    <event name="drop_performed" since="3"><br>
</span>+      <description summary="the drag-and-drop operation physically finished"><br>
<span class="">+        The user dropped this data onto an accepting destination. Note<br>
</span>+        that the data_source will be used further in the future (either<br>
+        immediately, or in a delayed manner on "ask" actions) and should<br>
+        not be destroyed here.<br>
<span class="">+      </description><br>
+    </event><br>
+<br>
+    <event name="drag_finished" since="3"><br>
</span>+      <description summary="the drag-and-drop operation finished"><br>
+        The drop destination finished interoperating with this data<br>
+        source, the client is now free to destroy this data source and<br>
+        free all associated data.<br>
+<br>
+        Clients can also trigger the deletion of source-side data on<br>
+        "move" drag-and-drop operations.<br>
<span class="">+      </description><br>
+    </event><br>
   </interface><br>
<br>
-  <interface name="wl_data_device" version="2"><br>
+  <interface name="wl_data_device" version="3"><br>
     <description summary="data transfer device"><br>
       There is one wl_data_device per seat which can be obtained<br>
       from the global wl_data_device_manager singleton.<br>
</span>@@ -659,7 +768,7 @@<br>
<span class="">     </request><br>
   </interface><br>
<br>
-  <interface name="wl_data_device_manager" version="2"><br>
+  <interface name="wl_data_device_manager" version="3"><br>
     <description summary="data transfer interface"><br>
       The wl_data_device_manager is a singleton global object that<br>
       provides access to inter-client data transfer mechanisms such as<br>
</span>@@ -682,6 +791,46 @@<br>
<span class="">       <arg name="id" type="new_id" interface="wl_data_device"/><br>
       <arg name="seat" type="object" interface="wl_seat"/><br>
     </request><br>
+<br>
+    <!-- Version 3 additions --><br>
+<br>
+    <enum name="dnd_action" since="3"><br>
+      <description summary="drag and drop actions"><br>
+        This is a bitmask of the available/preferred actions in a<br>
</span>+        drag-and-drop operation.<br>
+<br>
+        The current reserved ranges are:<br>
+<br>
+        0x0000 - 0x00FF: Reserved for the wayland core protocol.<br>
+        0x01FF - 0xFFFF: Reserved for future toolkit-specific use. Slots<br>
+                         may be reserved.<br>
+<br>
+        In the compositor, the selected action comes out as a result of<br>
+        matching the actions offered by the source and destination sides,<br>
+        "action" events with a "none" action will be sent to both source<br>
+        and destination if there is no match. All further checks will<br>
+        effectively happen on (source_actions &amp; dest_actions).<br>
+<br>
+        In addition, compositors may also pick different actions in<br>
+        reaction to key modifiers being pressed, one common ground that<br>
+        has been present in major toolkits (and the behavior recommended<br>
+        for compositors) is:<br>
+<br>
+        - If no modifiers are pressed, the first match (in bit order)<br>
+          will be used.<br>
+        - Pressing Shift selects "move", if enabled in the mask.<br>
+        - Pressing Control selects "copy", if enabled in the mask.<br>
+<br>
+        Behavior beyond that is considered implementation-dependent.<br>
+        Compositors may for example bind other modifiers (like Alt/Meta)<br>
+        or drags initiated with other buttons than BTN_LEFT to specific<br>
+        actions (eg. "ask", or the next match after move/copy).<br>
+      </description><br>
+      <entry name="none" value="0"/><br>
<span class="">+      <entry name="copy" value="1"/><br>
+      <entry name="move" value="2"/><br>
+      <entry name="ask" value="4"/><br>
+    </enum><br>
   </interface><br>
<br>
   <interface name="wl_shell" version="1"><br>
--<br>
</span>2.4.2<br>
<div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</div></div></blockquote></div><br></div>