diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-22 11:00:17 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-22 15:19:46 +0300 |
| commit | 8dcc41a54d2606bab2d0e950f4b67668b48d9750 (patch) | |
| tree | 26d0ec65bd1b8b2720a7d83b49cb5eb232c52552 | |
| parent | ba3d2e36c874a8be5425ee4f403406bd6f0fe86d (diff) | |
| download | niri-8dcc41a54d2606bab2d0e950f4b67668b48d9750.tar.gz niri-8dcc41a54d2606bab2d0e950f4b67668b48d9750.tar.bz2 niri-8dcc41a54d2606bab2d0e950f4b67668b48d9750.zip | |
Initialize PipeWire lazily
This helps with:
- System setups starting PipeWire late (after niri startup, but before any
screencast).
- Tests which don't even want to start PipeWire.
| -rw-r--r-- | src/dbus/mod.rs | 4 | ||||
| -rw-r--r-- | src/niri.rs | 17 |
2 files changed, 11 insertions, 10 deletions
diff --git a/src/dbus/mod.rs b/src/dbus/mod.rs index eab72ce7..a231a1d1 100644 --- a/src/dbus/mod.rs +++ b/src/dbus/mod.rs @@ -83,7 +83,7 @@ impl DBusServers { dbus.conn_introspect = try_start(introspect); #[cfg(feature = "xdp-gnome-screencast")] - if niri.pipewire.is_some() { + { let (to_niri, from_screen_cast) = calloop::channel::channel(); niri.event_loop .insert_source(from_screen_cast, { @@ -95,8 +95,6 @@ impl DBusServers { .unwrap(); let screen_cast = ScreenCast::new(backend.ipc_outputs(), to_niri); dbus.conn_screen_cast = try_start(screen_cast); - } else { - warn!("disabling screencast support because we couldn't start PipeWire"); } } diff --git a/src/niri.rs b/src/niri.rs index 03b4b4e4..d5cb5fdb 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -1,4 +1,4 @@ -use std::cell::{Cell, OnceCell, RefCell}; +use std::cell::{Cell, LazyCell, OnceCell, RefCell}; use std::collections::{HashMap, HashSet}; use std::ffi::OsString; use std::path::PathBuf; @@ -327,7 +327,7 @@ pub struct Niri { // Casts are dropped before PipeWire to prevent a double-free (yay). pub casts: Vec<Cast>, - pub pipewire: Option<PipeWire>, + pub pipewire: LazyCell<Option<PipeWire>, Box<dyn FnOnce() -> Option<PipeWire>>>, // Screencast output for each mapped window. #[cfg(feature = "xdp-gnome-screencast")] @@ -1504,13 +1504,15 @@ impl State { let gbm = match self.backend.gbm_device() { Some(gbm) => gbm, None => { - debug!("no GBM device available"); + warn!("error starting screencast: no GBM device available"); + self.niri.stop_cast(session_id); return; } }; - let Some(pw) = &self.niri.pipewire else { - error!("screencasting must be disabled if PipeWire is missing"); + let Some(pw) = &*self.niri.pipewire else { + warn!("error starting screencast: PipeWire failed to initialize"); + self.niri.stop_cast(session_id); return; }; @@ -1882,13 +1884,14 @@ impl Niri { } }; - let pipewire = match PipeWire::new(&event_loop) { + let loop_handle = event_loop.clone(); + let pipewire = LazyCell::new(Box::new(move || match PipeWire::new(&loop_handle) { Ok(pipewire) => Some(pipewire), Err(err) => { warn!("error connecting to PipeWire, screencasting will not work: {err:?}"); None } - }; + }) as _); let display_source = Generic::new(display, Interest::READ, Mode::Level); event_loop |
