aboutsummaryrefslogtreecommitdiff
path: root/src/dbus/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbus/mod.rs')
-rw-r--r--src/dbus/mod.rs92
1 files changed, 91 insertions, 1 deletions
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
+ }
+ }
+}