Hey Jonas, Late reply, let's try to pick this up again...
On mar, 2015-04-21 at 14:29 +0800, Jonas Ådahl wrote: > On Sat, Apr 18, 2015 at 04:53:46PM +0200, Carlos Garnacho wrote: > > Hey Jonas, > > Hi, > > Thanks for the explanations. I'll reply inline. > > > > > On vie, 2015-04-17 at 15:50 +0800, Jonas Ådahl wrote: > > > > <snip> > > > > > > > For the touch case, depending on how the grab is implemented, > > > > with > > > > the > > > > current guidelines the only 2 choices are "leave the client in > > > > inconsistent state" or "make the client still receives ongoing > > > > touches > > > > despite the pointer grab" (same applies if the grab is touch > > > > triggered, only with the other touches that didn't trigger the > > > > grab). > > > > > > > > More on topic, keyboards are also funky if we keep focus on > > > > clients, > > > > you can conceivably Esc/Ctrl-Q/... to close the app you're > > > > dragging > > > > from. IMO the way forward is precisely this, the compositor > > > > becomes in > > > > control of the keyboard, and we offer the missing semantics to > > > > cover > > > > for this. > > > > > > Meaning its the compositor that decides whether a drag is a copy > > > or a > > > move? I.e. either we hard code "Ctrl" to be copy in the > > > protocol, or > > > DND > > > will behave different on each compositor. Not sure I like any of > > > those > > > options. > > > > Yes, this would be implementation-dependent in the compositor as > > my > > proposal goes. We have 3 players here, whoever gets to handle the > > modifier->action translation, there's room for confusion in cross- > > DE/toolkit cases. > > The problem as I see it is that it'd be even confusing for DND within > the same application as it would be depending on the DE how it'd > work. > > > > Focusing on actions, I see the following possible data flows here > > (depicting the same situation on all: initial negotiation, changes > > on > > the dest on say pointer motion, and a modifier change): > > > > 1. If handled purely by the source: > > > > wl_data_source compositor wl_data_offer > > ============== ========== ============= > > -> notify_actions <- > > dest_actions <- > > -> preferred_action > > action <- -> action > > > > ... > > (pointer moves across > > widgets) > > notify_actions <- > > dest_actions <- > > -> preferred_action > > action <- -> action > > > > ... > > (modifiers change) > > modifiers <- > > -> preferred_action > > action <- -> action > > > > > > 2. If handled purely by the dest: > > > > wl_data_source compositor wl_data_offer > > ============== ========== ============= > > -> notify_actions > > -> source_actions > > notify_actions <- > > preferred_action <- > > action <- -> action > > > > ... > > (pointer moves across > > widgets) > > notify_actions <- > > preferred_action <- > > action <- -> action > > > > ... > > (modifiers change) > > -> modifiers > > preferred_action <- > > action <- -> action > > > > > > 3. If handled purely by the compositor: > > > > wl_data_source compositor wl_data_offer > > ============== ========== ============= > > -> notify_actions <- > > action <- -> action > > > > ... > > (pointer moves across > > widgets) > > notify_actions <- > > action <- -> action > > > > ... > > (modifiers change) > > action <- -> action > > > > > > Options #1 and #2 involve roundtrips, option #3 doesn't. Options > > #1 > > and #2 would still need some validation on the compositor to avoid > > picking options unknown to either side. > > I think its wrong to refer to these as roundtrips. A roundtrip is > typically a client that need to wait for a reply from a server, but > here > in any of the three options no one is waiting for anything, thus we > have > no round trips at all. Here I was referring to the places where the compositor sends an event to either side, and awaits an immediate reply for it. It is true that those are non blocking, the compositor is free to keep doing stuff in between everywhere else, except wrt the DnD operation. If these don't account as "roundtrips" in your book, I'll call them "avoidable hops" instead :). > The main differences as I see it are: > > In option 1 and 2 we pass an additional modifier state, and make > either > side be responsible for choosing. In option 3 we move this and make > it > compositor choose (either with hard coded policy in the protocol or > some > arbitrary policy given some private state inside the compositor). > > In option 1 and 2, we have a slightly longer delay in visual feedback > regarding the action (caused by the outsourcing of the decision > making). > I'd say these delays are in most cases insignificantly small. In any > solution we end up with latency as we are dealing with 3 entities > communicating asynchronously. Note that option 3 has this delay as > well, > but for chosen mime type visual feedback. TBH, this is something I've only seen on weston-dnd, and I've always thought it's due to the lack of DnD actions. Most normally, you don't care if the drag dest requests plain text, rtf, html or whatnot, you are dragging the same text, and the drag surface is either a surface with that text, or a generic "text" icon. It's been though the cursor surface what has traditionally changed to reflect the action being taken, which should only happen on the wl_data_source.action event handler as per the proposal. > > In option 2, "actions" would be handled identical to mime types. The > modifier change would be semantically equivalent to a motion event. > We'd > have all the decision making (mime type, action) on one side. I > suppose > this should be considered most "consistent" with the existing DND > protocol if that matters in any way. I see your point wrt consistency, although having worked lately on wayland/X11 DnD interoperation on mutter, I see this option very hard to reconcile in that scenario, with both working in its own terms and state machine: - When dragging from X11 to wayland clients, the drag source announces one modifier-induced action in its XdndPosition messages, the drag dest is expecting though .modifier() events in order to pick an action. As long as both parts agree, this is merely awkward/inconvenient. - When dragging from wayland to X11 clients, both sides are left awaiting for the other side to pick an action, so none does in the end, as it's the counterpart which usually would. > > In option 1, we'd be slightly more close to how XDND works, but > splits > the decision making between the two end points which might not be > very > nice. We'd also have one extra (probably also insignificant) delay > since > the compositor needs to make the let the source decide the action > before > performing the drop on the destination. We'd also need to delay the > drop > so the source can make a final decision, which doesn't seem very > nice. > > Assuming the extra visual feedback delay can be considered > insignificant > I think we have 3 major paths to take: > > 1) Actions are chosen arbitrarily by the compositor > 2) Policy is hard coded into the protocol (Ctrl means copy etc) > 3) Pass additional state (modifier) to the decision making client > > Personally, by just looking at how the protocol would look and how > data > would flow, option 3 with the destination making the choice seems to > make most sense to me, since it'd be most consistent with how it > currently works and it doesn't split up the decision making nor add > policy or undefined behavior to the protocol. After some time playing with the different options, I will stand for my v2 proposal as-is. - Passing modifiers to the drag source is completely backwards to the rest of the protocol, passing to the drag dest is more natural protocol -wise, but is unworkable wrt X11 interoperation. - In the "current action is chosen by the compositor" land, I've also tried to streamline action picking on the dest side, so it doesn't have to provide its action mask and does just pick an option, but I always end up seeing one major flaw: the drag destination would receive wl_data_offer.action twice each time the action changes, one as the tentative new action, and another after the drag dest has picked one. We may split that in 2 separate tentative/definitive events, but still doesn't strike me as trivial or race-free, plus we end up with both the compositor and the drag dest trying to retain part of the state in order to avoid messaging ping-pong. It does seem cleaner to me retaining all state in the compositor and only emitting the relevant signals in either way when anything changes. In case anybody wonders how XDND solves this, it demands that every XdndPosition message is replied with a XdndStatus one, and the drag source state machine blocks until this happens, so you can't get DnD started in between, because it's the drag source which decides when does it start. So, for simplicity sake, I'm chosing #2 in your options above, and adding some modifier/button recommendations for compositors. I'll double check the patches and send the necessary updates again. Cheers, Carlos _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
