client: screen relay switched to ximagesink
This commit is contained in:
parent
39e4458967
commit
3aef06001b
@ -23,6 +23,16 @@ fn ensure_runtime_dir() {
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<()> {
|
||||
// Prefer X11/Xwayland on KDE Wayland so wmctrl-based placement works
|
||||
if env::var_os("WAYLAND_DISPLAY").is_some() {
|
||||
if let Some(desktop) = env::var_os("XDG_CURRENT_DESKTOP") {
|
||||
if desktop.to_string_lossy().to_ascii_lowercase().contains("kde") {
|
||||
env::set_var("GDK_BACKEND", "x11");
|
||||
env::set_var("WINIT_UNIX_BACKEND", "x11");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ensure_runtime_dir();
|
||||
|
||||
/*------------- common filter & stderr layer ------------------------*/
|
||||
|
||||
@ -12,19 +12,6 @@ use tracing::{error, info, warn, debug};
|
||||
|
||||
use crate::output::{display, layout};
|
||||
|
||||
/* ---------- pipeline ----------------------------------------------------
|
||||
* ┌────────────┐ H.264/AU ┌─────────┐ Decoded ┌─────────────┐
|
||||
* │ AppSrc │────────────► decodebin ├──────────► glimagesink │
|
||||
* └────────────┘ (autoplug) (overlay) |
|
||||
* ----------------------------------------------------------------------*/
|
||||
const PIPELINE_DESC: &str = concat!(
|
||||
"appsrc name=src is-live=true format=time do-timestamp=true block=false ! ",
|
||||
"queue leaky=downstream ! ",
|
||||
"capsfilter caps=video/x-h264,stream-format=byte-stream,alignment=au ! ",
|
||||
"h264parse disable-passthrough=true ! decodebin ! videoconvert ! ",
|
||||
"glimagesink name=sink sync=false"
|
||||
);
|
||||
|
||||
pub struct MonitorWindow {
|
||||
_pipeline: gst::Pipeline,
|
||||
src: gst_app::AppSrc,
|
||||
@ -35,7 +22,23 @@ impl MonitorWindow {
|
||||
gst::init().context("initialising GStreamer")?;
|
||||
|
||||
// --- Build pipeline ---------------------------------------------------
|
||||
let pipeline: gst::Pipeline = gst::parse::launch(PIPELINE_DESC)?
|
||||
let sink = if std::env::var("GDK_BACKEND")
|
||||
.map(|v| v.contains("x11"))
|
||||
.unwrap_or_else(|_| std::env::var_os("DISPLAY").is_some())
|
||||
{
|
||||
"ximagesink name=sink sync=false"
|
||||
} else {
|
||||
"glimagesink name=sink sync=false"
|
||||
};
|
||||
|
||||
let desc = format!(
|
||||
"appsrc name=src is-live=true format=time do-timestamp=true block=false ! \
|
||||
queue leaky=downstream ! \
|
||||
capsfilter caps=video/x-h264,stream-format=byte-stream,alignment=au ! \
|
||||
h264parse disable-passthrough=true ! decodebin ! videoconvert ! {sink}"
|
||||
);
|
||||
|
||||
let pipeline: gst::Pipeline = gst::parse::launch(&desc)?
|
||||
.downcast::<gst::Pipeline>()
|
||||
.expect("not a pipeline");
|
||||
|
||||
@ -59,6 +62,9 @@ impl MonitorWindow {
|
||||
|
||||
/* -------- move/resize overlay ---------------------------------- */
|
||||
if let Some(sink_elem) = pipeline.by_name("sink") {
|
||||
if sink_elem.find_property("window-title").is_some() {
|
||||
let _ = sink_elem.set_property("window-title", &format!("Lesavka-eye-{id}"));
|
||||
}
|
||||
if let Ok(overlay) = sink_elem.dynamic_cast::<VideoOverlay>() {
|
||||
if let Some(r) = rects.get(id as usize) {
|
||||
// 1. Tell glimagesink how to crop the texture in its own window
|
||||
@ -81,11 +87,6 @@ impl MonitorWindow {
|
||||
run: Arc<dyn Fn(&str) -> std::io::Result<ExitStatus> + Send + Sync>,
|
||||
}
|
||||
|
||||
let is_kde = std::env::var("XDG_CURRENT_DESKTOP")
|
||||
.unwrap_or_default()
|
||||
.to_ascii_lowercase()
|
||||
.contains("kde");
|
||||
|
||||
let placer = if Command::new("swaymsg").arg("-t").arg("get_tree")
|
||||
.output().is_ok()
|
||||
{
|
||||
@ -102,30 +103,6 @@ impl MonitorWindow {
|
||||
.status()
|
||||
}),
|
||||
}
|
||||
} else if is_kde {
|
||||
// KWin DBus script: move/resize by title
|
||||
Placer {
|
||||
name: "kwin",
|
||||
run: Arc::new(|script| {
|
||||
let dbus = if Command::new("qdbus6")
|
||||
.arg("--version")
|
||||
.status()
|
||||
.is_ok()
|
||||
{
|
||||
"qdbus6"
|
||||
} else {
|
||||
"qdbus"
|
||||
};
|
||||
Command::new(dbus)
|
||||
.args([
|
||||
"org.kde.KWin",
|
||||
"/KWin",
|
||||
"org.kde.KWin.evaluateScript",
|
||||
script,
|
||||
])
|
||||
.status()
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
Placer {
|
||||
name: "noop",
|
||||
@ -150,19 +127,6 @@ impl MonitorWindow {
|
||||
x = r.x,
|
||||
y = r.y,
|
||||
),
|
||||
// KWin JS via DBus
|
||||
"kwin" => format!(
|
||||
"var clients = workspace.clientList(); \
|
||||
clients.forEach(function(c) {{ \
|
||||
if (c.caption === \"Lesavka-eye-{id}\") {{ \
|
||||
c.geometry = {{x:{x}, y:{y}, width:{w}, height:{h}}}; \
|
||||
}} \
|
||||
}});",
|
||||
x = r.x,
|
||||
y = r.y,
|
||||
w = r.w,
|
||||
h = r.h,
|
||||
),
|
||||
_ => String::new(),
|
||||
};
|
||||
|
||||
@ -187,7 +151,7 @@ impl MonitorWindow {
|
||||
});
|
||||
}
|
||||
}
|
||||
// 3. X11 placement (kwin/i3/etc.) via wmctrl
|
||||
// 3. X11 / Xwayland placement via wmctrl
|
||||
else if std::env::var_os("DISPLAY").is_some() {
|
||||
let title = format!("Lesavka-eye-{id}");
|
||||
let w = r.w;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user