wayland, fix check Lock && Mod Resolution

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2022-11-23 23:57:01 +08:00
parent fc89257566
commit e31130d4f8
3 changed files with 44 additions and 10 deletions

View File

@ -16,9 +16,10 @@ use gstreamer as gst;
use gstreamer::prelude::*;
use gstreamer_app::AppSink;
use hbb_common::config;
use super::capturable::PixelProvider;
use super::capturable::{Capturable, Recorder};
use super::pipewire_dbus::{OrgFreedesktopPortalRequestResponse, OrgFreedesktopPortalScreenCast};
#[derive(Debug, Clone, Copy)]
@ -130,6 +131,7 @@ impl PipeWireRecorder {
let src = gst::ElementFactory::make("pipewiresrc", None)?;
src.set_property("fd", &capturable.fd.as_raw_fd())?;
src.set_property("path", &format!("{}", capturable.path))?;
src.set_property("keepalive_time", &1_000.as_raw_fd())?;
// For some reason pipewire blocks on destruction of AppSink if this is not set to true,
// see: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/982
@ -384,6 +386,8 @@ fn streams_from_response(response: OrgFreedesktopPortalRequestResponse) -> Vec<P
}
static mut INIT: bool = false;
const RESTORE_TOKEN: &str = "restore_token";
const RESTORE_TOKEN_CONF_KEY: &str = "wayland-restore-token";
// mostly inspired by https://gitlab.gnome.org/snippets/19
fn request_screen_cast(
@ -412,6 +416,12 @@ fn request_screen_cast(
"handle_token".to_string(),
Variant(Box::new("u1".to_string())),
);
// The following code may be improved.
// https://flatpak.github.io/xdg-desktop-portal/#:~:text=To%20avoid%20a%20race%20condition
// To avoid a race condition
// between the caller subscribing to the signal after receiving the reply for the method call and the signal getting emitted,
// a convention for Request object paths has been established that allows
// the caller to subscribe to the signal before making the method call.
let path = portal.create_session(args)?;
handle_response(
&conn,
@ -419,6 +429,22 @@ fn request_screen_cast(
move |r: OrgFreedesktopPortalRequestResponse, c, _| {
let portal = get_portal(c);
let mut args: PropMap = HashMap::new();
if let Ok(version) = portal.version() {
if version >= 4 {
let restore_token = config::LocalConfig::get_option(RESTORE_TOKEN_CONF_KEY);
if !restore_token.is_empty() {
args.insert(
RESTORE_TOKEN.to_string(),
Variant(Box::new(restore_token)),
);
}
// persist_mode may be configured by the user.
args.insert(
"persist_mode".to_string(),
Variant(Box::new(2u32)),
);
}
}
args.insert(
"handle_token".to_string(),
Variant(Box::new("u2".to_string())),
@ -476,12 +502,24 @@ fn request_screen_cast(
c,
path,
move |r: OrgFreedesktopPortalRequestResponse, c, _| {
let portal = get_portal(c);
if let Ok(version) = portal.version() {
if version >= 4 {
if let Some(restore_token) = r.results.get(RESTORE_TOKEN) {
if let Some(restore_token) = restore_token.as_str() {
config::LocalConfig::set_option(
RESTORE_TOKEN_CONF_KEY.to_owned(),
restore_token.to_owned(),
);
}
}
}
}
streams
.clone()
.lock()
.unwrap()
.append(&mut streams_from_response(r));
let portal = get_portal(c);
fd.clone().lock().unwrap().replace(
portal.open_pipe_wire_remote(session.clone(), HashMap::new())?,
);

View File

@ -599,18 +599,13 @@ fn run(sp: GenericService) -> ResultType<()> {
}
try_gdi += 1;
}
#[cfg(target_os = "linux")]
{
would_block_count += 1;
if !scrap::is_x11() {
if would_block_count >= 1000 {
// For now, the user should choose and agree screen sharing agiain.
// to-do: Remember choice, attendless...
// super::wayland::release_resouce();
// bail!("Wayland capturer none 100 times, try restart captuere");
log::error!("Wayland capturer none 1000 times, try restart captuere");
would_block_count = 0;
if would_block_count >= 100 {
super::wayland::release_resouce();
bail!("Wayland capturer none 100 times, try restart captuere");
}
}
}

View File

@ -241,6 +241,7 @@ pub(super) fn get_display_num() -> ResultType<usize> {
}
}
#[allow(dead_code)]
pub(super) fn release_resouce() {
if scrap::is_x11() {
return;