Commit Graph

39 Commits

Author SHA1 Message Date
RustDesk
6a27910f34 fix(wayland): back off the polling display lookups after a failure (drm) (#15865)
* fix(wayland): back off the polling display lookups after a failure (drm)

In drm builds an enumeration that fails with no endpoint named in the
environment falls back to the socket probe, which forks a child bounded by
seconds, and the display service asks again every 300 ms -- at a greeter
with no reachable compositor that is a probe child per turn, forever. Such
a failure now stamps a shared 5 s backoff, and only the polling callers
honor it: the 300 ms displays-changed check skips its turn and the 1.5 s
live layout poll returns no answer for that turn.

Only the failure that would fork stamps. A session server is spawned with
WAYLAND_DISPLAY set, so its failed connect bails in-process before any
fork; stamping there would buy nothing and cost recovery latency, so live
sessions keep master's behavior exactly. The stamp also survives
clear_wayland_displays_cache: it describes the seat, not the cache, and
the ~1/s capturer rebuild loop clears on every teardown -- dropping the
stamp with the cache would let that loop defeat the backoff and would
turn every post-hotplug failure into a "first" one forever.

The displays-changed check weighs the backoff against what is already
published. With nothing synced yet it always populates -- an unaugmented
DRM list beats the empty broadcast the send path would otherwise emit.
With a synced layout, a suppressed turn keeps it, and a fresh first
failure keeps it too; only a failure that persists across a backoff
replaces it with the DRM stack, so a hotplug at a failing seat converges
within one backoff while a transient failure never tears down a good
layout.

One-shot callers -- session init, pipewire stream setup, capturer info --
keep probing fresh through get_displays, whose failure semantics are
unchanged: replaying a transient failure there would latch an empty answer
into session-long state. Non-drm builds compile none of this.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(wayland): log DRM lookup failure once

* fix(wayland): reset lookup warning after recovery

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 09:57:06 +08:00
RustDesk
7c23fd3073 Revert "fix(linux): bound the xrandr call in the wayland primary-display look…" (#15806)
This reverts commit 2915076642.
2026-08-09 18:40:50 +08:00
Mariano Abad
2915076642 fix(linux): bound the xrandr call in the wayland primary-display lookup (#15802)
`try_xrandr_primary` runs a bare `Command::new("xrandr").output()`. Its two
siblings in the same file, `try_kscreen_primary` and the gdbus one, both go through
`run_with_timeout(.., COMMAND_TIMEOUT)`, and the comment above that helper says why:
these commands are known to hang. xrandr is the one left bare.

It matters because of where it runs. `get_primary_monitor` is called from
`get_displays` with the process-wide `DISPLAYS` guard held, and on a Wayland host
the caller can be the service, which has no DISPLAY and no session bus. An X client
that blocks there blocks every consumer of the display list behind the same lock.

No behaviour change when xrandr answers: same command, same parsing, one second of
patience.
2026-08-09 18:04:54 +08:00
xPrimeTime
4389687d9d fix(wayland): subscribe to portal Response before making the request (#15726)
`request_remote_desktop` and its response handlers call the portal method
first and only then subscribe to the resulting Request's `Response` signal,
using the object path returned by the call. The comment above
`create_session` already describes why that is wrong:

> To avoid a race condition between the caller subscribing to the signal
> after receiving the reply for the method call and the signal getting
> emitted, a convention for Request object paths has been established that
> allows the caller to subscribe to the signal before making the method
> call.

The code then does the opposite of what the comment says. When the portal
emits `Response` before our match rule is installed, the signal is dropped
and the flow stalls: `request_remote_desktop` spins its 3-minute wait loop
and gives up, so the user sees the screen picker again (or a failure) even
when a valid restore token would have restored the session silently.

Build the request path from our unique bus name plus the `handle_token` we
pass in the call arguments, per the Request documentation, and subscribe
before calling. Applied to all five portal calls: CreateSession,
SelectSources (both the ScreenCast and post-SelectDevices paths),
SelectDevices, and Start. The `handle_token` values are unchanged; they are
now named locals so the path and the argument cannot drift apart.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 12:46:09 +08:00
CHarris
b4af82157b fix: refresh wayland uinput range on compositor layout change (#15628)
* fix: refresh wayland uinput range on compositor layout change

The uinput absolute range is computed once at session init. If the
compositor layout changes mid-session (monitor scale or position
change, or a portal virtual output appearing once capture starts),
injected coordinates are rescaled by the stale range and land offset.

Poll the live desktop bounding box from the display service loop while
subscribed (one wayland roundtrip, throttled to 1.5s, no subprocesses)
and re-apply the uinput resolution when it changes. Also read a fresh
layout when computing the initial range in check_init, since the cache
is not cleared when a session closes through the restore-token path.

This is the X component of #15601. The stale advertised origins (the Y
component) are not touched here: re-advertising DisplayInfo mid-session
trips the portal re-negotiation and can drop displays.

Signed-off-by: Cody Harris <codyharris7188@gmail.com>

* fix: bound the mouse resolution IPC wait during session init

Wrap update_mouse_resolution in the same 3s timeout the periodic
refresh uses, so a hung IPC response can't stall check_init.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: build timeout future inside runtime, split linux lazy_static

Constructing the timeout future eagerly as the block_on argument panics
with 'there is no reactor running'; move it into the async block so it is
built inside the runtime context. Also move WAYLAND_UINPUT_RECT into its
own cfg-gated lazy_static block, an attribute on a single item inside the
shared block does not compile.

* fix: confirm uinput mouse device adopted new range before caching rect

send_refresh() now waits for the mouse service to ack that it recreated the
device with the new range instead of firing and forgetting, and
update_mouse_resolution() propagates that result. The layout poller only
caches the rect after the device actually adopts the range, so a failed
refresh errors and retries on the next check. The ack read is bounded by
IPC_REQUEST_TIMEOUT, matching the keyboard get-key-state path.

* fix: propagate refresh failures instead of caching a stale range

- input_service: error when the custom-mouse downcast fails so the poller
  retries instead of caching an unconfirmed refresh
- uinput: on device recreation failure, keep the current device and the
  IPC connection and withhold the ack so the client retries, instead of
  killing the mouse handler

* fix: remap injected wayland coords onto the live layout after a monitor moves

The range refresh corrects the uinput ABS bounds, but a single-display client
sends whole-desktop coordinates offset by the origin of the display it follows,
taken from the layout advertised at session init. When another monitor is
rescaled or moved that origin shifts, so the coordinate lands offset before it
reaches uinput and the range refresh cannot recover it.

Snapshot the per-display layout at init, poll the live layout on the existing
1.5s throttle, and when they differ remap each injected move into the followed
display's current rectangle (matched by connector name, index fallback when the
compositor reports none). No-op and lock-free while the layout is unchanged.

---------

Signed-off-by: Cody Harris <codyharris7188@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 18:35:49 +08:00
IronCodeStudios
377547fa11 scrap/wayland: insert videoconvert to fix screencast on COSMIC / DMA-BUF portals (#15063)
On Wayland compositors whose xdg-desktop-portal backend exposes screencast
frames as DMA-BUF buffers — notably xdg-desktop-portal-cosmic 0.1.0 on
Pop!_OS 24.04 / COSMIC — inbound screen capture fails. PipeWireRecorder
links pipewiresrc directly to an appsink whose caps only accept
video/x-raw BGRx/RGBx in system memory. That format set is too narrow for
the portal's buffer-type / modifier negotiation, which collapses with:

  pw.link: negotiating -> error no more output formats (-22)
  gstpipewiresrc: stream error: no more output formats
  gstbasesrc: streaming stopped, reason not-negotiated (-4)
  ERROR src/server/wayland.rs: Failed scrap Element failed to change its state

Inserting a videoconvert element between pipewiresrc and appsink widens
the negotiable format set to any system-memory video/x-raw format, giving
the portal room to settle on a format it can deliver via its SHM path.
videoconvert then converts to the BGRx/RGBx the appsink expects.

Verified on Pop!_OS 24.04 / COSMIC with gst-launch, before and after:

  # fails (current behaviour):
  gst-launch-1.0 pipewiresrc path=N ! video/x-raw,format=BGRx ! fakesink
  # works (with this change):
  gst-launch-1.0 pipewiresrc path=N ! videoconvert ! video/x-raw,format=BGRx ! fakesink

After the change, inbound connections capture and stream the desktop
normally and the "Failed scrap" error no longer occurs.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:02:23 +08:00
Leo Louis
a8dc6fc632 Fix capture method return type in Recorder trait (#14748) 2026-04-13 13:04:43 +08:00
Leo Louis
771cb4ebd7 Update capture function return type for PixelProvider (#14747) 2026-04-13 13:03:35 +08:00
fufesou
7f804a0e45 refact: wayland, pipewire display offset cache to file (#13542)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-11-18 14:16:59 +08:00
fufesou
b2dff336ce fix: wayland controlled side, cursor misalignment (#13537)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-11-18 00:37:15 +08:00
Nathan Saslavsky
eacb07988d Add Wayland multi-monitor screen capture functionality (#12900)
* Add Wayland multi-monitor screen capture functionality

* fix wayland capture issues by reverting to CapturerPtr, the problem was that calling Display::all in get_capturer_for_display was dropping the pipewire capturer and causing the video to freeze.

* If running as AppImage or flatpak, ignore the 'multiple' argument

* Comment out warning log with unclear purpose Comment out warning log with unclear purpose

---------

Co-authored-by: fufesou <13586388+fufesou@users.noreply.github.com>
2025-09-22 21:53:14 +08:00
fufesou
fd4e0146e1 fix: replace sh with CMD_SH (#12173)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-06-26 15:54:16 +08:00
fufesou
21bcfd173d fix: wayland, rdp input, mouse, scale (#9402)
* fix: wayland, rdp input, mouse, scale

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: rdp input, mouse, scale, check 0

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-09-20 11:15:19 +08:00
rustdesk
cba8aaa410 tooltip for https://github.com/rustdesk/rustdesk/issues/8600, and change
dialog error to richtext with link support
2024-07-30 14:42:21 +08:00
fufesou
8fa611daed refact: Wayland, not support multiple displays (#8280)
* refact: Wayland, not support multiple displays

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* refact: Wayland disable multiple for RemoteDesktop

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <shuanglongchen@yeah.net>
Signed-off-by: fufesou <linlong1266@gmail.com>
2024-06-07 12:59:42 +08:00
fufesou
bbe9017318 fix: wayland delete restore token (#7988)
* fix: wayland delete restore token

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* Wayland close session when clearing restore token

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* fix build

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* Refact Wayland option

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* Wayland clear screen selection, fake token

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* fix build web

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* fix: build

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* chore

Signed-off-by: fufesou <shuanglongchen@yeah.net>

---------

Signed-off-by: fufesou <shuanglongchen@yeah.net>
2024-05-09 11:03:59 +08:00
fufesou
5537c525ca refact: comments, wayland, restore token (#7947)
We cannot store restore_token if the server is not running.

Because `org.freedesktop.portal.RemoteDesktop` does not support persist
mode for now.

Signed-off-by: fufesou <shuanglongchen@yeah.net>
2024-05-08 09:49:16 +08:00
rustdesk
08b7e036b4 test vcpkg new in android 2024-05-01 12:58:27 +08:00
Sahil Yeole
20b4ce3213 Wayland: Skip remote desktop portal calls when uinput is available (#6758)
* skip rdp when uinput is available

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix is_server_running

* remove clones

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

---------

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>
2023-12-28 10:40:58 +08:00
RustDesk
4b581c385c Revert "fix xdg portal verison check for persist_mode (#6742)" (#6755)
This reverts commit 57acadd52a.
2023-12-27 11:28:17 +08:00
linuxrider
57acadd52a fix xdg portal verison check for persist_mode (#6742) 2023-12-24 16:33:36 +08:00
Sahil Yeole
445fe6e714 Feat: Wayland flatpak input support | Remote desktop portal (#6675)
* autogen portal code

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use remote desktop portal

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove clipboard portal in favour of #6586

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove clipboard portal

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use select_devices for input capture

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove embedded cursor code as not being used | return session path for input capture

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* setup rdp input

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove simulate example

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* setup rdp input raw key events + mouse movements

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix rdp raw key input

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* refact rdp raw key inpuy & fix right meta key

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* refact and support rdp layout mode key input

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* support rdp mouse clicks

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* support rdp mouse scroll

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* support rdp key sequence input

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use rdp input only when uinput is not available

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* combine rdp input and get_capturables into a single rdp request

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* rdp fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* rdp fix build

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix rdp caps lock

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* format pipewire.rs

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* format rdp_input.rs

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* revert #6628 as rdp request state is now managed (better solution)

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* fix rdp crash on arch kde

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* rdp_input.rs improvements

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* refact request_remote_desktop

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* improve unwraps

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* remove unwraps

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

* use session references instead of clones

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>

---------

Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>
2023-12-19 10:44:58 +08:00
Sahil Yeole
948db1451f fix stream resolution mismatch/distortion on scaling
Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>
2023-11-21 16:59:45 +05:30
21pages
aa740f4263 remove many unwrap and enum_value_or_default
Signed-off-by: 21pages <pages21@163.com>
2023-07-23 20:00:58 +08:00
fufesou
de1005acb2 do not embed cursor on wayland
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-03-20 13:58:02 +08:00
fufesou
74a73b7ffd add default position for portal streams
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-31 17:51:20 +08:00
fufesou
b84f3ba1ee init wayland to update var 'cursor embeded'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-29 12:41:16 +08:00
fufesou
7e0c9e17df set cursor mode according to availible modes
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-29 12:41:16 +08:00
rustdesk
0d0957cea5 remove u128 compare 2022-12-26 17:44:29 +08:00
Sangha Lee
59a82a9fbd downgrade gstreamer to 0.16 2022-12-22 20:42:34 +09:00
Sangha Lee
0819a3d8ea Revert "Merge pull request #2628 from rustdesk/revert-2612-master"
This reverts commit e50882a660, reversing
changes made to 7f006102b5.
2022-12-22 18:54:27 +09:00
RustDesk
9c24117b13 Revert "Implement RGB0 pixel format " 2022-12-22 12:22:26 +08:00
Sangha Lee
3643870287 fix unsafe code 2022-12-21 18:42:22 +09:00
Sangha Lee
38f66df091 implement RGB0 #2608 2022-12-21 04:12:34 +09:00
Sangha Lee
d910e7ad96 update gstreamer 2022-12-21 03:32:42 +09:00
fufesou
87306a3d01 wayland filter last same frame
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2022-11-25 19:28:43 +08:00
fufesou
e31130d4f8 wayland, fix check Lock && Mod Resolution
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2022-11-25 19:28:43 +08:00
RustDesk
7282c3a16d Update README.md 2021-07-23 17:54:16 +08:00
rustdesk
c15c44788c try out wayland 2021-07-23 17:52:38 +08:00