mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
Extract dbus server startup
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+91
-1
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -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]) {
|
||||
|
||||
+11
-126
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user