diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df8403a..64879bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,9 @@ jobs: with: key: ${{ matrix.configuration }} + - name: Build (no default features) + run: cargo build ${{ matrix.release-flag }} --no-default-features + - name: Build run: cargo build ${{ matrix.release-flag }} diff --git a/Cargo.toml b/Cargo.toml index a361602..5f12e74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ logind-zbus = "3.1.2" log = { version = "0.4.20", features = ["max_level_trace", "release_max_level_debug"] } miette = "5.10.0" nix = { version = "0.27.1", default-features = false, features = ["time"] } -pipewire = "0.7.2" +pipewire = { version = "0.7.2", optional = true } portable-atomic = { version = "1.4.3", default-features = false, features = ["float"] } profiling = "1.0.11" sd-notify = "0.4.1" @@ -62,6 +62,10 @@ proptest = "1.2.0" proptest-derive = "0.4.0" [features] +default = ["xdp-gnome-screencast"] +# Enables screencasting support through xdg-desktop-portal-gnome. +xdp-gnome-screencast = ["pipewire"] +# Enables the Tracy profiler instrumentation. profile-with-tracy = ["profiling/profile-with-tracy", "tracy-client/default"] [profile.release] diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 6475cab..0c27abd 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -2,8 +2,6 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Duration; -use smithay::backend::allocator::gbm::GbmDevice; -use smithay::backend::drm::DrmDeviceFd; use smithay::backend::renderer::gles::GlesRenderer; use smithay::output::Output; use smithay::wayland::dmabuf::DmabufFeedback; @@ -93,7 +91,11 @@ impl Backend { } } - pub fn gbm_device(&self) -> Option> { + #[cfg(feature = "xdp-gnome-screencast")] + pub fn gbm_device( + &self, + ) -> Option> + { match self { Backend::Tty(tty) => tty.gbm_device(), Backend::Winit(_) => None, diff --git a/src/backend/tty.rs b/src/backend/tty.rs index c4ac14e..11595ef 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -853,6 +853,7 @@ impl Tty { self.connectors.clone() } + #[cfg(feature = "xdp-gnome-screencast")] pub fn gbm_device(&self) -> Option> { self.output_device.as_ref().map(|d| d.gbm.clone()) } diff --git a/src/dbus/mod.rs b/src/dbus/mod.rs index 459af25..ca0dfac 100644 --- a/src/dbus/mod.rs +++ b/src/dbus/mod.rs @@ -1,4 +1,5 @@ pub mod gnome_shell_screenshot; pub mod mutter_display_config; +#[cfg(feature = "xdp-gnome-screencast")] pub mod mutter_screen_cast; pub mod mutter_service_channel; diff --git a/src/dummy_pw_utils.rs b/src/dummy_pw_utils.rs new file mode 100644 index 0000000..a0939cd --- /dev/null +++ b/src/dummy_pw_utils.rs @@ -0,0 +1,13 @@ +use anyhow::bail; +use smithay::reexports::calloop::LoopHandle; + +use crate::niri::State; + +pub struct PipeWire; +pub struct Cast; + +impl PipeWire { + pub fn new(_event_loop: &LoopHandle<'static, State>) -> anyhow::Result { + bail!("PipeWire support is disabled (see \"xdp-gnome-screencast\" feature)"); + } +} diff --git a/src/main.rs b/src/main.rs index 7db9e4d..0aa0592 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,16 +10,21 @@ mod handlers; mod input; mod layout; mod niri; -mod pw_utils; mod utils; mod watcher; +#[cfg(not(feature = "xdp-gnome-screencast"))] +mod dummy_pw_utils; +#[cfg(feature = "xdp-gnome-screencast")] +mod pw_utils; use std::ffi::OsString; use std::path::PathBuf; use std::{env, mem}; use clap::Parser; use config::Config; +#[cfg(not(feature = "xdp-gnome-screencast"))] +use dummy_pw_utils as pw_utils; use miette::{Context, NarratableReportHandler}; use niri::{Niri, State}; use portable_atomic::Ordering; diff --git a/src/niri.rs b/src/niri.rs index a5663e3..6f152a0 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -11,7 +11,6 @@ use std::{env, thread}; use _server_decoration::server::org_kde_kwin_server_decoration_manager::Mode as KdeDecorationsMode; use anyhow::Context; use sd_notify::NotifyState; -use smithay::backend::allocator::dmabuf::Dmabuf; use smithay::backend::allocator::Fourcc; use smithay::backend::renderer::element::surface::{ render_elements_from_surface_tree, WaylandSurfaceRenderElement, @@ -19,7 +18,7 @@ use smithay::backend::renderer::element::surface::{ use smithay::backend::renderer::element::texture::{TextureBuffer, TextureRenderElement}; use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement}; use smithay::backend::renderer::element::{ - render_elements, AsRenderElements, Element, Kind, RenderElement, RenderElementStates, + render_elements, AsRenderElements, Kind, RenderElement, RenderElementStates, }; use smithay::backend::renderer::gles::{GlesMapping, GlesRenderer, GlesTexture}; use smithay::backend::renderer::{Bind, ExportMem, Frame, ImportAll, Offscreen, Renderer}; @@ -71,6 +70,7 @@ use crate::backend::{Backend, Tty, Winit}; use crate::config::Config; use crate::dbus::gnome_shell_screenshot::{self, NiriToScreenshot, ScreenshotToNiri}; use crate::dbus::mutter_display_config::DisplayConfig; +#[cfg(feature = "xdp-gnome-screencast")] use crate::dbus::mutter_screen_cast::{self, ScreenCast, ToNiriMsg}; use crate::dbus::mutter_service_channel::ServiceChannel; use crate::frame_clock::FrameClock; @@ -122,6 +122,7 @@ pub struct Niri { pub zbus_conn: Option, pub inhibit_power_key_fd: Option, + #[cfg(feature = "xdp-gnome-screencast")] pub screen_cast: ScreenCast, // Casts are dropped before PipeWire to prevent a double-free (yay). @@ -334,7 +335,9 @@ impl Niri { } }; + #[cfg(feature = "xdp-gnome-screencast")] let (to_niri, from_screen_cast) = calloop::channel::channel(); + #[cfg(feature = "xdp-gnome-screencast")] event_loop .insert_source(from_screen_cast, { let to_niri = to_niri.clone(); @@ -419,6 +422,7 @@ impl Niri { } }) .unwrap(); + #[cfg(feature = "xdp-gnome-screencast")] let screen_cast = ScreenCast::new(backend.connectors(), to_niri); let (to_niri, from_screenshot) = calloop::channel::channel(); @@ -520,20 +524,22 @@ impl Niri { 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 pipewire.is_some() { server .at("/org/gnome/Mutter/ScreenCast", screen_cast.clone()) .unwrap(); - server - .at( - "/org/gnome/Mutter/DisplayConfig", - DisplayConfig::new(backend.connectors()), - ) - .unwrap(); conn.request_name_with_flags("org.gnome.Mutter.ScreenCast", flags) .unwrap(); - conn.request_name_with_flags("org.gnome.Mutter.DisplayConfig", flags) - .unwrap(); } } @@ -584,20 +590,22 @@ impl Niri { 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 pipewire.is_some() { server .at("/org/gnome/Mutter/ScreenCast", screen_cast.clone()) .unwrap(); - server - .at( - "/org/gnome/Mutter/DisplayConfig", - DisplayConfig::new(backend.connectors()), - ) - .unwrap(); conn.request_name_with_flags("org.gnome.Mutter.ScreenCast", flags) .unwrap(); - conn.request_name_with_flags("org.gnome.Mutter.DisplayConfig", flags) - .unwrap(); } } @@ -650,6 +658,7 @@ impl Niri { zbus_conn, inhibit_power_key_fd, + #[cfg(feature = "xdp-gnome-screencast")] screen_cast, pipewire, casts: vec![], @@ -1033,10 +1042,13 @@ impl Niri { self.send_frame_callbacks(output); // Render and send to PipeWire screencast streams. - let renderer = backend - .renderer() - .expect("renderer must not have disappeared"); - self.send_for_screen_cast(renderer, output, &elements, presentation_time); + #[cfg(feature = "xdp-gnome-screencast")] + { + let renderer = backend + .renderer() + .expect("renderer must not have disappeared"); + self.send_for_screen_cast(renderer, output, &elements, presentation_time); + } } fn send_dmabuf_feedbacks(&self, output: &Output, feedback: &DmabufFeedback) { @@ -1173,6 +1185,7 @@ impl Niri { feedback } + #[cfg(feature = "xdp-gnome-screencast")] fn send_for_screen_cast( &mut self, renderer: &mut GlesRenderer, @@ -1393,13 +1406,16 @@ fn render_to_vec( Ok(copy.to_vec()) } +#[cfg(feature = "xdp-gnome-screencast")] fn render_to_dmabuf( renderer: &mut GlesRenderer, - dmabuf: Dmabuf, + dmabuf: smithay::backend::allocator::dmabuf::Dmabuf, size: Size, scale: Scale, elements: &[OutputRenderElements], ) -> anyhow::Result<()> { + use smithay::backend::renderer::element::Element; + let _span = tracy_client::span!("render_to_dmabuf"); let output_rect = Rectangle::from_loc_and_size((0, 0), size);