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.
This commit is contained in:
Ivan Molodetskikh
2024-12-22 11:00:17 +03:00
parent ba3d2e36c8
commit 8dcc41a54d
2 changed files with 11 additions and 10 deletions
+1 -3
View File
@@ -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");
}
}
+10 -7
View File
@@ -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