From cf491da230e69c37d5c90b033cb4e7c5274dccca Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 6 Mar 2026 14:54:32 -0300 Subject: [PATCH 1/2] feat(wayland): add restore_token/persist_mode support for RemoteDesktop portal The RemoteDesktop portal path was missing persist_mode and restore_token support, causing a screen picker dialog on every connection. This adds: - Version check for RemoteDesktop portal (>= 2) separately from ScreenCast (>= 4) - persist_mode and restore_token args in SelectDevices for RemoteDesktop sessions - Token refresh from Start response for both portal paths (token is single-use) Fixes https://github.com/rustdesk/rustdesk/discussions/13902 --- libs/scrap/src/wayland/pipewire.rs | 41 +++++++++++++++++++----------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/libs/scrap/src/wayland/pipewire.rs b/libs/scrap/src/wayland/pipewire.rs index d29677c7a..dd2461ed7 100644 --- a/libs/scrap/src/wayland/pipewire.rs +++ b/libs/scrap/src/wayland/pipewire.rs @@ -633,9 +633,17 @@ pub fn request_remote_desktop( ); let mut is_support_restore_token = false; - if let Ok(version) = screencast_portal::version(&portal) { - if version >= 4 { - is_support_restore_token = true; + if is_server_running() { + if let Ok(version) = screencast_portal::version(&portal) { + if version >= 4 { + is_support_restore_token = true; + } + } + } else { + if let Ok(version) = remote_desktop_portal::version(&portal) { + if version >= 2 { + is_support_restore_token = true; + } } } @@ -774,8 +782,14 @@ fn on_create_session_response( failure.clone(), )?; } else { - // TODO: support persist_mode for remote_desktop_portal // https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html + if is_support_restore_token { + let restore_token = config::LocalConfig::get_option(RESTORE_TOKEN_CONF_KEY); + if !restore_token.is_empty() { + args.insert(RESTORE_TOKEN.to_string(), Variant(Box::new(restore_token))); + } + args.insert("persist_mode".to_string(), Variant(Box::new(2u32))); + } args.insert( "handle_token".to_string(), @@ -897,16 +911,13 @@ fn on_start_response( ) -> Result<(), Box> { move |r: OrgFreedesktopPortalRequestResponse, c, _| { let portal = get_portal(c); - // See `is_server_running()` to understand the following code. - if is_server_running() { - if is_support_restore_token { - if let Some(restore_token) = r.results.get(RESTORE_TOKEN) { - if let Some(restore_token) = restore_token.as_str() { - config::LocalConfig::set_option( - RESTORE_TOKEN_CONF_KEY.to_owned(), - restore_token.to_owned(), - ); - } + if is_support_restore_token { + if let Some(restore_token) = r.results.get(RESTORE_TOKEN) { + if let Some(restore_token) = restore_token.as_str() { + config::LocalConfig::set_option( + RESTORE_TOKEN_CONF_KEY.to_owned(), + restore_token.to_owned(), + ); } } } @@ -975,7 +986,7 @@ pub fn get_capturables() -> Result, Box> { // Otherwise, we have to use remote_desktop_portal's input method. // // `screencast_portal` supports restore_token and persist_mode if the version is greater than or equal to 4. -// `remote_desktop_portal` does not support restore_token and persist_mode. +// `remote_desktop_portal` supports restore_token and persist_mode if the version is greater than or equal to 2. pub(crate) fn is_server_running() -> bool { let v = IS_SERVER_RUNNING.load(Ordering::SeqCst); if v > 0 { From 33e19db5f60605bdb41464e5076ffa81c723069b Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 11 Mar 2026 11:50:35 +0000 Subject: [PATCH 2/2] ci: change nightly upload-tag for branch testing --- .github/workflows/flutter-nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index b16db4c4a..e6bec7de9 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -12,4 +12,4 @@ jobs: secrets: inherit with: upload-artifact: true - upload-tag: "nightly" + upload-tag: "rustdesk-persistent-perms-wayland-test"