Pointer lock and warping
Bill Spitzak
spitzak at gmail.com
Mon Apr 22 19:48:14 PDT 2013
Thinking about Todd Showalter's requests for pointer warping, I think in
fact a correctly-behaving Wayland app will always want pointer warping
and incremental update when the mouse is held down. This would require a
major change in the mouse api, though I think the differences in
back-compatibility can be worked around in the client library. This has
the side effect of also getting the "slow scrollbar" effect requested,
and edge resistance, and an equivalent of the pointer-lock proposal into
a single api.
The purpose is to produce non-jittery dragging of objects. If the user
drags an object drawn in the window, if the pointer image and drawn
image move out of sync they will jitter in respect to each other. The
solution is to synchronize the pointer movement with the drawing using
the commit mechanism.
I propose merging the current implicit grab on mouse-down, the pointer
lock, and the direct grab into a single mode, and adding a pointer-warp
request.
POINTER-GRABBED-MODE:
When the client receives a mouse-down event, it knows it is in this
mode. The mode is exited when all the mouse buttons are released.
While in this mode the mouse position is reported as though the user is
dragging over a very large torus surface (ie it wraps at very large
integers), the same as the pointer-lock proposal.
The pointer stops moving on-screen except in response to pointer-warp
requests from the client. The pointer *does not vanish* (unlike the
pointer-lock proposal) because I see no way for the client to draw a
fake pointer without a possible flicker (the client can set it to a
blank surface to make it vanish).
On release of all the mouse buttons this mode is exited. The client will
get the last release event in the toroidal space. If the pointer has
been warped to a location that is not over the initial surface an enter
event is sent to the new surface and a leave to the old surface.
The shell can force this mode to exit (for Alt+Tab or the screen saver
turning on). This sends a pointer-grab-lost event.
POINTER-WARP REQUEST:
Moves the pointer to the given position relative to a surface. The move
is not done until a commit is done to the surface. If the pointer image
is changed then a commit must be done to both before it moves.
This is ignored if the client does not have focus for the pointer. The
request includes the serial number of the triggering event so the
compositor can ignore old ones even if the client lost focus and
regained it.
I think this also must be allowed if the client has keyboard focus and
the event is a keystroke or a focus-in. However that can probably be
discussed later.
A simple client can just echo the position for all drag events back to
pointer-warp requests to make the cursor move normally.
POINTER-GRAB REQUEST:
If no mouse buttons are down, send all move events to this surface. Then
on the next mouse-down enter into pointer-grab mode (which will last
until all buttons are released).
This is a bit different from the current grab in that the caller must
re-grab after each click (which will only work if the pointer focus is
in one of it's surfaces), and that the client also gets the
press+drag+release of a click outside it's surfaces (which may be useful
for screen shot software, though that will need extra privileges to get
the screen contents).
This only works in the same cases the pointer-warp request works (client
must have focus for the pointer, or possibly for some keyboard events).
If the client has already done one of these requests (or is in an
implicit grab) then this can be used to change what surface everything
is relative to. This is useful for complex popup menus. No
pointer-grab-lost event is sent in this case.
More information about the wayland-devel
mailing list