[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