[RFC xwayland] Pointer warp emulation
Jonas Ã…dahl
jadahl at gmail.com
Wed Apr 13 10:07:51 UTC 2016
Hi,
With Wayland, the X server is no longer in control of the pointer
position, and as such, clients warping the pointer has no effect. This
causes many applications (mostly games) to fail to function properly, as
they depend on the warp requests to actually take effect. The same can
be said about pointer grabs with window confinement.
A way to make it possible to allow these applications to behave as
expected is to introduce the concept of "pointer warp emulation".
I have implemented such a solution, which can be found here:
https://github.com/jadahl/xserver/commits/wip/xwayland-pointer-warp
It currently only works on mutter (explained further below), but should
work with weston given by making some (minor) equivalent changes there.
For reference, the mutter branch can be found here:
https://github.com/jadahl/mutter/commits/wip/xwayland-pointer-warps
I have so far mostly tested with three applications (games): OpenTTD,
Half Life 2, and Trine 1, which all seem to work fine with the current
branch.
With pointer warp emulation, a client warping the pointer is translated
into Xwayland using of the relative pointer[0] and pointer
constraints[1] Wayland protocols, while faking the pointer position
exposed to the rest of the X server.
When the emulator is enabled, the actual pointer position and the
pointer position exposed to Xwayland may be different.
There are a few problems to solve here:
1) when to enable a pointer warp emulator
2) when to disable a pointer warp emulator
3) when to enable a pointer lock
4) when to disable a pointer lock
Problem 3) needs attention in both Xwayland and in the compositor, but
the rest can be partly solved completely in Xwayland.
As for problem 1) and 2), in my implementation I enable the emulator
once the pointer is warped, but given that the pointer cursor and the exposed
pointer position may be different, only as long as the pointer sprite is
already hidden. The emulator is disabled once the sprite is made visible
again.
As for problem 3), in the compositor I prototyped this with (mutter), I
had to relax the requirements for enabling a pointer lock. For regular
Wayland clients, a lock was only enabled if its surface was active/in
focus. This was not possible for X11 clients, as often the surface that
was the target of the warp happened to be an override-redirect window,
which never will have such a state. So for X11 clients the requirements
had to be relaxed, and the responsibility of behaving responsibly had to
be partly moved to Xwayland.
In order to make Xwayland behave more responsibly regarding problem 3),
some requirements were added in order to trigger a pointer lock. The
requirements more or less tries to mimic the situations where the window
would receive input events. For example the current implementation looks
at the current grab, pointer focus and warp destination, etc to figure
out whether locking is reasonable.
As for problem 4), in order to gracefully give back pointer control to
the compositor, the lock is always disabled if the fake pointer position
ends up outside of the given window rectangle.
An alternative solution to using the Wayland pointer constraints
protocols could be to introduce a half-private "wp_xwayland" protocol
with a "warp_pointer" request, only exposed to Xwayland. This would,
apart from making the compositors require more feature and becoming more
complicated, largely have the same problems as mentioned above,
requiring an "emulator" to keep track of fake positions vs real
positions, knowing when to avoid warping, and I suspect it would work
more or less equally well as this solution; but its worth to mention.
Apart from warping, the linked branch also adds support for confining
pointer grabs. These requests are more directly translated to
the equivalent Wayland protocol.
How does people feel about adding "emulation" code like this to
XWayland? Does the approach described in this E-mail and implemented in
the linked branch seem reasonable?
Jonas
[0] https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml
[1] https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
More information about the xorg-devel
mailing list