Commit Graph

4208 Commits

Author SHA1 Message Date
Geoffrey McRae
ccb80d6464 [client] clipboard: preserve formats after file import failure
Retain non-file clipboard representations while asynchronous file MIME
imports are validated. If an offered URI list is invalid or cannot be
read, publish the retained image and text formats instead of clearing
the clipboard.
2026-08-21 13:32:39 +10:00
Geoffrey McRae
423269802f [client] evdev: fix input capture and device handling
Classify configured devices by keyboard and pointer capability so
automatic keyboard capture leaves relative pointer devices with the
display server.

Run descriptor, grab, physical-state, and LED operations on one worker.
Marshal normalized events through each display server's event loop and
serialize ownership changes with per-lane barriers.

Fall back whole lanes to native input when an evdev cohort cannot be
owned, and retry missing or removed devices without disabling the rest.

Handle report framing, SYN_DROPPED, high-resolution wheels, queue
overflow, held-state cleanup, and guest-driven keyboard LEDs. Restore
host LEDs and kernel grabs during teardown.

Re-evaluate capture when the active input transport changes.
2026-08-21 13:10:34 +10:00
Geoffrey McRae
8b38546049 [client] displayserver: support external event sources
Allow display servers to dispatch a caller-owned event source on their
native event thread. This lets background input readers marshal events
to the thread that owns application and display-server state.

Poll X11 fairly when native events remain continuously available, and
use bounded polling if the external descriptor cannot be registered.
2026-08-21 13:07:51 +10:00
Geoffrey McRae
71733433ed [client/idd] input: synchronize keyboard LEDs
Report guest HID keyboard LED state from LGInput to LGIdd and
publish it with the LGMP input endpoint status.

Forward SPICE modifier updates through the same provider state so evdev
can synchronize physical keyboard LEDs across transport changes and
reconnects.

Bump the versioned pipe and KVMFR input status contracts for the new
feedback state.

Accept earlier LGMP input status versions without LED feedback so the
client retains input while the guest driver is being upgraded.
2026-08-21 13:07:46 +10:00
Geoffrey McRae
1a5bdc14aa [client] input: fix focus capture startup
Capture-on-focus could consume the initial focus event before an input
provider became available. The focused state then suppressed any later
attempt to establish capture.

Treat explicit capture as local window state, refresh keyboard ownership
on focus and input-policy changes, and preserve pre-ungrab availability
for key release. Fall back to the window center when guest cursor
geometry is not ready.
2026-08-21 04:23:42 +10:00
Geoffrey McRae
82c59cecf2 [idd] helper: retry topology after desktop access failure
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
The interactive Helper can start when the console user token exists but
before WinSta0\Default is ready. SetDisplayConfig then returns
ERROR_ACCESS_DENIED while recovery exit caches the failure and keeps
topology enforcement suppressed.

Keep the recovery request pending while desktop access is transient.
Move the pipe worker to the input desktop and retry without caching
intermediate failures. Leave an exhausted access failure uncached so a
later replay can recover.

Restore the periodic enforcement timer and retry topology without
reapplying a display mode that Windows has already accepted.
2026-08-21 01:02:10 +10:00
Geoffrey McRae
e2ee9244ed [client] recovery: add force keybind
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Add a configured escape key plus Shift+R command that requests display
recovery from the LGMP transport and switches video to SPICE.

Track the request on the main thread, report its asynchronous result,
and return its producer instance with the request serial for exact
correlation.

Preserve normal escape+R rotation behavior, including custom Shift
escape keys.
2026-08-20 16:53:10 +10:00
Geoffrey McRae
60a51fccdf [idd] recovery: unplug monitor without helper
When LGIddHelper is unavailable, recovery requests could remain
pending until timeout while the virtual monitor stayed connected.
This could leave a logged-out guest without a usable display.

Fall back to departing the IDD monitor for active recovery, then
re-arrive it before normal recovery completes. Serialize monitor
lifecycle changes and preserve recovery ordering across Helper
reconnects, timeouts, and stale responses.
2026-08-20 16:12:24 +10:00
Geoffrey McRae
7b059ad67e [woodpecker] idd: there is no need to build the Debug release here
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-08-17 13:24:07 +10:00
Geoffrey McRae
571a58b716 [idd] helper: preserve mode apply transaction 2026-08-17 13:22:52 +10:00
Quantum
cec1a16cfc [idd] helper: use registry boolean helper instead of duplication
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-08-17 05:58:36 +10:00
Geoffrey McRae
2005ea5d69 [idd] capture: add forced indirect copy
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-08-17 05:12:05 +10:00
Geoffrey McRae
96c3056cc9 [idd] capture: add direct full-copy workaround 2026-08-17 04:46:25 +10:00
Geoffrey McRae
4e15f3b68b [idd] transport: stream writes to WC mappings 2026-08-17 03:00:54 +10:00
Geoffrey McRae
4f695b93d6 [idd] helper: coalesce no-GPU notifications 2026-08-17 02:47:06 +10:00
Geoffrey McRae
66b9f18cb6 [idd] helper: scroll refresh rate input 2026-08-17 02:39:15 +10:00
Geoffrey McRae
c6bd370e3e [client] config: reject recursive resize options 2026-08-17 02:22:52 +10:00
Geoffrey McRae
94754051a8 [idd] helper: wait for display mode enumeration 2026-08-17 02:21:53 +10:00
Geoffrey McRae
9d074519b2 [idd] config: retain four-decimal refresh rates 2026-08-17 02:09:58 +10:00
Geoffrey McRae
c0de47b1e1 [idd] wcwrite: gate SIMD stores on SSE2 2026-08-17 02:08:29 +10:00
Geoffrey McRae
26cafbe3df [idd] lgmp: stream staged copies to WC memory 2026-08-17 01:27:38 +10:00
Geoffrey McRae
636e55db0d [client] egl: drop incomplete frames 2026-08-17 01:27:26 +10:00
Geoffrey McRae
86b83f3e23 [idd] lgmp: reject invalid frame layouts 2026-08-17 00:59:27 +10:00
Geoffrey McRae
e08e03bec0 [idd] postprocess: normalize downsample layout 2026-08-17 00:59:20 +10:00
Geoffrey McRae
10c4366594 [client] shutdown: silence expected transport teardown 2026-08-16 22:35:41 +10:00
Geoffrey McRae
056be1242a [client] spice: add fail-fast connection option 2026-08-16 22:35:41 +10:00
Geoffrey McRae
209ac4d749 [client] spice: gate USB reconnect on MAIN health 2026-08-16 22:09:15 +10:00
Geoffrey McRae
d26e73f615 [client] transport: exit after SPICE session loss 2026-08-16 21:56:33 +10:00
Geoffrey McRae
da36a5c4c2 [client] transport: report loss before provider cleanup
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-08-16 21:42:36 +10:00
Geoffrey McRae
eaafc52f10 [lgmp] client: cancel queue waits after session loss 2026-08-16 21:42:36 +10:00
Quantum
4cee75dab5 [common] linux/proctitle: fix off-by-one bug
0884d14bde introduces an off-by-one bug: if
`strlen(title) == totalSize`, then no space will be left for a null terminator.
2026-08-16 19:56:07 +10:00
Quantum
0884d14bde [common] linux/proctitle: zero out entire usable memory block
This avoids additional arguments showing up when their memory hasn't been
touched at all.
2026-08-16 16:03:27 +10:00
Geoffrey McRae
90c898f9c7 [client] lgmp: skip release after session loss
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Heartbeat expiry does not change the LGMP session ID. Queue operations
can therefore accept ownership releases into stale shared memory after
a guest reboot, where no host remains to advance the acknowledgement
serial.

Skip graceful clipboard and input ownership release when the session is
already invalid. Keep the existing timeout and warning for a live host
that fails to process the release.
2026-08-16 05:03:58 +10:00
Geoffrey McRae
20b2225c69 [client] overlay: limit splash fade to startup
The splash state machine reset its fade whenever a transport handoff
restored the logo. Each replacement source therefore started another
one-second fade when it became ready.

Retain one startup fade allowance and consume it on the first hide.
Later source changes can still show the unavailable-video splash, but
hide it immediately when video returns.
2026-08-16 02:59:23 +10:00
Geoffrey McRae
358171ff8b [client] main: preserve restart after primary video loss
Primary frame and pointer workers can still be unwinding an abandoned
payload when another thread detects that the primary transport has
disconnected. Their fatal paths previously stored SHUTDOWN
unconditionally, allowing a stale renderer or transport failure to
overwrite RESTART and terminate the client instead of activating the
SPICE fallback.

Publish RESTART at the beginning of primary-loss handling, before
transport bookkeeping, and make worker-local fatal paths transition to
SHUTDOWN only while the application is still RUNNING. Global failures
and the case where both primary and fallback sessions are lost remain
terminal.
2026-08-16 02:50:46 +10:00
Geoffrey McRae
3b5bbb8467 [client] tests: cover Caja clipboard MIME handling
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Teach the X11 fixture about the MATE atom and verify import
preference, source target advertisement, and copied-files delivery.

Cover the same Wayland offer and source behavior. Assert that MATE
reuses the single GNOME-style payload instead of fetching a duplicate
representation.

Exercise the core parser and generator with the MATE copied-files MIME,
including invalid operation handling and byte-identical remote output.
2026-08-15 20:49:40 +10:00
Geoffrey McRae
3e9491dbea [client] wayland: fix MATE clipboard MIME handling
Treat either GNOME or MATE copied-files data as preferred over the URI
list fallback. The previous pair of strcmp conditions could never both
be false, so a MATE offer could not replace an earlier URI list.

GNOME and MATE use the same copied-files representation. Generate that
payload once and serve it under both advertised MIME names instead of
overwriting and leaking the first allocation.
2026-08-15 20:43:56 +10:00
Geoffrey McRae
52d9ab10a0 [client] clipboard: add support for Caja 2026-08-15 20:29:08 +10:00
Geoffrey McRae
946e0f4945 [idd] capture: copy partial linear damage by byte range
Retained native candidates and framebuffer targets are both linear
buffers with the same pitched layout. Publish partial damage using
CopyBufferRegion with byte offsets instead of encoding the ranges as
texture-footprint copies.

Collapse full-width rectangles into one command. Fall back to a full
copy when the partial path would exceed 256 commands, copy at least a
full frame of data, or receive invalid damage coordinates.

This removes the native-only command path introduced by 650636cc that
can fault the D3D12 copy queue after RGB24 benchmarking selects native.
2026-08-15 20:19:54 +10:00
Geoffrey McRae
edeff3cce1 [idd] install: keep captured output in one encoding
nsExec merges stdout and stderr into one pipe and detects its
encoding once. Emit UTF-16LE on both streams so error output cannot
reinterpret progress messages as CJK text.

Disable CRT buffering on both streams so progress is visible while
service and SetupAPI operations are running.
2026-08-15 19:12:14 +10:00
Geoffrey McRae
5d51567fd5 [idd] install: let SetupAPI manage device updates
Remove the separate ConfigMgr disable and enable transaction. It
bypassed device class/co-installers, failed before DiInstallDriverW,
and could add two 30-second waits to every update.

Keep LGIddHelper stopped across both DiInstallDriverW calls and let
SetupAPI own PnP stop/start and report any required restart.
2026-08-15 19:11:48 +10:00
Geoffrey McRae
d23a7a3cf2 [idd] helper: release authority during device removal
Register the retained LGIdd authority handle for service device
notifications. Close the exact handle before granting query-remove.

Use cancellable overlapped control requests so the SCM handler never
waits for driver I/O while Plug and Play is removing the device.

Keep authority publication, host liveness, and child activation under
one synchronized state machine to prevent activation after removal.

Retire device notifications on the service thread and keep polling for
the interface so a manual re-enable recovers without a service restart.
2026-08-15 18:53:33 +10:00
Geoffrey McRae
a1f11bcc3e [idd] install: quiesce devices during driver updates
Stop LGIddHelper before updating either UMDF stack. Disable LGInput
before LGIdd, update both packages while quiesced, then restore the
provider before its dependent and start the service last.

Use in-use replacement for UMDF binaries and prevent the INF from
restarting the Helper during package installation. Report each
SetupAPI restart result and propagate it through NSIS.

Roll back transaction-owned devices, packages, and service state on
fresh-install failure. Preserve dependency order during removal and
select the package actually installed on each devnode.
2026-08-15 18:50:44 +10:00
Geoffrey McRae
fd2357565a [idd] input: purge report reads asynchronously
WDF forbids WdfIoQueuePurgeSynchronously from an I/O callback.
Keep HID deactivation pending while the report queue is purged
asynchronously, then complete it from the queue-state callback.

Reject activation during the transition. Complete any remaining
deactivation request during queue cleanup.
2026-08-15 18:00:23 +10:00
Geoffrey McRae
066d64393d [idd] clipboard: pipeline remote file reads
Add two protocol-sized read-ahead buffers to each active clipboard
file stream. Fetch the next remote block on a worker while the caller
or CopyTo destination consumes the current block.

Serialize stream operations and invalidate queued work on seeks and
failures. Join the worker before releasing the remote dataset lease.
2026-08-15 16:32:59 +10:00
Geoffrey McRae
94d5f3729e [idd] clipboard: batch helper stream delivery
Extend the clipboard target boundary with ordered prefix delivery.
Pass up to four queued LGMP stream records to the Helper ring in one
operation, apply state only to the accepted prefix, and retain the
remaining suffix for exact retries.

The channel holds its write lock across the prefix and emits one pipe
doorbell per stream window instead of one per record.
2026-08-15 16:32:43 +10:00
Geoffrey McRae
5bdfc0fe80 [idd] clipboard: remove stream payload restaging
Keep inbound stream payloads in the bounded stream-target window while
the Helper channel is busy and publish directly from those buffers.
Retain the pending target only for LGMP queue controls. Their credits
remain outstanding across retries.

This removes one full payload copy per client-to-Helper record without
changing delivery order, backpressure, or reset behavior.
2026-08-15 16:17:39 +10:00
Geoffrey McRae
4477ac0de1 [idd] clipboard: optimize write-combined reads
Add a reusable copy path for moving data from write-combined mappings
into normal cacheable memory. Dispatch to MOVNTDQA-based SSE4.1 or AVX2
loads when the processor and OS support them, with a fenced fallback.

Use the optimized path when staging inbound clipboard stream records from
the IVSHMEM mapping.
2026-08-15 16:09:28 +10:00
Geoffrey McRae
9e9bf6b88c [idd] lgmp: use precise clipboard polling
Drive adaptive clipboard stream polling with a high-resolution waitable
timer instead of rounding microsecond delays into coarse wait-function
timeouts.

Preserve the explicit stop and local wake events while avoiding a clock-tick
stall at each file-transfer window.
2026-08-15 16:03:43 +10:00
Geoffrey McRae
6a590e343a [idd] win32: use wait result constants
Use the documented Win32 wait constants throughout the pipe, clipboard,
and input workers instead of local numeric aliases.

Select the WDK NT-status definitions before including Windows headers.
Include wudfwdm.h privately in the affected translation units so UMDF 2
provides NTSTATUS without exposing WDF headers through LGCommon's public
interface to the desktop Helper.
2026-08-15 15:07:38 +10:00