Merge pull request #2982 from fufesou/fix/wayland_portal_cursor_mode

Fix/wayland portal cursor mode
This commit is contained in:
RustDesk 2023-01-29 13:08:17 +08:00 committed by GitHub
commit 3040997c45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 9 deletions

View File

@ -76,7 +76,7 @@ pub fn is_cursor_embedded() -> bool {
if is_x11() {
x11::IS_CURSOR_EMBEDDED
} else {
wayland::IS_CURSOR_EMBEDDED
wayland::is_cursor_embedded()
}
}

View File

@ -4,12 +4,33 @@ use std::{io, sync::RwLock, time::Duration};
pub struct Capturer(Display, Box<dyn Recorder>, bool, Vec<u8>);
pub const IS_CURSOR_EMBEDDED: bool = true;
static mut IS_CURSOR_EMBEDDED: Option<bool> = None;
lazy_static::lazy_static! {
static ref MAP_ERR: RwLock<Option<fn(err: String)-> io::Error>> = Default::default();
}
pub fn is_cursor_embedded() -> bool {
unsafe {
if IS_CURSOR_EMBEDDED.is_none() {
init_cursor_embedded();
}
IS_CURSOR_EMBEDDED.unwrap_or(false)
}
}
unsafe fn init_cursor_embedded() {
use crate::common::wayland::pipewire::get_available_cursor_modes;
match get_available_cursor_modes() {
Ok(modes) => {
IS_CURSOR_EMBEDDED = Some((modes & 0x02) > 0);
}
Err(..) => {
IS_CURSOR_EMBEDDED = Some(false);
}
}
}
pub fn set_map_err(f: fn(err: String) -> io::Error) {
*MAP_ERR.write().unwrap() = Some(f);
}
@ -74,7 +95,7 @@ impl Display {
}
pub fn all() -> io::Result<Vec<Display>> {
Ok(pipewire::get_capturables(true)
Ok(pipewire::get_capturables(is_cursor_embedded())
.map_err(map_err)?
.drain(..)
.map(|x| Display(x))

View File

@ -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<u32, dbus::Error> {
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,
@ -473,7 +479,17 @@ fn request_screen_cast(
args.insert("multiple".into(), Variant(Box::new(true)));
args.insert("types".into(), Variant(Box::new(1u32))); //| 2u32)));
let cursor_mode = if capture_cursor { 2u32 } else { 1u32 };
let mut cursor_mode = 0u32;
let mut available_cursor_modes = 0u32;
if let Ok(modes) = portal.available_cursor_modes() {
available_cursor_modes = modes;
}
if capture_cursor {
cursor_mode = 2u32 & available_cursor_modes;
}
if cursor_mode == 0 {
cursor_mode = 1u32 & available_cursor_modes;
}
let plasma = std::env::var("DESKTOP_SESSION").map_or(false, |s| s.contains("plasma"));
if plasma && capture_cursor {
// Warn the user if capturing the cursor is tried on kde as this can crash
@ -483,7 +499,9 @@ fn request_screen_cast(
desktop, see https://bugs.kde.org/show_bug.cgi?id=435042 for details! \
You have been warned.");
}
args.insert("cursor_mode".into(), Variant(Box::new(cursor_mode)));
if cursor_mode > 0 {
args.insert("cursor_mode".into(), Variant(Box::new(cursor_mode)));
}
let session: dbus::Path = r
.results
.get("session_handle")

View File

@ -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

View File

@ -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::{is_cursor_embedded, set_map_err, Capturer, Display, Frame, TraitCapturer};
use std::io;
use super::video_service::{
@ -12,7 +12,7 @@ lazy_static::lazy_static! {
static ref LOG_SCRAP_COUNT: Mutex<u32> = Mutex::new(0);
}
pub fn set_wayland_scrap_map_err() {
pub fn init() {
set_map_err(map_err_scrap);
}
@ -129,7 +129,7 @@ pub(super) async fn check_init() -> ResultType<()> {
let num = all.len();
let (primary, mut displays) = super::video_service::get_displays_2(&all);
for display in displays.iter_mut() {
display.cursor_embedded = true;
display.cursor_embedded = is_cursor_embedded();
}
let mut rects: Vec<((i32, i32), usize, usize)> = Vec::new();