[PATCH weston 1/3] Introduce pointer lock interface
Bill Spitzak
spitzak at gmail.com
Wed Sep 24 12:44:24 PDT 2014
On 09/24/2014 09:04 AM, Matthieu Gautier wrote:
> If for any reason the user move the mouse and the pointer position
> doesn't change (cause of pointer lock or pointer is already on a screen
> corner),
> a motion event is still generated but with surface_x/surface_y being the
> same as the previous ones.
This is exactly (except for the pointer-lock) what I would suggest. Some
X servers (IRIX I think) did exactly this when the mouse hit the edge of
the screen, and it was very useful for making huge menus scroll as the
user dragged the mouse. Later X servers did not do this and it made some
nice menu interaction impossible (we had to resort to the
warp-the-cursor hack you mention games doing).
These old systems did use low-resolution mice, so it knew a motion event
corresponded to one pixel. This may be a problem with modern systems as
the events are delivered for very tiny movements. An alternative idea is
to deliver motion events as though the xy position kept moving outside
the screen, but if the user moves the mouse back toward the screen such
that the cursor should move away from the edge, the xy position jumps
back inside the screen.
Pointer lock:
I'm not sure what "wl_pointer" is, but there have been a lot of strange
statements that seem to indicate people think it is impossible for the
motion events to have something other than where the user sees the
cursor. There are in fact two objects of interest:
1. A cursor. This is an image (usually an arrow) that is composited into
the display. There is one cursor per seat. This can be placed anywhere
on the screen. Usually the compositor does this, but when pointer-lock
is on the client does it.
2. An xy position. This is a per-seat xy position. Motion events and
enter/leave are delivered by this. The compositor updates it based on
input devices attached to the seat. It might also move it when pointer
lock is canceled.
These are DIFFERENT!!! It should be obvious that if the client can move
the cursor there is a race condition if the motion events depend on that
position. Therefore they must be independent.
The client should be allowed to move the cursor anywhere while pointer
lock is on (the compositor may clamp it to be on-screen). It has ZERO
effect on motion events it gets.
PS: The client cannot make a "fake cursor", as several have suggested,
because when pointer lock is released the xy position and cursor had
better be in the same location the user thought it was. Therefore the
compositor has to know where the cursor is.
Relative events:
You should not have relative events.
As long as moving the mouse actually produces different numbers (ie it
does not stop at any edges) then it is trivial for the client to extract
relative events, by subtracting the previous position.
Switching to relative events does not help at all, it makes clients more
complicated. This is because there is a race condition, the compositor
may have delivered some normal motion events before responding to the
pointer lock. The client has to deal with these so it must already have
code to deal with absolute events and therefore relative events do not
save anything.
If the input device is relative (ie a mouse), pointer lock should allow
the xy position to move anywhere, not limited to the screen. This is the
only change needed to get the benefits of "relative events".
Confine:
"confine to surface" is useless. This is because the client will always
want to confine to a widget, which the compositor is unaware of.
All that is needed is for the client to be able to move the cursor while
pointer lock is on. It can then implement any confinement rules it
wants, such as mapping to a spherical projection.
So please don't have a "confine" mode.
More information about the wayland-devel
mailing list