diff options
| -rw-r--r-- | src/dbus/gnome_shell_screenshot.rs | 20 | ||||
| -rw-r--r-- | src/dbus/mod.rs | 92 | ||||
| -rw-r--r-- | src/dbus/mutter_display_config.rs | 18 | ||||
| -rw-r--r-- | src/dbus/mutter_screen_cast.rs | 18 | ||||
| -rw-r--r-- | src/dbus/mutter_service_channel.rs | 11 | ||||
| -rw-r--r-- | src/main.rs | 4 | ||||
| -rw-r--r-- | src/niri.rs | 137 |
7 files changed, 171 insertions, 129 deletions
diff --git a/src/dbus/gnome_shell_screenshot.rs b/src/dbus/gnome_shell_screenshot.rs index fad3649b..fbf3bc1f 100644 --- a/src/dbus/gnome_shell_screenshot.rs +++ b/src/dbus/gnome_shell_screenshot.rs @@ -1,7 +1,10 @@ use std::path::PathBuf; use smithay::reexports::calloop; -use zbus::{dbus_interface, fdo}; +use zbus::dbus_interface; +use zbus::fdo::{self, RequestNameFlags}; + +use super::Start; pub struct Screenshot { to_niri: calloop::channel::Sender<ScreenshotToNiri>, @@ -55,3 +58,18 @@ impl Screenshot { Self { to_niri, from_niri } } } + +impl Start for Screenshot { + fn start(self) -> anyhow::Result<zbus::blocking::Connection> { + let conn = zbus::blocking::Connection::session()?; + let flags = RequestNameFlags::AllowReplacement + | RequestNameFlags::ReplaceExisting + | RequestNameFlags::DoNotQueue; + + conn.object_server() + .at("/org/gnome/Shell/Screenshot", self)?; + conn.request_name_with_flags("org.gnome.Shell.Screenshot", flags)?; + + Ok(conn) + } +} diff --git a/src/dbus/mod.rs b/src/dbus/mod.rs index ca0dfacd..b4b2cdb0 100644 --- a/src/dbus/mod.rs +++ b/src/dbus/mod.rs @@ -1,5 +1,95 @@ +use smithay::reexports::calloop; +use zbus::blocking::Connection; +use zbus::Interface; + +use crate::niri::State; + pub mod gnome_shell_screenshot; pub mod mutter_display_config; +pub mod mutter_service_channel; + #[cfg(feature = "xdp-gnome-screencast")] pub mod mutter_screen_cast; -pub mod mutter_service_channel; +#[cfg(feature = "xdp-gnome-screencast")] +use mutter_screen_cast::ScreenCast; + +use self::mutter_display_config::DisplayConfig; +use self::mutter_service_channel::ServiceChannel; + +trait Start: Interface { + fn start(self) -> anyhow::Result<zbus::blocking::Connection>; +} + +#[derive(Default)] +pub struct DBusServers { + pub conn_service_channel: Option<Connection>, + pub conn_display_config: Option<Connection>, + pub conn_screen_shot: Option<Connection>, + #[cfg(feature = "xdp-gnome-screencast")] + pub conn_screen_cast: Option<Connection>, +} + +impl DBusServers { + pub fn start(state: &mut State, is_session_instance: bool) { + let _span = tracy_client::span!("DBusServers::start"); + + let backend = &state.backend; + let niri = &mut state.niri; + let config = niri.config.borrow(); + + let mut dbus = Self::default(); + + if is_session_instance { + let service_channel = ServiceChannel::new(niri.display_handle.clone()); + dbus.conn_service_channel = try_start(service_channel); + } + + if is_session_instance || config.debug.dbus_interfaces_in_non_session_instances { + let display_config = DisplayConfig::new(backend.connectors()); + dbus.conn_display_config = try_start(display_config); + + let (to_niri, from_screenshot) = calloop::channel::channel(); + let (to_screenshot, from_niri) = async_channel::unbounded(); + niri.event_loop + .insert_source(from_screenshot, move |event, _, state| match event { + calloop::channel::Event::Msg(msg) => { + state.on_screen_shot_msg(&to_screenshot, msg) + } + calloop::channel::Event::Closed => (), + }) + .unwrap(); + let screenshot = gnome_shell_screenshot::Screenshot::new(to_niri, from_niri); + dbus.conn_screen_shot = try_start(screenshot); + + #[cfg(feature = "xdp-gnome-screencast")] + { + let (to_niri, from_screen_cast) = calloop::channel::channel(); + niri.event_loop + .insert_source(from_screen_cast, { + let to_niri = to_niri.clone(); + move |event, _, state| match event { + calloop::channel::Event::Msg(msg) => { + state.on_screen_cast_msg(&to_niri, msg) + } + calloop::channel::Event::Closed => (), + } + }) + .unwrap(); + let screen_cast = ScreenCast::new(backend.connectors(), to_niri); + dbus.conn_screen_cast = try_start(screen_cast); + } + } + + niri.dbus = Some(dbus); + } +} + +fn try_start<I: Start>(iface: I) -> Option<Connection> { + match iface.start() { + Ok(conn) => Some(conn), + Err(err) => { + warn!("error starting {}: {err:?}", I::name()); + None + } + } +} diff --git a/src/dbus/mutter_display_config.rs b/src/dbus/mutter_display_config.rs index 1807f01d..663d3f8e 100644 --- a/src/dbus/mutter_display_config.rs +++ b/src/dbus/mutter_display_config.rs @@ -3,9 +3,12 @@ use std::sync::{Arc, Mutex}; use serde::Serialize; use smithay::output::Output; +use zbus::fdo::RequestNameFlags; use zbus::zvariant::{OwnedValue, Type}; use zbus::{dbus_interface, fdo}; +use super::Start; + pub struct DisplayConfig { connectors: Arc<Mutex<HashMap<String, Output>>>, } @@ -86,3 +89,18 @@ impl DisplayConfig { Self { connectors } } } + +impl Start for DisplayConfig { + fn start(self) -> anyhow::Result<zbus::blocking::Connection> { + let conn = zbus::blocking::Connection::session()?; + let flags = RequestNameFlags::AllowReplacement + | RequestNameFlags::ReplaceExisting + | RequestNameFlags::DoNotQueue; + + conn.object_server() + .at("/org/gnome/Mutter/DisplayConfig", self)?; + conn.request_name_with_flags("org.gnome.Mutter.DisplayConfig", flags)?; + + Ok(conn) + } +} diff --git a/src/dbus/mutter_screen_cast.rs b/src/dbus/mutter_screen_cast.rs index d64fa734..020d06a3 100644 --- a/src/dbus/mutter_screen_cast.rs +++ b/src/dbus/mutter_screen_cast.rs @@ -6,9 +6,12 @@ use std::sync::{Arc, Mutex}; use serde::Deserialize; use smithay::output::Output; use smithay::reexports::calloop; +use zbus::fdo::RequestNameFlags; use zbus::zvariant::{DeserializeDict, OwnedObjectPath, Type, Value}; use zbus::{dbus_interface, fdo, InterfaceRef, ObjectServer, SignalContext}; +use super::Start; + #[derive(Clone)] pub struct ScreenCast { connectors: Arc<Mutex<HashMap<String, Output>>>, @@ -200,6 +203,21 @@ impl ScreenCast { } } +impl Start for ScreenCast { + fn start(self) -> anyhow::Result<zbus::blocking::Connection> { + let conn = zbus::blocking::Connection::session()?; + let flags = RequestNameFlags::AllowReplacement + | RequestNameFlags::ReplaceExisting + | RequestNameFlags::DoNotQueue; + + conn.object_server() + .at("/org/gnome/Mutter/ScreenCast", self)?; + conn.request_name_with_flags("org.gnome.Mutter.ScreenCast", flags)?; + + Ok(conn) + } +} + impl Session { pub fn new( id: usize, diff --git a/src/dbus/mutter_service_channel.rs b/src/dbus/mutter_service_channel.rs index 29af6529..646bc4c5 100644 --- a/src/dbus/mutter_service_channel.rs +++ b/src/dbus/mutter_service_channel.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use smithay::reexports::wayland_server::DisplayHandle; use zbus::dbus_interface; +use super::Start; use crate::niri::ClientState; pub struct ServiceChannel { @@ -36,3 +37,13 @@ impl ServiceChannel { Self { display } } } + +impl Start for ServiceChannel { + fn start(self) -> anyhow::Result<zbus::blocking::Connection> { + let conn = zbus::blocking::ConnectionBuilder::session()? + .name("org.gnome.Mutter.ServiceChannel")? + .serve_at("/org/gnome/Mutter/ServiceChannel", self)? + .build()?; + Ok(conn) + } +} diff --git a/src/main.rs b/src/main.rs index 6680e11b..c9d10ea0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,6 +37,8 @@ use tracing_subscriber::EnvFilter; use utils::spawn; use watcher::Watcher; +use crate::dbus::DBusServers; + #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Cli { @@ -107,7 +109,7 @@ fn main() { } } - state.niri.start_dbus(&state.backend, is_systemd_service); + DBusServers::start(&mut state, is_systemd_service); // Notify systemd we're ready. if let Err(err) = sd_notify::notify(true, &[NotifyState::Ready]) { diff --git a/src/niri.rs b/src/niri.rs index ad5973e7..5d121b07 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -36,7 +36,7 @@ use smithay::output::Output; use smithay::reexports::calloop::generic::Generic; use smithay::reexports::calloop::timer::{TimeoutAction, Timer}; use smithay::reexports::calloop::{ - self, Idle, Interest, LoopHandle, LoopSignal, Mode, PostAction, RegistrationToken, + Idle, Interest, LoopHandle, LoopSignal, Mode, PostAction, RegistrationToken, }; use smithay::reexports::nix::libc::CLOCK_MONOTONIC; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::WmCapabilities; @@ -70,16 +70,14 @@ use smithay::wayland::socket::ListeningSocketSource; use smithay::wayland::tablet_manager::TabletManagerState; use smithay::wayland::text_input::TextInputManagerState; use smithay::wayland::virtual_keyboard::VirtualKeyboardManagerState; -use zbus::fdo::RequestNameFlags; use crate::backend::{Backend, Tty, Winit}; use crate::config::Config; use crate::cursor::Cursor; -use crate::dbus::gnome_shell_screenshot::{self, NiriToScreenshot, ScreenshotToNiri}; -use crate::dbus::mutter_display_config::DisplayConfig; +use crate::dbus::gnome_shell_screenshot::{NiriToScreenshot, ScreenshotToNiri}; #[cfg(feature = "xdp-gnome-screencast")] -use crate::dbus::mutter_screen_cast::{self, ScreenCast, ScreenCastToNiri}; -use crate::dbus::mutter_service_channel::ServiceChannel; +use crate::dbus::mutter_screen_cast::{self, ScreenCastToNiri}; +use crate::dbus::DBusServers; use crate::frame_clock::FrameClock; use crate::layout::{output_size, Layout, MonitorRenderElement}; use crate::pw_utils::{Cast, PipeWire}; @@ -136,7 +134,7 @@ pub struct Niri { pub cursor_image: CursorImageStatus, pub dnd_icon: Option<WlSurface>, - pub zbus_conn: Option<zbus::blocking::Connection>, + pub dbus: Option<DBusServers>, pub inhibit_power_key_fd: Option<zbus::zvariant::OwnedFd>, // Casts are dropped before PipeWire to prevent a double-free (yay). @@ -308,9 +306,9 @@ impl State { } #[cfg(feature = "xdp-gnome-screencast")] - fn on_screen_cast_msg( + pub fn on_screen_cast_msg( &mut self, - to_niri: &calloop::channel::Sender<ScreenCastToNiri>, + to_niri: &smithay::reexports::calloop::channel::Sender<ScreenCastToNiri>, msg: ScreenCastToNiri, ) { match msg { @@ -354,7 +352,7 @@ impl State { } } - fn on_screen_shot_msg( + pub fn on_screen_shot_msg( &mut self, to_screenshot: &async_channel::Sender<NiriToScreenshot>, msg: ScreenshotToNiri, @@ -535,127 +533,13 @@ impl Niri { cursor_image: CursorImageStatus::default_named(), dnd_icon: None, - zbus_conn: None, + dbus: None, inhibit_power_key_fd: None, pipewire, casts: vec![], } } - pub fn start_dbus(&mut self, backend: &Backend, is_session_instance: bool) { - let config = self.config.borrow(); - - #[cfg(feature = "xdp-gnome-screencast")] - let (to_niri, from_screen_cast) = calloop::channel::channel(); - #[cfg(feature = "xdp-gnome-screencast")] - self.event_loop - .insert_source(from_screen_cast, { - let to_niri = to_niri.clone(); - move |event, _, state| match event { - calloop::channel::Event::Msg(msg) => state.on_screen_cast_msg(&to_niri, msg), - calloop::channel::Event::Closed => (), - } - }) - .unwrap(); - #[cfg(feature = "xdp-gnome-screencast")] - let screen_cast = ScreenCast::new(backend.connectors(), to_niri); - - let (to_niri, from_screenshot) = calloop::channel::channel(); - let (to_screenshot, from_niri) = async_channel::unbounded(); - self.event_loop - .insert_source(from_screenshot, move |event, _, state| match event { - calloop::channel::Event::Msg(msg) => state.on_screen_shot_msg(&to_screenshot, msg), - calloop::channel::Event::Closed => (), - }) - .unwrap(); - let screenshot = gnome_shell_screenshot::Screenshot::new(to_niri, from_niri); - - let mut zbus_conn = None; - if is_session_instance { - let conn = zbus::blocking::ConnectionBuilder::session() - .unwrap() - .name("org.gnome.Mutter.ServiceChannel") - .unwrap() - .serve_at( - "/org/gnome/Mutter/ServiceChannel", - ServiceChannel::new(self.display_handle.clone()), - ) - .unwrap() - .build() - .unwrap(); - - { - let server = conn.object_server(); - let flags = RequestNameFlags::AllowReplacement - | RequestNameFlags::ReplaceExisting - | RequestNameFlags::DoNotQueue; - - server - .at("/org/gnome/Shell/Screenshot", screenshot) - .unwrap(); - conn.request_name_with_flags("org.gnome.Shell.Screenshot", flags) - .unwrap(); - - server - .at( - "/org/gnome/Mutter/DisplayConfig", - DisplayConfig::new(backend.connectors()), - ) - .unwrap(); - conn.request_name_with_flags("org.gnome.Mutter.DisplayConfig", flags) - .unwrap(); - - #[cfg(feature = "xdp-gnome-screencast")] - if self.pipewire.is_some() { - server - .at("/org/gnome/Mutter/ScreenCast", screen_cast.clone()) - .unwrap(); - conn.request_name_with_flags("org.gnome.Mutter.ScreenCast", flags) - .unwrap(); - } - } - - zbus_conn = Some(conn); - } else if config.debug.dbus_interfaces_in_non_session_instances { - let conn = zbus::blocking::Connection::session().unwrap(); - let flags = RequestNameFlags::AllowReplacement - | RequestNameFlags::ReplaceExisting - | RequestNameFlags::DoNotQueue; - - { - let server = conn.object_server(); - - server - .at("/org/gnome/Shell/Screenshot", screenshot) - .unwrap(); - conn.request_name_with_flags("org.gnome.Shell.Screenshot", flags) - .unwrap(); - - server - .at( - "/org/gnome/Mutter/DisplayConfig", - DisplayConfig::new(backend.connectors()), - ) - .unwrap(); - conn.request_name_with_flags("org.gnome.Mutter.DisplayConfig", flags) - .unwrap(); - - #[cfg(feature = "xdp-gnome-screencast")] - if self.pipewire.is_some() { - server - .at("/org/gnome/Mutter/ScreenCast", screen_cast.clone()) - .unwrap(); - conn.request_name_with_flags("org.gnome.Mutter.ScreenCast", flags) - .unwrap(); - } - } - - zbus_conn = Some(conn); - } - - self.zbus_conn = zbus_conn; - } - pub fn inhibit_power_key(&mut self) -> anyhow::Result<()> { let conn = zbus::blocking::ConnectionBuilder::system()?.build()?; @@ -1580,7 +1464,8 @@ impl Niri { } } - let server = self.zbus_conn.as_ref().unwrap().object_server(); + let dbus = &self.dbus.as_ref().unwrap(); + let server = dbus.conn_screen_cast.as_ref().unwrap().object_server(); let path = format!("/org/gnome/Mutter/ScreenCast/Session/u{}", session_id); if let Ok(iface) = server.interface::<_, mutter_screen_cast::Session>(path) { let _span = tracy_client::span!("invoking Session::stop"); |
