`process` and `bind` are called from the same thread in order, there is
no need for atomic usage here.
This reverts commit 3d7dbd6371.
This reverts commit b3db1ba10b.
It used to be the case that we overwrite this->sync even if it was non-zero
when updating the texture, without deleting the sync object. If we update
faster than we render, the result would be leaking sync objects.
This commit ensures that sync objects are deleted when they are replaced.
Invalidating the entire window on an Expose event causes poor WM
performance when dragging the window around. Instead flag to redraw and
wait for the expose events to stop for 100ms before doing it.
This uses the same line sweep algorithm originally created to copy DXGI
textures to IVSHMEM to implement the copy from IVSHMEM to memory-mapped
pixel buffer objects.
It looks really weird having a separator right after a sentence ending in :.
A separator makes the list look detached from the paragraph that introduces
it, which looks awkward. Instead, this commit moves the separator before the
introducing paragraph.
Also added logic to properly pluralize the sentence.
The display servers and renderers may want to register their own
overlays in the future, as such we need g_state.overlays to be
initialized to allow for this.
Since we only update imgui's cursor location when the overlay is
enabled, if the last cursor position was showing a shape that is
incorrect when we re-enter the overlay the cursor will be wrong. This
corrects this by updating the location as we enter overlay mode.
This adds a new `earlyInit` call which allows the overlay to register
options before actually being intialized. Also the keybind handling and
state tracking for each overlay has been moved internal to the overlay
itself.
When entering overlay mode if the cursor was previously grabbed we
should restore the state when exiting overlay mode. This will also
correct the pointer setting it to NONE or SQUARE depending on the prior
grab state.
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.
This replaces the scaled `destRect` with a version that uses doubles
correcting the rounding error that is causing a failure to properly
clear the black bar areas.
This mesh will later be used to render only damaged portions of the desktop.
We also moved the coordinate transformation for damage overlay into a matrix
and computed by the shader.
XPresent doesn't give us the time before presentation, but the time just
after. This code calculates and calibrates a delay to sleep for before
signaling the wait event for render when using jitRender
After the damage queue PR, EGL damage count 0 means no change, and -1 means
invalidate the entire window. However, several other places have different
semantics, and we are not handling them correctly:
1. KVMFR uses 0 to signal invalidating the entire frame, so if we receive 0
rectangles in egl_on_frame, we should set damage count to -1.
2. The damage overlay treated 0 as full damage, which is now incorrect. This
is fixed, and now it treats 0 as no update, and -1 as full damage.
The way things were handled in EGLTexture is not only very hard to
follow, but broken. This change set breaks up EGLTexture into a modular
design making it easier to implement the various versions.
Note that DMABUF is currently broken and needs to be re-implemented.
There used to be a possible race when a bunch of rectangle is appended, but
the total count is not updated before it's read. Using a lock eliminates
all such races.
Without configuring Wayland compositors to send frame callbacks as late as
possible, JIT rendering can increase latency by more than one frame.
For example, by default, sway asks applications to render right after a
vblank, and does its own composition right after a vblank, resulting in
~2 frame's worth of latency. If max_render_time is set on the output,
it composes that many milliseconds before the vblank, losing ~1 frame's
worth of latency. If max_render_time is set on the window also, the frame
callback is sent that many milliseconds before composition, and we achieve
perfectly low latency.
Therefore, out of the box, JIT rendering should not be enabled, as manual
compositor configuration is required for optimal results.
For reference, the following sway settings results in the best latency:
output <insert output name> max_render_time 1
for_window [app_id="looking-glass-client"] max_render_time 1
This reverts commit 3baed05728.
If we invalidate the window, we used to not update this->cursorLast, and
this causes us to lose track of the cursor. Now we update this->cursorLast
unconditionally, and this fixes the issue.
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.
When requested, JIT render mode will be used if the display server supports it.
Otherwise, a warning is generated instead.
This essentially uses the signalNextFrame logic for imgui, but for everything.
We automatically enable this mode when overlay is on.
Currently, this exposes some damage tracking bugs in the EGL renderer.
This prevents damage from being overwritten when frames are received
faster than could be rendered.
This implementation cycles between two queues, removing all need for
memory allocation.
This method takes an LGEvent and signals it when the next frame should be
rendered in time for the next vblank.
We will be using this to render imgui at screen refresh rate, but this could
potentially be used later to implement a better form of vsync for supported
display servers.
This must be invoked before swapping buffers.
The imgui overlay requires input even if the display is not captured and
operating in raw mode. XInput2 correctly only sends
XI_Press/ReleaseButton events if the device has not been captured, as
such it's safe to handle both raw and non raw buttons events at the same
time.
We look for the client config in $XDG_CONFIG_HOME/looking-glass/client.ini.
This is done because it's more conventional, and also allows us to add
additional configuration files, e.g. for the host.
We fallback to $HOME/.config as is standard, and then as a last resort use
getpwuid(getuid())->pw_dir. This is also recommended by the getpwuid manpage:
> An application that wants to determine its user's home directory should
> inspect the value of HOME (rather than the value getpwuid(getuid())->pw_dir)
> since this allows the user to modify their notion of "the home directory"
> during a login session.
Currently, we load /etc/looking-glass-client.ini and/or
~/.config/looking-glass-client.ini as long as they exist, even if they are
not files. We should only load them if they are files.
We don't want to encourage craziness of people making the client suid to
bypass permission issues on the shm file.
Note: I see no evidence of this happening in the wild, but let's be
proactive.
The refresh-copyright script now automatically updates the copyright string
embedded in config.c. In order to achieve this, refresh-copyright gained the
ability to reflow text as the situation needs.
We now give ImGui the true logical size of the window and tell it to scale
the framebuffer. To fix the blurry fonts, we continue to load fonts at the
scale necessary for the DPI and use FontGlobalScale to shrink the fonts back
to the logical size. The font rectangle is then expanded by the framebuffer
scaling, resulting in good text rendering.
This method has the advantage of not messing up the sizes of resizable
overlays when moving across monitors.
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.
Now that we are drawing with damage rects, when the window is hidden and
then exposed the window may not get fully redrawn. This provides
`app_invalidateWindow` for the display server backend to call when the
screen needs a full redraw.
When a new client connects to our session the host will repeat the last
valid frame for the new client. This change will detect this and skip
the duplicated frame.
This is necessary in case overlays change size. When this happens, we must
damage the larger of the overlays' rectangles this frame and last frame.
This erases the overlay from where it is no longer appears.
In order to do this, we must keep track of the rectangles for every overlay
with no exception. We cannot short-circuit the generation of rectangles if
we run out of buffer space, and we must allocate space for MAX_OVERLAY_RECTS
rectangles for every frame. Otherwise, we will not know where to erase the
overlay if it disappears.
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.
While the renderer can internally track this it would be better to
simply provide this information to the renderer directly so it can make
better decisions on how best to update the screen.
If the guest is not sending frames at a constant rate, the minimum FPS
timeout may expire drawing an additional frame. This change calculates
the average ups frame time over the past 100ms and adds this to the
timeout value allowing this value to be dynamic.
The accumulated time is not the best way to do this as the timer
function callback may not be exactly every 1000ms, by using the
monotonic clock we will get more accurate results.
1. Use atomics and return exact cursor positions from egl_cursor_render
to avoid race conditions between cursor render and update.
2. Instead of messing with lastCursorValid in various overlays, simply use
the hasOverlay/hadOverlay logic for cursor damage. This simplifies the
logic greatly.
As a result, I believe all cursor-related artifacts are fixed.
Note to reviewer: as atomic_init and atomic_store are implemented as macros,
it is currently not possible to pass structs as compound literals due to the
comma being interpreted as an argument separator by the preprocessor.
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.
Instead of using the desktop <GL/gl.h>, we properly use the OpenGL ES 3.x
headers. Also, we now use GL_EXT_buffer_storage for MAP_PERSISTENT_BIT_EXT
and MAP_COHERENT_BIT_EXT as the core versions are only available in desktop
OpenGL 4.4. Similarly, we need GL_EXT_texture_format_BGRA8888 for GL_BGRA_EXT
as GL_BGRA is desktop-only.
The renderer may take time to process the cursor update due to various
internal factors, as such it's best we copy the data and mark the
message as done ASAP. This prevents the host from filling up the queue
as easily when a high dpi mouse is in use.
People often miss the warnings about invalid arguments in their command
line, this last minute patch attempts to address this by making
warnings, errors, fixme's and fatal errors stand out if stdout is a TTY.
Conversion from the float values srcW/srcH to the int values for the client window dimensions would sometimes round down, causing the client to scale instead of matching the host's resolution.
A resolution switch could cause the renderer state to become invalid as
the texture format may change while it's being rendered. This fixes this
by adding a lock around the format change and render calls to the
renderer.
Drawing to the front buffer directly requires special handling to
prevent seeing the draw progress (avoiding glClear, etc) and as a result
the output is quite bad unless a compositor is running. Also vsync if
enabled will not function without double buffering enabled.
As OpenGL is the legacy fallback, there are no plans to implement clean
front buffer draw support, so just enable double buffering.
If a compositor has not yet started or is not running the atom
`_NET_WM_BYPASS_COMPOSITOR` may not have yet been created. As such we
need to create it so that if a compositor is started it will see this
propery and honour it.
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
The existing code would overwrite the texture's data even if the texture
is currently being used to render to screen. This changeset generates a
texture for each buffer preventing this invalid usage.
The incorrect spelling, NETWM_BYPASS_COMPOSITOR, somehow worked in the
past, but it appears to not work right now. Corrgan on Discord reported
the issue and confirmed that changing the spelling allowed the compositor
to be bypassed and the client to update faster than 60 Hz on his mixed
refresh rate setup.
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.
This fixes a regression caused by the move from SDL2 which handled this
itself. We should only minimize when focus is lost if the application
was in full screen mode.
util_guestCurToLocal may not be able to provide the local position if
we do not yet know where the guest cursor is, or the destination render
rect dimensions. Acting on this when this information is unknown causes
undefined behaivour.
To start a clipboard incr transfer the client has to delete the INCR
window property as the reply to the selection. This deletion generates a
property change event with the type delete, errornously triggering the
incr processing of the data. This patch corrects this by ignoring
property deletions.
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 option controls the time period (in ms) after which the help menu
appears when holding down the escape key. After this time period,
capture mode is no longer toggled.
This fixes#527.
Due to the logic in the event loop property events may get filtered out
that were clipboard related. This changes ensures the clipboard event
handler code gets to run first avoiding this issue.
The clipboard atoms may not exist yet and as such we must create them if
this is the case. Failure to do so results in `SEL_DATA` being zero
breaking the clipboard paste mechanics
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.
If the window manager does not support the motif hints then fallback to
creating a utility window, do not do both. A utility window is a
sub-optimal fallback as it may prevent the application being shown in
the taskbar or as a running application as has been reported on KDE.
Using the first two valuators present in the event is incorrect. Events
with only one valuator set, such as those sent by the Xorg evdev driver
when the mouse moved along one axis only, were being discarded. On the
other hand, mice with multiple scroll wheels may be able to emit events
with two scroll wheel valuators set.
The XInput2 specification is light on details, but "Rel X" and "Rel Y"
appear to be the de facto standard names for the motion valuators. If
valuators with those labels are not found, fall back to using valuators
with numbers 0 and 1.
Due to the confusing nature of the x11 protocol, bit_gravity and
win_gravity are not what they appear to be. These do not describe the
window position but rather the pixels/subwindows when the window is
resized. Instead set the gravity via the WM_SIZE_HINTS property which
all modern window managers should respect.
This fixes the fullscreen and likely borderless issue too that people
have been reporting on X11 under gnome. Thanks to tdb in discord for
spotting the error.
When linking against libbfd.so, just passing libbfd.so to the compiler is
sufficient. When linking against the static version libbfd.a, however,
we must additionally link against libiberty.a and libz.a.
This commit adds a CMake helper to find the correct libraries that need
to be passed to link against libbfd correctly.
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.
When users press escapeKey for a long time, they probably want to
see the help text instead of actually toggling capture. Therefore,
if the key is held down for more than 500 ms, we assume the user
wants to look at the help text and do not toggle capture mode.
500 ms seems to be a decent compromise, allowing slow presses, but
is not enough time for the user to have looked at the help text.
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.
During the refactor/rebase period with B3-next the conditional was
accidentally reversed. This would cause the cursor to be ungrabbed
simply when toggling capture mode instead of waiting for the cursor to
exit the window.
Mouse move deltas greater then 10 are rare, let alone the 20 this code
now uses. Any movements that exceed 20 pixels will disable the exit
detection code path preventing rapid movements in FPV games from causing
the cursor to exit the window if autoCapture is enabled.
As we now are using our own backends instead of SDL, there is no longer
any need to warp back to the center of the window when in autoCapture
mode. This breaks the SDL ds backend behaviour, however as SDL is
planned to be removed this is not an issue.
The $escape+S keybinding now cycles through the available scale algorithms.
This allows the user to switch between algorithms if the automatic detection
turns out to be problematic.
The algorithms are renumbered so that 0 can be LG_SCALE_AUTO.
Reusing cached EGLImages while the frame format has changed will result
in visual artifacts. We should instead destroy the EGLImages and let
them be recreated.
Instead of duplicating the #defines from the shader into the C code,
this commit adds a custom CMake rule that exports all the #defines
from a shader into a C header.
This commit fixes the issues with the meaning of useNearest being flipped
by removing the variable and use enumerations.
We define an enumeration EGL_DesktopScaleType to express the type of scaling
needed to be performed: no scaling, upscaling, or downscaling. This is
updated when either the frame size or the viewport size changes.
Previously, we only updated the useNearest when the frame size changes.
The desktop shader can now support an enumeration of scaling algorithms,
although only nearest and linear are currently implemented.
Like before, nearest is used when not scaling or upscaling, and linear is
used when downscaling.
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 makes dealing with window manager shortcuts that overlap with guest
keys more pleasant, while retaining the previous functionality for users
who prefer it.
For instance, previously, using Alt+Tab (or $mod as Alt in i3/sway
movement commands) would result in the guest retaining Alt as pressed.
When the guest regained focus, it would continue thinking Alt is
pressed, leading to accidentally triggering obscure shortcuts. One had
to remember to press Alt again to "unstick" things, which was
suboptimal.
This commit forces the DMA'd memory to be copied into the texture in
the EGL on_frame handler. This avoids tearing when the LG host inevitably
updates the underlying memory. We need an additional copy inside the GPU,
but this is cheap compared to copying from system memory.
We could have used logic to lock the memory buffer, but that would require
performing DMA on every frame, which wastes memory bandwidth. This
manifests as reduced frame rate when moving the mouse compared to the
non-DMA implementation.
We also keep multiple EGLImages, one for each DMA fd, to avoid issues
with the OpenGL driver.
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.
This commit adds a new option, win:autoScreensaver, which when set to yes,
automatically disables the screensaver when requested by an application
running in the guest, and enables it when the application no longer wants
it disabled.
This is useful when doing media playback in the guest.
It appears that the keyboard should only be grabbed if the client is
focused and the cursor is in the view. However, the relevant logic was
missing from core_setCursorInView, and the keyboard was never actually
grabbed.
This commit adds the call to g_state.ds->grabKeyboard(), allowing grabbing
to work.
Before, if you want to see the FPS, you need to close the client and
restart it with the -k switch to see the FPS. This is annoying.
This PR introduces a new keybind, ScrollLock+D, which, when pressed,
toggles the display of the FPS.
This is implemented for both EGL and OpenGL backends.
egl_help_set_text and egl_help_render were both accessing bmp->help from
different threads. This creates a race condition in which if the help text
is quickly toggled on and off, it stays on.
This has been fixed with an atomic exchange.
This should prevent the looking-glass-client window from having an alpha
channel. On Wayland, the alpha channel is used to compose the window onto
the desktop, so the wallpaper would bleed through unless set to complete
opaque.
We worked around this by using constant alpha for rendering, but it was
not sustainable. Instead, we should just ask for 24-bit context.
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).
`$DISPLAY` will be set even in a Wayland session, which causes LG to
initialize itself under Xwayland unless it is explicitly compiled with
`-DENABLE_X11=OFF`.
We could add a Wayland check within the X11 backend, but reordering the
code-generated array seems like a better solution.
We ask for 32-bit colour buffer when creating the EGL context. On Wayland,
this sometimes give contexts with alpha channels, resulting in unwanted
transparency. So we clear the alpha channel in the desktop shader.
We also switch to using constant alpha for blending the splash, which
avoids more alpha issues.
As the window manager may change our mode to full screen without our
request we must ask the ds backend for the current state when we want to
toggle the mode.
When input:grabKeyboardOnFocus=no, exiting capture mode should ungrab
the keyboard. Otherwise, focusing the window doesn't grab the keyboard,
but toggling capture mode would leave the keyboard stuck in a grabbed
state until defocused.
This effectively reverts 4bceaf5.
Upstream ticket: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4180
Commit 941c651 makes working around the hang in LG itself not as
annoying as before.
In the future, we can bypass this entire issue by implementing our own
swapchain and listening to frame callbacks ourselves.
While a compositor will never send us 0-delta motion events, they can
still end up as 0-deltas post-projection, consuming QEMU buffer space
for no reason.
This should help with mouse skipping issues.
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).
If the renderer fails to start it sets the run state to stopped, having
lgInit where it was causes this to be reset to running triggering
invalid usage of g_state.lgmp.
Under some circumstances, Looking Glass can hang when SIGINT'd, for
instance, if it's stuck waiting on spice I/O that won't complete because
the guest is misbehaving.
This commit provides an escape hatch for such cases, so one doesn't have
to reach for `kill -9 $(pidof looking-glass-client)`.
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 does not make sense to accumulate fractional error in non-capture mode
as you know exactly where the cursor is supposed to be, at least on Wayland.
On Wayland, we base movements on the current guest position and desired
target position, and the accumulated errors only skew our movements.
Build failed with _FORTIFY_SOURCE enabled because the compiler couldn't
ensure the switch statements didn't hit the default arm and thus wouldn't
define the variables. Adding a statically failing assert makes sure that
all code paths either define the variables or fail early.
$ cd client
$ env CFLAGS='-O1 -D_FORTIFY_SOURCE=1' cmake -B build/
$ make -C build
[...]
client/renderers/EGL/egl.c: In function ‘egl_calc_mouse_size’:
client/renderers/EGL/egl.c:299:36: error: ‘h’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
299 | (this->mouseHeight * (1.0f / h)) * this->scaleY
| ~~~~~~^~~~
When using the meta resize feautre the cursor is over the client window,
and as such the application continues to receive motion events. This
causes the window size to spaz out.
As the screen output rotation can be changed on the fly, if it has been
rotated to 90 or 270 the nearest flag will be incorrect, so we perform
this check here and override the provided value.
This is an ugly hack for now that will get us over the line for Beta 3,
after which will need to be addressed and people will need to be
informed that their configured escape key will have changed.
If the guest has it's output rotated (ie, landscape) we must rotate and
translate the pointer draw location, as well as all the translations of
cursor coordinate spaces based on the rotation, along with any local
rotations that may also be applied.
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.
Unless the corresponding mouse down event was on our surface, we should
not be receiving the mouse up.
This is always the case on Wayland. On some other platforms,
SDL_CaptureMouse can be used to obtain input that happens outside the
Looking Glass surface, but Looking Glass does not make use of that
function.
We may want to process a mouse up if the corresponding mouse down
initiated a drag (e.g., of a window) that was released slightly outside
of the Looking Glass surface. Previously, Looking Glass would ignore the
mouse up, and the guest would be confused into thinking the button had
never been released, not ending the drag.
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.
If the guest cursor state & position is unknown we can not rely on the
information to detect edge crossings. As such only allow cursor input if
LG is operating in capture mode.
Platforms such as Wayland have no abillity to warp the cursor, as such
can not operate in an always relative mode. This property allows
platforms to report the lack of warp support and prevent LG from
grabbing the pointer.
Some platforms such as Wayland need to set environment vairables before
SDL is initialized, as such this change detects the display server
before SDL has started and calls the new `earlyInit` method providing
the implementation an opportunity to set things up.
When capture mode is set if the cursor is not already in the view area
we need to force it to the state it would be if it were in view as
capture mode overrides all.
The pointer may not yet be in the view area so we should defer drawing
it until the mouse move handler determines that it's inside the view
area and turn it on itself.
As LG always operates in relitive mode, the actual pointer grab/ungrab
is managed by the move handler, as such setGrabQuiet should not alter
the grab/ungrab state of the local pointer.
The prototype for abs is int abs (int n), which implicitly casts floating
point values to integers. The correct function is fabs.
This commit allows the client to compile under clang.
gcc -Wimplicit-fallthrough only detects comments if they are immediately
preceded before the next label. Braces stops it from recognizing the
fallthrough comment.
-Wno-sign-compare is used to suppress warnings related to comparing signed
values with unsigned ones. It's too pedantic.
-Wunused-parameter is also too pedantic, especially since all parameters
have to be named in C.
Otherwise, -Wextra lets us catch bugs, such as x < 0 for unsigned x.
On gcc, we pass -Wimplicit-fallthrough=2 so it will recognize our fall
through comment.
This makes it a compile-time error to call a function that semantically
takes no parameters with a nonzero number of arguments.
Previously, such code would still compile, but risk blowing up the stack
if a compiler chose to use something other than caller-cleanup calling
conventions.
Copying rich text from the guest would be turned into plaintext on the client.
Prior to this change, this would be sent back to the guest, overwriting its
clipboard. This made it impossible to copy rich text inside the guest.
This commit detects such self-copies by checking if the receiver is the
current process, and rejecting it.
This prevents looking-glass-client from failing with an error message like:
error marshalling arguments for receive (signature sh): null value passed for arg 0
Error marshalling request: Invalid argument
When input:grabKeyboardOnFocus is set (default), entering capture mode grabs
the keyboard a second time. This commit makes the second grab a no-op on
Wayland to avoid a crash.
Previously, main.c would segfault at runtime if clipboards were disabled
via cmake flags, as the clipboards array would be empty but still
indexed during initialization.
Co-authored-by: Quantum <quantum2048@gmail.com>
Otherwise, a badly-behaving client causes Looking Glass to receive a
SIGPIPE during Wayland copy operations. Handle EPIPE at call-sites
instead.
Co-authored-by: Quantum <quantum2048@gmail.com>
The normal logic does not work due to Wayland not supporting mouse warp.
We use a simple logic that works for the desktop with 1:1 mouse patch and
require capture mode for all other cases.
=================================================================
==7680==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000ec010 at pc 0x5622fcf9f386 bp 0x7f36084ff680 sp 0x7f36084ff678
WRITE of size 4 at 0x6020000ec010 thread T1
#0 0x5622fcf9f385 in clipboardRequest /code/LookingGlass/client/src/main.c:707
#1 0x5622fd0036c9 in wayland_cb_notice /code/LookingGlass/client/clipboards/Wayland/src/wayland.c:521
#2 0x5622fcf9f4dc in spiceClipboardNotice /code/LookingGlass/client/src/main.c:724
#3 0x5622fcfc4d59 in spice_agent_process /code/LookingGlass/repos/PureSpice/src/spice.c:1106
#4 0x5622fcfc16d6 in spice_on_main_channel_read /code/LookingGlass/repos/PureSpice/src/spice.c:655
#5 0x5622fcfbee4f in spice_process /code/LookingGlass/repos/PureSpice/src/spice.c:361
#6 0x5622fcf9e3a2 in spiceThread /code/LookingGlass/client/src/main.c:598
#7 0x5622fd006b5e in threadWrapper /code/LookingGlass/common/src/platform/linux/thread.c:39
#8 0x7f3614b2bf26 in start_thread /build/glibc-WZtAaN/glibc-2.30/nptl/pthread_create.c:479
#9 0x7f3614a4c2ee in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xfd2ee)
0x6020000ec011 is located 0 bytes to the right of 1-byte region [0x6020000ec010,0x6020000ec011)
allocated by thread T1 here:
#0 0x7f36156f9628 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x107628)
#1 0x5622fcf9f33f in clipboardRequest /code/LookingGlass/client/src/main.c:705
#2 0x5622fd0036c9 in wayland_cb_notice /code/LookingGlass/client/clipboards/Wayland/src/wayland.c:521
#3 0x5622fcf9f4dc in spiceClipboardNotice /code/LookingGlass/client/src/main.c:724
#4 0x5622fcfc4d59 in spice_agent_process /code/LookingGlass/repos/PureSpice/src/spice.c:1106
#5 0x5622fcfc16d6 in spice_on_main_channel_read /code/LookingGlass/repos/PureSpice/src/spice.c:655
#6 0x5622fcfbee4f in spice_process /code/LookingGlass/repos/PureSpice/src/spice.c:361
#7 0x5622fcf9e3a2 in spiceThread /code/LookingGlass/client/src/main.c:598
#8 0x5622fd006b5e in threadWrapper /code/LookingGlass/common/src/platform/linux/thread.c:39
#9 0x7f3614b2bf26 in start_thread /build/glibc-WZtAaN/glibc-2.30/nptl/pthread_create.c:479
Thread T1 created by T0 here:
#0 0x7f361562b9b2 in pthread_create (/lib/x86_64-linux-gnu/libasan.so.5+0x399b2)
#1 0x5622fd006cd0 in lgCreateThread /code/LookingGlass/common/src/platform/linux/thread.c:50
#2 0x5622fcfa5a7d in lg_run /code/LookingGlass/client/src/main.c:1615
#3 0x5622fcface28 in main /code/LookingGlass/client/src/main.c:2035
#4 0x7f3614975e0a in __libc_start_main ../csu/libc-start.c:308
SUMMARY: AddressSanitizer: heap-buffer-overflow /code/LookingGlass/client/src/main.c:707 in clipboardRequest
Shadow bytes around the buggy address:
0x0c04800157b0: fa fa 00 00 fa fa fd fa fa fa fd fa fa fa fd fd
0x0c04800157c0: fa fa fd fd fa fa fd fa fa fa 00 fa fa fa 00 fa
0x0c04800157d0: fa fa 00 fa fa fa fd fa fa fa fd fd fa fa fa fa
0x0c04800157e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c04800157f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c0480015800: fa fa[01]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015850: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==7680==ABORTING