[PATCH] Refine compositor grabs behavior

Daniel Stone daniel at fooishbar.org
Mon Nov 30 23:51:21 PST 2015


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.

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.

Cheers,
Daniel


More information about the wayland-devel mailing list