[PATCH weston 14/17] Introduce pointer locking and confinement protocol
jadahl at gmail.com
Mon Dec 8 06:07:44 PST 2014
On Tue, Dec 02, 2014 at 02:39:21PM -0800, Bill Spitzak wrote:
> On 12/02/2014 05:49 AM, Jonas Ådahl wrote:
> >+ <request name="lock_pointer">
> >+ <description summary="lock pointer to a position">
> >+ The lock_pointer request lets the client disable absolute pointer
> >+ movements, locking the pointer to a position.
> >+ There may not be another lock of any kind active when requesting a lock,
> >+ and if there is, an error will be raised.
> >+ The intersection of the region passed with this request and the input
> >+ region of the surface is used to determine where the pointer must be
> >+ in order for the lock to activate. It is up to the compositor to warp
> >+ the pointer, or require some kind of user interaction for the lock to
> >+ activate. If the region is null, then an infinit region is used.
> >+ The request will create a new object wl_locked_pointer which is used to
> >+ interact with the lock as well as receive updates about its state. See
> >+ the the description of wl_locked_pointer for further information.
> >+ Note that while a locked pointer doesn't move its absolute position, it
> >+ may still emit relative motion events via the wl_relative_pointer
> >+ object.
> >+ </description>
> >+ <arg name="id" type="new_id" interface="_wl_locked_pointer"/>
> >+ <arg name="surface" type="object" interface="wl_surface"
> >+ summary="surface to lock pointer to"/>
> >+ <arg name="seat" type="object" interface="wl_seat"
> >+ summary="seat where the pointer should be locked"/>
> >+ <arg name="region" type="object" interface="wl_region" allow-null="true"
> >+ summary="region of surface"/>
> >+ </request>
> - Does this need some id of the triggering event? Mostly to determine if the
> surface had the pointer focus at the time the request was made.
It does not, and the lock is postponed until that trigger event happens.
For example a surface can lock the pointer, but the lock may not
activate until the user clicks the surface. It should not be hard coded
exactly what type of event should trigger a lock.
> A lock that is lost when the mouse button is released might be nice. It
> would be used for the "slow scrollbar" and similar widgets, avoid a
> round-trip on the release event, and would probably share code with normal
> mouse-up handling. I think this could be determined based on what type of
> event triggered the lock.
Don't think it's very beneficial to add various kinds of locks that
unlocks at specific events. The client can simply unlock on mouse
button release. Not sure what round trip you are talking about here, but
the client has no need for doing a round trip for unlocking, it simply
destroys its lock object and when the pointer moves, it'll receive new
> - I am very unclear on what "require some kind of user interaction for the
> lock to activate" means. What I expect is that it will work if and only if
> the surface has the pointer focus. Any "user interaction" has already
> happened (ie they may have moved to another surface). Can somebody explain?
> Or perhaps this is just badly worded.
It simply means that the compositor may, if it wants to, require certain
user interaction, such as clicking, to actually activate the lock. This
is because the compositor might want to avoid letting clients "take" the
lock without any interaction (for example locking on just pointer focus a
surface could steal the cursor when the user just crosses some area of
In the proposed implementation, the heuristics currently are that a lock
is activated on click, or immediately if the surface was already
activated by clicking; but the heuristics could be different from that.
Do you have a suggestion for a better wording?
> - Do not warp the pointer. The pointer should freeze exactly where it is
> (even if outside the region), and only client requests to set the cursor
> position should move it. Any compositor-chosen position may be incorrect and
> will result in a flicker as the cursor is placed in this wrong position
The pointer is only potentially warped when unlocking, and the hint is
used for getting a potentially good position. While locked, the pointer
is not going to move, neither by moving the mouse or setting the hint.
We don't want clients to start assuming they can control the cursor,
that's the job of the compositor.
> - Is the region really necessary? I think it would be easy for a client to
> see that the cursor has moved out of any desired region and just not do this
> request. Also this removes any questions about complex regions.
Locking may only be relevant for a portion of a surface. One might still
want to have usable window decorations for example. Complex regions are
only really hard to deal with for confinement, not for locking.
> > + <request name="set_cursor_position_hint">
> > + <description summary="set the pointer cursor position hint">
> Why is this called a "hint"? This better be a lot stronger than a "hint", it
> is pretty near useless if the cursor does not move to where the client
> wants. It's true that it sometimes won't work (for instance if the lock has
> been lost) but if that was the rule *every* request in Wayland would have to
> be called a "hint"!
> It would be really nice if you removed this excess verbage and called this
> "set_cursor_position" or even "set_position".
> What happens is the compositor cannot set the position, for instance if it
> is off-screen? Does it send a motion event saying where it was really
It's called a hint simply because it only is a hint. It's not the job of
the client to move the cursor around, it's the job of the compositor. We
don't want to make clients assume they can control the cursor but we
still want to enable the client to draw its own cursor and then not have
an awkward warp when unlocking and displaying the real cursor again, and
this is what the hint is for.
> >+ <request name="confine_pointer">
> >+ <description summary="confine pointer to a region">
> >+ The confine_pointer request lets the client confine the pointer cursor
> >+ to a given region.
> I don't think this should be necessary. The plain pointer-lock can be used,
> and the client uses set_cursor_position to do the confinement. And that
> removes any questions about complicated regions.
We don't want clients to control the cursor position. If the client
really wants to be in control, it should lock the pointer, hide the
cursor, and then draw its own cursor sprite, either as part of its own
scene, or as a subsurface. Confinement, however, allows for lower
latency confinement. Consider playing an RTS game; moving the pointer
cursor without having to do an extra round trip via the client to move
the cursor could make the experience better. This cannot be done with
either the client drawing the cursor, or the client setting the cursor
> >+ <event name="locked">
> >+ <description summary="enter event">
> >+ Notification that the pointer lock of this seat's pointer is activated.
> >+ </description>
> Can't this just be assumed by the fact that you created the pointer lock
> object and have not gotten the unlocked event yet?
The lock may be postponed, and this event is used to let the client know
that the lock was actually activated.
> >+ <event name="unlocked">
> >+ <description summary="leave event">
> >+ Notification that the pointer lock of seat's pointer is no longer
> >+ active. This object is no defunct and should be destroyed.
> >+ </description>
> May want to point out that this is also sent immediately if there is a
> failure to get the pointer lock.
This is not the case though. If the lock could not be immediately be
activated, it is postponed until when the compositor thinks it is a good
idea to let the client steal the cursor control.
More information about the wayland-devel