X11 needs to calibrate to get the best possible latency, as such it
needs the scene to render so that the render time of the scene can be
accounted for in the delay calculation.
Version 3 does not send xdg_output.done events, instead guaranteeing that
all xdg_output.* events are sent before wl_output.done. This saves us from
doing the work twice.
The method used is not guaranteed to work on all Wayland compositors,
so offer a way out. We need to support it anyways in case xdg_output
or wp_viewporter protocols are not available.
Currently, we scale the desktop up to the next largest integer, and rely on
the wayland compositor to scale it back down to the correct size.
This is obviously undesirable.
In this commit, we attempt to detect the actual fractional scaling by finding
the current active mode in wl_output, and dividing it by the logical screen
size reported by xdg_output, taking into consideration screen rotation.
We then use wp_viewporter to set the exact buffer and viewport sizes if
fractional scaling is needed.
The default of [0, 50] makes sense for FPS/UPS graphs, but does not for
things like the import graph. The latter should not take more than 5 ms
for sure.
This commit allows the min/max y-axis value to be specified when registering
the graph.
Currently, we dispatch the events on the wayland display server ourselves.
This is fine when using the cairo backend of libdecor, as it does the same
thign we do, but other backends may require other things to be dispatched.
This commit lets libdecor dispatch events instead through libdecor_get_fd
and libdecor_dispatch, which should hopefully makes things less sketchy.
This commit creates a new utility library, eglutil.h, which contains code
to detect and use EGL_KHR_swap_buffers_with_damage or its EXT equivalent.
This logic used to be duplicated between the X11 and Wayland display servers,
which is not ideal.
This should fix the occasional Wayland protocol errors that arise when
the UI thread and the cursor thread race.
Example of error that is fixed:
zwp_pointer_constraints_v1@11: error 1: a pointer constraint with a wl_pointer of the same wl_seat is already on this surface
This commit restructures the Wayland clipboard handling for host->VM.
Before, we select one clipboard format and buffers the data for it, to
be presented to spice when needed.
Now, we simply offer all clipboard formats supported, and only when spice
asks for the data do we actually read the wl_data_offer. The wl_data_offer
is kept around until a new offer is presented, the offer invalidated, or
when we lose keyboard focus. This is in accordance with the specification
for wl_data_device::selection, which states that:
> The data_offer is valid until a new data_offer or NULL is received or
> until the client loses keyboard focus. The client must destroy the
> previous selection data_offer, if any, upon receiving this event.
We still buffer the entire clipboard data into memory because we have no
knowledge of the clipboard data size in advance and cannot do incremental
transfers.
Furthermore, if the user performs drag-and-drop on our window, we may have
need to handle multiple wl_data_offer objects at the same time. Therefore,
instead of storing state on the global wlCb object, we instead allocate
memory and store it as user_data on the wl_data_offer. As a result, we also
handle drag-and-drop so that we can free the memory.
Support for non-PNG types is optional in the spice agent, so we should
avoid sending those if PNG is available.
Currently, the spice VDAgent supports only PNG and BMP formats.
Instead of damaging the entire surface when rendering a cursor move,
we can use the EGL_KHR_swap_buffers_with_damage extension to only
damage the part of the window covered by the cursor. This should
reduce the cursor movement latency on Wayland.
We previously used strstr, which can be prone to false positives when
the name of one extension is a substring of another extension.
This commit creates the helper function util_hasGLExt, which asserts
that the substring found in extension list is bounded by either spaces
or the beginning/end of the string.
Using util_cursorToInt messes with the error tracking for normal movements,
and is not necessary since we are computing an absolute position on the
client window.
Instead, we should pass doubles directly to display servers and let them
decide how to best handle them. For example, XIWarpPointer accepts doubles
directly.
This prevents the host cursor from moving into another window in capture
mode, solving the problem of input going to an overlapping window in
capture mode, and also preventing loss of focus with focus_follows_mouse.
Currently, (un)grabPointer is used both for tracking/confining the mouse
in normal mode, as well as entering/exiting capture mode. This makes it
impossible to use separate cursor logic for capture mode, which is needed
to deal with overlapping windows for the Wayland backend.
This commit creates separate (un)capturePointer for entering/exiting
capture mode. There should be no behaviour changes.
This adds a new method to the display server interface to allow the
application to notify the ds when there is a guest cursor position
update along with the translated local guest cursor position. This makes
it possible for the display server to keep the local cursor position in
sync with the guest cursor so that window leave events can be detected
when the cursor would move into an overlapping window.
Wayland currently just has a stub for this, and the X11 implementation
still needs some minor tweaking.
This commit fixes the -Wmissing-field-initializers warning, which can only
be disabled with a pragma. GCC wants us to Initialize libdecor reserved
fields, which requires knowing how many reserved fields there are.
This is an implementation detail, and so we can only disable the warning.
This also fixes -Wincompatible-pointer-types, which is an actual bug.
The only addition to v4 was `wl_surface_damage_buffer`, which we do not
use.
This change should allow running on more compositors (even though v4 is
already old -- 5 years now).
Ref
3384f69ecf.
We don't necessarily need `wl_output.release`, which is the only
addition in v3.
This allows Looking Glass to run on Ubuntu 20.04 without having to go
difficult lengths to acquire newer Wayland packages. Since 20.04 is an
LTS release, this seems worthwhile for the small amount of complexity
this introduces.
Fixes
https://forum.level1techs.com/t/latest-build-allow-inhibiting-shortcuts-dialog-ubuntu/168684/6.
This was missed when splitting up wayland.c into multiple modules.
This commit also drops the useless #include <SDL2/SDL.h>, bringing
SDL removal one step closer.
If the scale factor of an wl_output changes while the client is running,
the maximum scale factor is not updated. This may result in incorrect
scaling.
Therefore, when the scale factor is changed, we should generate a
resize event.
The Wayland display server is getting unwieldy due to the sheer size.
To make it easier to edit in the future, I split it into many components
based on logical boundaries.
This is enabled on default. Specify wayland:warpSupport=no to disable it,
which may be useful on certain compositors that do not warp when the
pointer is confined.
This commit implements support for LG_DS_WARP_SURFACE, as well as a warp
routine based on cursor confines.
This may not necessarily work for all compositors. As such, the old cursor
routines are still kept, and used when wm.warpSupport is set to false.
This commit converts the output of ds->getProp(LG_DS_WARP_SUPPORT) to
an enum containing three items:
* LG_DS_WARP_NONE: warp is not supported at all
* LG_DS_WARP_SURFACE: warp is possible, but only inside the window
* LG_DS_WARP_SCREEN: warp is possible anywhere on the screen
LG_DS_WARP_NONE corresponds to the old false return value, and
LG_DS_WARP_SCREEN corresponds to the old true return value.
LG_DS_WARP_SURFACE is designed for Wayland, where warping is possible,
but only in our window. In this case, since we cannot warp outside
the window, we can warp the cursor to the edge when we attempt to exit.
If the cursor leaves, the normal leave routine gets called, and the
cursor disappears. If the cursor does not end up leaving, we grab it
again.
This new implementation uses a special mimetype to tag data copied from
the guest, instead of using flags. This should make it easier to
implement asynchronous transfers in the future. Also, it's simpler to
understand and less error-prone.
The pid is included in the mimetype in order to distinguish between
different instances of looking glass: you might want to copy between
two different VMs, for example.
One of the major issues with the old tracking code is a data race
between the cursor thread updating g_cursor.guest and the
app_handleMouseBasic function. Specifically, the latter may have
sent mouse input via spice that has not been processed by the guest
and updated g_cursor.guest, but the guest may overwrite g_cursor.guest
to a previous state before the input is processed. This causes some
movements to be doubled. Eventually, the cursor positions will
synchronize, but this nevertheless causes a lot of jitter.
In this commit, we introduce a new field g_cursor.projected, which
is unambiguously the position of the cursor after taking into account
all the input already sent via spice. This is synced up to the guest
cursor upon entering the window and when the host restarts. Afterwards,
all mouse movements will be based on this position. This eliminates
all cursor jitter as far as I could tell.
Also, the cursor is now synced to the host position when exiting
capture mode.
A downside of this commit is that if the 1:1 movement patch is not
correctly applied, the cursor position would be wildly off instead
of simply jittering, but that is an unsupported configuration and
should not matter.
Also unsupported is when an application in guest moves the cursor
programmatically and bypassing spice. When using those applications,
capture mode must be on. Before this commit, we try to move the guest
cursor back to where it should be, but it's inherently fragile and
may lead to scenarios such as wild movements in first-person shooters.
We used to test for the EGL_KHR_platform_base and EGL_EXT_platform_base,
but those only really signal the availability of eglGetPlatformDisplay(EXT)
functions, not whether the constant EGL_PLATFORM_WAYLAND_KHR or
EGL_PLATFORM_WAYLAND_EXT is accepted by their respective functions.
Instead, we switch to test for the extensions that tells us whether the
Wayland platform is supported.
Using a macro ENABLE_OPENGL just like ENABLE_EGL to optionally remove
OpenGL implementation code. This is mostly because on Wayland it's just
a rehash of the EGL code (as EGL is the only way to create OpenGL
contexts on Wayland).
Before this, copying rich text ends up with a lot of funky behaviour,
for example:
* copying text from Discord shows up as HTML unless pasted into a text
editor first
* copying text from Firefox shows up as the single letter h
This commit fixes all the above issues.
Due to the change in logic, we now use the first text format offered
instead of the last, which is almost certainly the preferred form.
Doing this gets us proper Unicode support, or Unicode characters would
end up as escapes of the form \uXXXX (this is used in the fallback
forms for applications without UTF-8 support).
We are forced to use accelerated movement in regular mode as that is how the
host machine cursor moves and we want the cursors to line up (since Wayland
cannot do warps). To avoid a change in sensitivity when toggling capture
mode on/off, we should use accelerated deltas for capture mode as well,
unless the user explicitly asks for raw input with input:rawMouse.
It appears that Wayland pointer motion handlers are called even when relative
mouse mode is enabled. The events they generate break first-person games.
This commit disables those handlers when relative mouse is enabled.
zwp_relative_pointer_manager_v1 and zwp_pointer_constraints_v1 are
supported by GNOME/KDE/sway (and most other compositors), but they are
not a required part of the protocol.
Some users also run software in one-off nested compositors like cage[0]
for an extra layer of isolation; cage, at least, does not support
pointer captures.
This commit makes Looking Glass warn when an optional protocol is
unsupported, and fail if a required one is missing. Pointer grab paths
have a new guard against the aforementioned protocols being missing.
[0]: https://github.com/Hjdskes/cage
We are actually getting mouse events directly from Wayland instead of going
through SDL, so we call app_updateCursorPos in pointer motion handlers and
swallow the SDL event.
Also removed parameters for app_handleMouseBasic as it relies exclusively on
absolute positions provided by app_updateCursorPos. Wayland does not give
you relative movements at all unless grabbed and passing absolute movements
is semantically incorrect.
Note that when the cursor is grabbed, movements are handled entirely through
relativePointerMotionHandler in wayland.c and does not go through
app_handleMouseBasic at all.