diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs index 1de2f89d6..1df96f511 100644 --- a/libs/scrap/src/common/mod.rs +++ b/libs/scrap/src/common/mod.rs @@ -12,7 +12,7 @@ cfg_if! { mod x11; pub use self::linux::*; pub use self::x11::Frame; - pub use self::wayland::set_map_err; + pub use self::wayland::{set_map_err, detect_cursor_embeded}; } else { mod x11; pub use self::x11::*; @@ -76,7 +76,7 @@ pub fn is_cursor_embedded() -> bool { if is_x11() { x11::IS_CURSOR_EMBEDDED } else { - wayland::IS_CURSOR_EMBEDDED + unsafe { wayland::IS_CURSOR_EMBEDDED } } } diff --git a/libs/scrap/src/common/wayland.rs b/libs/scrap/src/common/wayland.rs index e625fca7e..c807479f1 100644 --- a/libs/scrap/src/common/wayland.rs +++ b/libs/scrap/src/common/wayland.rs @@ -4,12 +4,26 @@ use std::{io, sync::RwLock, time::Duration}; pub struct Capturer(Display, Box, bool, Vec); -pub const IS_CURSOR_EMBEDDED: bool = true; +pub static mut IS_CURSOR_EMBEDDED: bool = true; lazy_static::lazy_static! { static ref MAP_ERR: RwLock io::Error>> = Default::default(); } +pub fn detect_cursor_embeded() { + if unsafe { IS_CURSOR_EMBEDDED } { + use crate::common::wayland::pipewire::get_available_cursor_modes; + match get_available_cursor_modes() { + Ok(modes) => unsafe { + IS_CURSOR_EMBEDDED = (modes & 0x02) > 0; + }, + Err(..) => unsafe { + IS_CURSOR_EMBEDDED = false; + }, + } + } +} + pub fn set_map_err(f: fn(err: String) -> io::Error) { *MAP_ERR.write().unwrap() = Some(f); } @@ -74,7 +88,7 @@ impl Display { } pub fn all() -> io::Result> { - Ok(pipewire::get_capturables(true) + Ok(pipewire::get_capturables(unsafe { IS_CURSOR_EMBEDDED }) .map_err(map_err)? .drain(..) .map(|x| Display(x)) diff --git a/libs/scrap/src/wayland/pipewire.rs b/libs/scrap/src/wayland/pipewire.rs index d1a8d9f85..fefab9b77 100644 --- a/libs/scrap/src/wayland/pipewire.rs +++ b/libs/scrap/src/wayland/pipewire.rs @@ -415,6 +415,12 @@ static mut INIT: bool = false; const RESTORE_TOKEN: &str = "restore_token"; const RESTORE_TOKEN_CONF_KEY: &str = "wayland-restore-token"; +pub fn get_available_cursor_modes() -> Result { + let conn = SyncConnection::new_session()?; + let portal = get_portal(&conn); + portal.available_cursor_modes() +} + // mostly inspired by https://gitlab.gnome.org/snippets/19 fn request_screen_cast( capture_cursor: bool, diff --git a/src/common.rs b/src/common.rs index 2bf287feb..c2d5a81f0 100644 --- a/src/common.rs +++ b/src/common.rs @@ -52,7 +52,7 @@ pub fn global_init() -> bool { #[cfg(target_os = "linux")] { if !*IS_X11 { - crate::server::wayland::set_wayland_scrap_map_err(); + crate::server::wayland::init(); } } true diff --git a/src/server/wayland.rs b/src/server/wayland.rs index 68b9c37cf..96fc2fff6 100644 --- a/src/server/wayland.rs +++ b/src/server/wayland.rs @@ -1,6 +1,6 @@ use super::*; use hbb_common::{allow_err, platform::linux::DISTRO}; -use scrap::{set_map_err, Capturer, Display, Frame, TraitCapturer}; +use scrap::{detect_cursor_embeded, set_map_err, Capturer, Display, Frame, TraitCapturer}; use std::io; use super::video_service::{ @@ -12,7 +12,8 @@ lazy_static::lazy_static! { static ref LOG_SCRAP_COUNT: Mutex = Mutex::new(0); } -pub fn set_wayland_scrap_map_err() { +pub fn init() { + detect_cursor_embeded(); set_map_err(map_err_scrap); }