Accept -listenfd and pass on to Xwayland
This commit is contained in:
parent
ac391db415
commit
9e48795087
3 changed files with 64 additions and 11 deletions
14
src/lib.rs
14
src/lib.rs
|
|
@ -8,7 +8,7 @@ use log::{error, info};
|
|||
use rustix::event::{poll, PollFd, PollFlags};
|
||||
use smithay_client_toolkit::data_device_manager::WritePipe;
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd};
|
||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd};
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::process::{Command, ExitStatus, Stdio};
|
||||
use wayland_server::{Display, ListeningSocket};
|
||||
|
|
@ -35,6 +35,7 @@ type RealServerState = ServerState<RealConnection>;
|
|||
|
||||
pub trait RunData {
|
||||
fn display(&self) -> Option<&str>;
|
||||
fn listenfds(&mut self) -> Vec<OwnedFd>;
|
||||
fn server(&self) -> Option<UnixStream> {
|
||||
None
|
||||
}
|
||||
|
|
@ -46,7 +47,7 @@ pub trait RunData {
|
|||
fn xwayland_ready(&self, _display: String, _pid: u32) {}
|
||||
}
|
||||
|
||||
pub fn main(data: impl RunData) -> Option<()> {
|
||||
pub fn main(mut data: impl RunData) -> Option<()> {
|
||||
let mut version = env!("VERGEN_GIT_DESCRIBE");
|
||||
if version == "VERGEN_IDEMPOTENT_OUTPUT" {
|
||||
version = env!("CARGO_PKG_VERSION");
|
||||
|
|
@ -70,6 +71,12 @@ pub fn main(data: impl RunData) -> Option<()> {
|
|||
if let Some(display) = data.display() {
|
||||
xwayland.arg(display);
|
||||
}
|
||||
|
||||
let fds = data.listenfds();
|
||||
for fd in &fds {
|
||||
xwayland.args(["-listenfd", &fd.as_raw_fd().to_string()]);
|
||||
}
|
||||
|
||||
let mut xwayland = xwayland
|
||||
.args([
|
||||
"-rootless",
|
||||
|
|
@ -84,6 +91,9 @@ pub fn main(data: impl RunData) -> Option<()> {
|
|||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
// Now that Xwayland spawned and got the listenfds, we can close them here.
|
||||
drop(fds);
|
||||
|
||||
let xwl_pid = xwayland.id();
|
||||
|
||||
let (mut finish_tx, mut finish_rx) = UnixStream::pair().unwrap();
|
||||
|
|
|
|||
55
src/main.rs
55
src/main.rs
|
|
@ -1,24 +1,63 @@
|
|||
use std::os::fd::{FromRawFd, OwnedFd, RawFd};
|
||||
|
||||
fn main() {
|
||||
pretty_env_logger::formatted_timed_builder()
|
||||
.filter_level(log::LevelFilter::Info)
|
||||
.parse_default_env()
|
||||
.init();
|
||||
xwayland_satellite::main(RealData(get_display()));
|
||||
xwayland_satellite::main(parse_args());
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct RealData(Option<String>);
|
||||
struct RealData {
|
||||
display: Option<String>,
|
||||
listenfds: Vec<OwnedFd>,
|
||||
}
|
||||
impl xwayland_satellite::RunData for RealData {
|
||||
fn display(&self) -> Option<&str> {
|
||||
self.0.as_deref()
|
||||
self.display.as_deref()
|
||||
}
|
||||
|
||||
fn listenfds(&mut self) -> Vec<OwnedFd> {
|
||||
std::mem::take(&mut self.listenfds)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_display() -> Option<String> {
|
||||
fn parse_args() -> RealData {
|
||||
let mut data = RealData {
|
||||
display: None,
|
||||
listenfds: Vec::new(),
|
||||
};
|
||||
|
||||
let mut args: Vec<_> = std::env::args().collect();
|
||||
if args.len() > 2 {
|
||||
panic!("Unexpected arguments: {:?}", &args[2..]);
|
||||
if args.len() < 2 {
|
||||
return data;
|
||||
}
|
||||
|
||||
(args.len() == 2).then(|| args.swap_remove(1))
|
||||
// Argument at index 1 is our display name. The rest can be -listenfd.
|
||||
let mut i = 2;
|
||||
while i < args.len() {
|
||||
let arg = &args[i];
|
||||
if arg == "-listenfd" {
|
||||
let next = i + 1;
|
||||
if next == args.len() {
|
||||
// Matches the Xwayland error message.
|
||||
panic!("Required argument to -listenfd not specified");
|
||||
}
|
||||
|
||||
let fd: RawFd = args[next].parse().expect("Error parsing -listenfd number");
|
||||
// SAFETY:
|
||||
// - whoever runs the binary must ensure this fd is open and valid.
|
||||
// - parse_args() must only be called once to avoid double closing.
|
||||
let fd = unsafe { OwnedFd::from_raw_fd(fd) };
|
||||
|
||||
data.listenfds.push(fd);
|
||||
i += 2;
|
||||
} else {
|
||||
panic!("Unrecognized argument: {arg}");
|
||||
}
|
||||
}
|
||||
|
||||
data.display = Some(args.swap_remove(1));
|
||||
|
||||
data
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue