diff --git a/wayvr/src/overlays/screen/pw.rs b/wayvr/src/overlays/screen/pw.rs index 6e5eaa58..afe0740f 100644 --- a/wayvr/src/overlays/screen/pw.rs +++ b/wayvr/src/overlays/screen/pw.rs @@ -18,6 +18,9 @@ use wlx_capture::{ }; use wlx_common::{astr_containers::AStrMapExt, overlays::ToastTopic}; +#[cfg(feature = "x11")] +use wlx_capture::xshm::XshmScreen; + use crate::{ backend::task::{OverlayTask, TaskType}, gui::panel::{GuiPanel, NewGuiPanelParams}, @@ -112,6 +115,51 @@ impl ScreenCastBackend { finalize_fn, ) } + #[cfg(feature = "x11")] + pub fn new_x11pw( + m: &XshmScreen, + token: Option>, + app: &mut AppState, + ) -> anyhow::Result { + use glam::vec2; + + fn finalize_fn( + name: Arc, + logical_pos: Vec2, + logical_size: Vec2, + capture: Box>, + app: &mut AppState, + ) -> Box { + use wlx_capture::frame::Transform; + + let mut backend = + ScreenBackend::new_raw(name, app.feats.xr_backend, CaptureType::PipeWire, capture); + + backend.logical_pos = logical_pos; + backend.logical_size = logical_size; + backend.apply_mouse_transform_with_override(Transform::Undefined); + + Box::new(backend) + } + + let params = ScreenCastParams { + token, + embed_mouse: true, + screens_only: true, + persist: true, + allow_multiple: false, + }; + + Self::new_raw( + m.name.clone(), + format!("{} {}", m.monitor.x(), m.monitor.y()).into(), + vec2(m.monitor.x() as f32, m.monitor.y() as f32), + vec2(m.monitor.width() as f32, m.monitor.height() as f32), + params, + app, + finalize_fn, + ) + } pub(super) fn new_raw( name: Arc, diff --git a/wayvr/src/overlays/screen/x11.rs b/wayvr/src/overlays/screen/x11.rs index 80d44a8d..a02ca487 100644 --- a/wayvr/src/overlays/screen/x11.rs +++ b/wayvr/src/overlays/screen/x11.rs @@ -1,14 +1,15 @@ use std::sync::Arc; +use wgui::log::LogErr; + use glam::{DVec2, vec2}; use wlx_capture::{ WlxCapture, frame::Transform, xshm::{XshmCapture, XshmScreen}, }; +use wlx_common::{astr_containers::AStrMapExt, config::CaptureMethod}; -#[cfg(feature = "pipewire")] -use crate::state::save_pw_token_config; use crate::{ overlays::screen::{backend::CaptureType, create_screen_from_backend}, state::{AppState, ScreenMeta}, @@ -21,9 +22,7 @@ use super::{ }; #[cfg(feature = "pipewire")] -use wlx_capture::pipewire::{ - PipewireStream, ScreenCastParams, capture::PipewireCapture, screen_cast_select_blocking, -}; +use crate::{overlays::screen::pw::ScreenCastBackend, windowing::backend::OverlayBackend}; impl ScreenBackend { pub fn new_xshm(screen: Arc, app: &AppState) -> Self { @@ -40,45 +39,43 @@ impl ScreenBackend { } } +#[cfg(feature = "pipewire")] +pub fn create_screen_renderer_x11pw( + output: &XshmScreen, + app: &mut AppState, +) -> anyhow::Result> { + let display_name = &*output.name; + + // Find existing token by display + let token = app + .session + .pw_tokens + .arc_get(display_name) + .map(|x| x.to_string().into()); + + if token.is_some() { + log::info!("Found existing Pipewire token for display {display_name}"); + } + + Ok(Box::new( + ScreenCastBackend::new_x11pw(output, token, app) + .log_err("Failed to create screen with screen cast backend")?, + )) +} + #[cfg(feature = "pipewire")] pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result { use wlx_capture::xshm::xshm_get_monitors; - use wlx_common::astr_containers::AStrMapExt; use crate::{overlays::screen::create_screen_from_backend, state::ScreenMeta}; use super::ScreenCreateData; - let pw_tokens_copy = app.session.pw_tokens.clone(); - - let params = ScreenCastParams { - token: app - .session - .pw_tokens - .arc_get("x11") - .map(|x| x.clone().into()), - embed_mouse: !app.session.config.double_cursor_fix, - allow_multiple: true, - persist: true, - screens_only: true, - }; - - // this one still blocks - let select_screen_result = screen_cast_select_blocking(params)?; - - if let Some(restore_token) = select_screen_result.restore_token - && app - .session - .pw_tokens - .arc_set("x11".into(), restore_token.clone()) - { - log::info!("Adding Pipewire token {restore_token}"); - } - if pw_tokens_copy != app.session.pw_tokens { - // Token list changed, re-create token config file - if let Err(err) = save_pw_token_config(app.session.pw_tokens.clone()) { - log::error!("Failed to save Pipewire token config: {err}"); - } + if !matches!( + app.session.config.capture_method, + CaptureMethod::PipeWireCpu | CaptureMethod::PipeWire + ) { + anyhow::bail!("Pipewire is not selected as backend"); } let monitors = match xshm_get_monitors() { @@ -87,49 +84,39 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result anyhow::Result( - stream: &PipewireStream, - mut streams: impl Iterator, -) -> Option<&'a XshmScreen> { - let mut best = streams.next(); - log::debug!("stream: {:?}", stream.position); - log::debug!("first: {:?}", best.map(|b| &b.monitor)); - let Some(position) = stream.position else { - return best; - }; - - let mut best_dist = best.map_or(i32::MAX, |b| { - (b.monitor.x() - position.0).abs() + (b.monitor.y() - position.1).abs() - }); - for stream in streams { - log::debug!("checking: {:?}", stream.monitor); - let dist = - (stream.monitor.x() - position.0).abs() + (stream.monitor.y() - position.1).abs(); - if dist < best_dist { - best = Some(stream); - best_dist = dist; - } - } - log::debug!("best: {:?}", best.map(|b| &b.monitor)); - best -} - pub fn create_screens_xshm(app: &mut AppState) -> anyhow::Result { use wlx_capture::xshm::xshm_get_monitors; diff --git a/wlx-common/src/config.rs b/wlx-common/src/config.rs index c54c9619..bafb3cae 100644 --- a/wlx-common/src/config.rs +++ b/wlx-common/src/config.rs @@ -25,11 +25,7 @@ pub enum CaptureMethod { Auto, #[serde(alias = "pipewire")] - #[strum(props( - Text = "PipeWire GPU", - Tooltip = "APP_SETTINGS.OPTION.PIPEWIRE_HELP", - Desktop = "Wayland" - ))] + #[strum(props(Text = "PipeWire GPU", Tooltip = "APP_SETTINGS.OPTION.PIPEWIRE_HELP"))] PipeWire, #[strum(props( @@ -40,11 +36,7 @@ pub enum CaptureMethod { ScreenCopyGpu, #[serde(alias = "pw-fallback")] - #[strum(props( - Text = "PipeWire CPU", - Tooltip = "APP_SETTINGS.OPTION.PW_FALLBACK_HELP", - Desktop = "Wayland" - ))] + #[strum(props(Text = "PipeWire CPU", Tooltip = "APP_SETTINGS.OPTION.PW_FALLBACK_HELP"))] PipeWireCpu, #[serde(alias = "screencopy")]