aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-10-10 09:55:44 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-10-10 09:55:44 +0400
commit02f37c8573afb8cce9f38e8d4a809ea58ca3eae8 (patch)
tree7125f7dd3719d1e5367aeec834bec0ec1446a364
parent66533ae0b1b84c0d5acbc5e6618fb1700eeb61db (diff)
downloadniri-02f37c8573afb8cce9f38e8d4a809ea58ca3eae8.tar.gz
niri-02f37c8573afb8cce9f38e8d4a809ea58ca3eae8.tar.bz2
niri-02f37c8573afb8cce9f38e8d4a809ea58ca3eae8.zip
Extract dbus server startup
-rw-r--r--src/dbus/gnome_shell_screenshot.rs20
-rw-r--r--src/dbus/mod.rs92
-rw-r--r--src/dbus/mutter_display_config.rs18
-rw-r--r--src/dbus/mutter_screen_cast.rs18
-rw-r--r--src/dbus/mutter_service_channel.rs11
-rw-r--r--src/main.rs4
-rw-r--r--src/niri.rs137
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");