This repository was archived by the owner on Sep 25, 2026. It is now read-only.
Repository navigation
fix(portal): bound D-Bus wait, capture cursor, repair zero-size env - #17
Merged
Merged
Conversation
Closes #14 and #16 by patching three classes of portal/Linux bugs that combined to make capture unreliable or wedge the HTTPS control plane. Issue #14 (cursor invisible, absolute mouse silently dropped): - select_screencast_sources() now requests cursor_mode=EMBEDDED when the portal advertises AvailableCursorModes, so KDE's u 7 (HIDDEN|EMBEDDED| METADATA) actually puts the cursor in the PipeWire stream. Compositors that reject EMBEDDED (RemoteDesktop, headless) keep the omit behavior via the AvailableCursorModes check. - verify_and_update_display_parameters() falls back per monitor to the logical resolution when wl_output reports a 0x0 physical size (KWin does this). As a last resort it uses the stream dimensions rather than leaving env_width/env_height at zero, which would otherwise invalidate the touch port and discard every absolute mouse packet. Issue #16 (HTTPS control plane instability): - g_main_loop_run() inside dbus_response_wait() is now bounded by a 15s GLib timeout. A stalled portal previously wedged the entire nvhttp io thread, which made the host look offline from Moonlight for the full 120 s /resume timeout. The portal still fails the encoder probe, but other HTTPS handlers stay responsive. - The response signal is now subscribed BEFORE the proxy call is issued (not after it returns), so a fast portal response can't race the subscription setup. The request_path returned by the call is verified against the expected one, which prevents stale signals from an older request terminating the wait. - dbus_response_t gained a destructor that unsubscribes the signal subscription, removes the timeout source, and unrefs the captured response variant. This removes a concrete class of subscription/ variant leaks that fit the same pattern as the recent g_autofree double-free fix. The HTTPS-session use-after-free from #16 failure 3 still requires an ASan build to pinpoint reliably and is tracked separately. Verified: cmake --build (release + ASan) both compile cleanly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #14 and #16.
Bug 1 — portal cursor invisible on KDE (closes #14 bug 1)
select_screencast_sources()did not passcursor_modein theSelectSources options. Per the XDG Desktop Portal ScreenCast spec the
default is HIDDEN, so the PipeWire stream carried no cursor at all.
Fix: query the cached
AvailableCursorModesproperty on the screencastproxy. When EMBEDDED (2) is advertised (KDE returns
u 7= HIDDEN |EMBEDDED | METADATA), request
cursor_mode = EMBEDDEDso the cursoris composited into the stream. Compositors that reject EMBEDDED with
"Unavailable cursor mode 2" (RemoteDesktop, headless) keep the omit
behavior.
Bug 2 — absolute mouse silently dropped on KWin (closes #14 bug 2)
verify_and_update_display_parameters()accumulated desktop size fromthe physical dimensions only. KWin reports the physical resolution
as 0x0 via
wl_outputwhile the logical resolution is valid, soenv_width/env_heightwere left at 0. The touch port(
touch_port_t::operator bool) then required nonzero dimensions, theabsolute move handler dropped every packet, and the only diagnostic was
verbose-level.
Fix: fall back per monitor to the logical resolution when the physical
is 0x0, and as a last resort use the stream dimensions instead of
leaving the env size at zero. A warning is logged so the fallback is
visible instead of silent.
Bug 3 — HTTPS control plane wedged by untimed portal wait (closes #16 fix 1)
dbus_response_wait()enteredg_main_loop_run()with no timeout,called from
video::probe_encoders()on the nvhttp io thread. A stalledportal wedged the entire HTTPS server; Moonlight saw the host as
offline and /resume timed out after 120 s.
Fix: arm a 15 s GLib timeout in
dbus_response_init(). The wait nowreturns after at most 15 s, the encoder probe fails fast, and other
HTTPS handlers stay responsive.
While here:
(was subscribed after, racing a fast response).
generated, so a stale signal cannot terminate the wait for a
different request.
dbus_response_tgained a destructor that unsubscribes the signalsubscription, removes the timeout source, and unrefs the captured
response variant. Same bug class as the recent
g_autofreedouble-free fix (75c83f9), applied to the portal code path.
Out of scope for this PR (follow-up)
Issue #16 failure 3 (HTTPS session UAF during shutdown, PID 208986
core) still requires an ASan build to pinpoint reliably — GCC parallel
LTO partitioning isn't deterministic across builds, so the byte-
identical binary couldn't be reproduced. The fix in this PR removes a
concrete class of subscription/variant leaks that fit the same pattern;
the remaining UAF is tracked separately.
Verification
cmake --build build(release) andcmake --build build-asanboth compile cleanly with the changes. E2E verification on Fedora 44 /
KDE Plasma Wayland still belongs with the original reporter's setup.