[PATCH] Refine compositor grabs behavior

Peter Hutterer peter.hutterer at who-t.net
Thu Dec 3 16:49:45 PST 2015


On Tue, Dec 01, 2015 at 07:51:21AM +0000, Daniel Stone wrote:
> Hi,
> 
> On 30 November 2015 at 23:20, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> > On Mon, Nov 30, 2015 at 09:56:16PM +0000, Daniel Stone wrote:
> >> On 23 November 2015 at 00:19, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> >> > double pointer case when split across frames:
> >> > p1.leave, p1.frame, *FOCUS OUT* \
> >> >   p2.leave, p2.frame *FOCUS OUT* \
> >> >   p1.enter, p1.frame *FOCUS IN* \
> >> >   p2.enter, p2.frame *FOCUS IN*
> >> >
> >> > double pointer case merged:
> >> > p1.leave, p1.enter, p1.frame *FOCUS TRANSITIONED* \
> >> >   p2.leave, p2.enter, p2.frame *FOCUS TRANSITIONED*
> >> >
> >> > in the split case, a part of the client can be lagging behind in state,
> >> > there's no time where the pointer is focused on two surfaces. That's not the
> >> > case in the merged case. If we enforce the protocol to this instead:
> >> >
> >> > p1.leave, p2.leave, \
> >> >   p1.enter, p2.enter,\
> >> >   p1.frame *FOCUS TRANSITIONED*, p2.frame *FOCUS TRANSITIONED*
> >> >
> >> > we have the same issue where two surfaces are focused simultaneously though
> >> > at least in this case it's detectable. I don't know how much of an issue
> >> > this is in the real world, Carlos may have more feedback here.
> >>
> >> I've read this a couple of times, trying to get my head around it, and
> >> am failing thus far. Can you please give a slightly longer-winded
> >> explanation for idiots? :)
> >
> > hehe, I'll do my best. Let's assume a client calls wl_seat.get_pointer
> > twice, so you have 2 pointer objects to the same device, p1 and p2.
> > Let's assume that the cursor moves from one surface to the next, generating
> > leave and enter events.
> 
> That helps, thanks!
> 
> > the current implementation of the leave events guarantees to send all leave
> > events before the first pointer event, so you never have a situation where
> > you have focus in two different surfaces. If we look at the events received
> > by the client:
> >    p1.leave
> >    p2.leave
> >    <pointer has no focus>
> >    p1.enter
> >    p2.enter
> >
> > after the first event we have p2 still focused on the surface while p1 has
> > no focus (and the reverse in the enter case) but we never have p1 and p2
> > focused on two different surfaces simultaneously (remember that p1 and p2
> > are the same device). adding frame events immediately after the leave
> > doesn't change anything here:
> >    p1.leave
> >    p1.frame
> >    p2.leave
> >    p2.frame
> >    <pointer has no focus>
> >    p1.enter
> >    p1.frame
> >    p2.enter
> >    p2.frame
> >
> > The question is: can we make the focus transition obvious by packing leave
> > and enter into the same event frame, i.e. leave, enter, frame.
> > the simple implementation would produce the event sequence:
> >   p1.leave
> >   p1.enter
> >   p1.frame
> >   <p1 has different focus now than p2>
> >   p2.leave
> >   p2.enter
> >   p2.frame
> >
> > So there is a point where p1 has moved to a new surface but p2 is still on
> > the old surface and we effectively have two surfaces focused by the same
> > device. That's only for a fraction of a second, the next events would
> > be in the pipe already, but it could confuse a client.
> >
> > One solution is to interleave the two sequences:
> >   p1.leave
> >   p2.leave
> >   p1.enter
> >   p2.enter
> >   p1.frame
> >   <p1 has different focus now than p2>
> >   p2.frame
> >
> > With wl_pointer.frame events we expect clients not to update until they
> > receive the frame event. We still have the same issue as above, there is a
> > point where p1 has a different focus to p2. But in this case it is
> > detectable, the second event frame has started already, a client could
> > recognise this and work around it. Whether clients can and will do this is a
> > different question.
> >
> > So in short, if we want to pack enter/leave events into a frame we get
> > double-focused surfaces and we rely on the clients to work around this. Not
> > an ideal situation.
> 
> To be honest, the disjoint-focus thing happens already with the rest
> of your examples; it's just that it's having a different surface
> focused, rather than no surface focused. For example, if you look at
> the first line of your first example, p1 is unfocused and p2 is
> focused. So already they differ.

yes, the main difference here is that I expect having one surface still
focused and the other out of focus will do less damage than having two
focused at the same time.

> It isn't a big deal anyway though, as you won't get two components
> enough to have different pointer objects, working on the same event
> queue. They'd either process them synchronously, e.g.:
> ----component 1 dispatches queue----
> p1.leave
> p1.enter
> p1.frame
> ----component 1 hands over control to component 2----
> p2.leave
> p2.enter
> p2.frame
> ----both quiescent----
> 
> or do them asynchronously in threads. Neither really present any new
> challenge: with this model, component 1 could already have seen
> (p1.leave, p1.enter) without component 2 having seen anything. So in
> that sense, the ordering of events in the protocol is basically
> irrelevant, given the independent queue dispatch, and you're not
> introducing any new problems here.

is this a guarantee or a "sane clients won't do this"? :)
then again, I guess we shouldn't optimise for clients that do crazy stuff.

Cheers,
   Peter


More information about the wayland-devel mailing list