[PATCH] Refine compositor grabs behavior

Peter Hutterer peter.hutterer at who-t.net
Mon Nov 30 15:20:09 PST 2015


On Mon, Nov 30, 2015 at 09:56:16PM +0000, Daniel Stone wrote:
> Hi,
> 
> 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.

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.

Cheers,
   Peter



More information about the wayland-devel mailing list