aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-12-22 11:00:17 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-12-22 15:19:46 +0300
commit8dcc41a54d2606bab2d0e950f4b67668b48d9750 (patch)
tree26d0ec65bd1b8b2720a7d83b49cb5eb232c52552 /src
parentba3d2e36c874a8be5425ee4f403406bd6f0fe86d (diff)
downloadniri-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.
Diffstat (limited to 'src')
-rw-r--r--src/dbus/mod.rs4
-rw-r--r--src/niri.rs17
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