Skip to content

Commit 780e1d4

Browse files
olafkfreundclaude
andcommitted
feat: add RemoteDesktop portal with EIS input injection and consent dialog
Implements org.freedesktop.impl.portal.RemoteDesktop, enabling remote keyboard, mouse, and touchscreen input injection via the EIS protocol. The portal provides: - CreateSession/SelectDevices/SelectSources/Start/ConnectToEIS methods - A consent dialog with device type chips and screen/window selection - EIS socket pair creation forwarded to the compositor via D-Bus - Session lifecycle management with proper cleanup - Reuse of existing ScreenCast infrastructure for video streams Security model: - Consent dialog is always shown (never skipped via restore data) - Device types are masked to valid bits only - Per-session UNIX socket isolation - Portal's own D-Bus connection used for compositor calls Requires compositor support for AcceptEisSocket D-Bus method (com.system76.CosmicComp.RemoteDesktop). Closes #23 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 276af0b commit 780e1d4

File tree

9 files changed

+1105
-16
lines changed

9 files changed

+1105
-16
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ memmap2 = "0.9.8"
2929
pipewire = { git = "https://gitlab.freedesktop.org/pipewire/pipewire-rs", features = [
3030
"v0_3_33",
3131
] }
32+
reis = { version = "0.5", features = ["tokio"] }
3233
png = "0.18"
3334
rustix = { version = "1.1", features = ["fs"] }
3435
# spa_sys = { package = "libspa-sys", git = "https://github.com/pop-os/pipewire-rs" }

data/cosmic.portal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[portal]
22
DBusName=org.freedesktop.impl.portal.desktop.cosmic
3-
Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Settings;org.freedesktop.impl.portal.ScreenCast
3+
Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.RemoteDesktop;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Settings;org.freedesktop.impl.portal.ScreenCast
44
UseIn=COSMIC

i18n/en/xdg_desktop_portal_cosmic.ftl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ share-screen = Share your screen
1313
unknown-application = Unknown Application
1414
output = Output
1515
window = Window
16+
17+
remote-desktop-access = Remote Desktop Access
18+
.description = "{$app_name}" is requesting remote control of your desktop. The following inputs will be shared:
19+
remote-desktop-keyboard = keyboard
20+
remote-desktop-pointer = pointer
21+
remote-desktop-touchscreen = touchscreen

src/app.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{access, config, file_chooser, screencast_dialog, screenshot, subscription};
1+
use crate::{
2+
access, config, file_chooser, remote_desktop_dialog, screencast_dialog, screenshot,
3+
subscription,
4+
};
25
use cosmic::Task;
36
use cosmic::iced_core::event::wayland::OutputEvent;
47
use cosmic::widget;
@@ -38,6 +41,9 @@ pub struct CosmicPortal {
3841
pub screencast_args: Option<screencast_dialog::Args>,
3942
pub screencast_tab_model:
4043
widget::segmented_button::Model<widget::segmented_button::SingleSelect>,
44+
pub remotedesktop_args: Option<remote_desktop_dialog::Args>,
45+
pub remotedesktop_tab_model:
46+
widget::segmented_button::Model<widget::segmented_button::SingleSelect>,
4147
pub location_options: Vec<String>,
4248
pub prev_rectangle: Option<screenshot::Rect>,
4349
pub wayland_helper: crate::wayland::WaylandHelper,
@@ -63,6 +69,7 @@ pub enum Msg {
6369
FileChooser(window::Id, file_chooser::Msg),
6470
Screenshot(screenshot::Msg),
6571
Screencast(screencast_dialog::Msg),
72+
RemoteDesktop(remote_desktop_dialog::Msg),
6673
Portal(subscription::Event),
6774
Output(OutputEvent, WlOutput),
6875
ConfigSetScreenshot(config::screenshot::Screenshot),
@@ -112,6 +119,8 @@ impl cosmic::Application for CosmicPortal {
112119
screenshot_args: Default::default(),
113120
screencast_args: Default::default(),
114121
screencast_tab_model: Default::default(),
122+
remotedesktop_args: Default::default(),
123+
remotedesktop_tab_model: Default::default(),
115124
location_options: Vec::new(),
116125
prev_rectangle: Default::default(),
117126
outputs: Default::default(),
@@ -132,6 +141,8 @@ impl cosmic::Application for CosmicPortal {
132141
access::view(self).map(Msg::Access)
133142
} else if id == *screencast_dialog::SCREENCAST_ID {
134143
screencast_dialog::view(self).map(Msg::Screencast)
144+
} else if id == *remote_desktop_dialog::REMOTEDESKTOP_ID {
145+
remote_desktop_dialog::view(self).map(Msg::RemoteDesktop)
135146
} else if self.outputs.iter().any(|o| o.id == id) {
136147
screenshot::view(self, id).map(Msg::Screenshot)
137148
} else {
@@ -160,6 +171,12 @@ impl cosmic::Application for CosmicPortal {
160171
subscription::Event::CancelScreencast(handle) => {
161172
screencast_dialog::cancel(self, handle).map(cosmic::Action::App)
162173
}
174+
subscription::Event::RemoteDesktop(args) => {
175+
remote_desktop_dialog::update_args(self, args).map(cosmic::Action::App)
176+
}
177+
subscription::Event::CancelRemoteDesktop(handle) => {
178+
remote_desktop_dialog::cancel(self, handle).map(cosmic::Action::App)
179+
}
163180
subscription::Event::Config(config) => self.update(Msg::ConfigSubUpdate(config)),
164181
subscription::Event::Accent(_)
165182
| subscription::Event::IsDark(_)
@@ -175,6 +192,9 @@ impl cosmic::Application for CosmicPortal {
175192
},
176193
Msg::Screenshot(m) => screenshot::update_msg(self, m).map(cosmic::Action::App),
177194
Msg::Screencast(m) => screencast_dialog::update_msg(self, m).map(cosmic::Action::App),
195+
Msg::RemoteDesktop(m) => {
196+
remote_desktop_dialog::update_msg(self, m).map(cosmic::Action::App)
197+
}
178198
Msg::Output(o_event, wl_output) => {
179199
match o_event {
180200
OutputEvent::Created(Some(info))

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ mod buffer;
1414
mod documents;
1515
mod file_chooser;
1616
mod localize;
17+
mod remote_desktop;
18+
mod remote_desktop_dialog;
1719
mod screencast;
1820
mod screencast_dialog;
1921
mod screencast_thread;

0 commit comments

Comments
 (0)