mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
xwayland: Make abstract socket optional and Linux-only
Hopefully fixes build on FreeBSD.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use std::os::fd::OwnedFd;
|
||||
use std::os::linux::net::SocketAddrExt;
|
||||
use std::os::unix::net::{SocketAddr, UnixListener};
|
||||
|
||||
use anyhow::{anyhow, ensure, Context as _};
|
||||
@@ -17,7 +16,8 @@ const X11_TMP_UNIX_DIR: &str = "/tmp/.X11-unix";
|
||||
|
||||
struct X11Connection {
|
||||
display_name: String,
|
||||
abstract_fd: OwnedFd,
|
||||
// Optional because there are no abstract sockets on FreeBSD.
|
||||
abstract_fd: Option<OwnedFd>,
|
||||
unix_fd: OwnedFd,
|
||||
_unix_guard: Unlink,
|
||||
_lock_guard: Unlink,
|
||||
@@ -82,7 +82,10 @@ fn bind_to_socket(addr: &SocketAddr) -> anyhow::Result<UnixListener> {
|
||||
Ok(listener)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn bind_to_abstract_socket(display: u32) -> anyhow::Result<UnixListener> {
|
||||
use std::os::linux::net::SocketAddrExt;
|
||||
|
||||
let name = format!("/tmp/.X11-unix/X{display}");
|
||||
let addr = SocketAddr::from_abstract_name(name).unwrap();
|
||||
bind_to_socket(&addr)
|
||||
@@ -97,8 +100,14 @@ fn bind_to_unix_socket(display: u32) -> anyhow::Result<(UnixListener, Unlink)> {
|
||||
bind_to_socket(&addr).map(|listener| (listener, guard))
|
||||
}
|
||||
|
||||
fn open_display_sockets(display: u32) -> anyhow::Result<(UnixListener, UnixListener, Unlink)> {
|
||||
let a = bind_to_abstract_socket(display).context("error binding to abstract socket")?;
|
||||
fn open_display_sockets(
|
||||
display: u32,
|
||||
) -> anyhow::Result<(Option<UnixListener>, UnixListener, Unlink)> {
|
||||
#[cfg(target_os = "linux")]
|
||||
let a = Some(bind_to_abstract_socket(display).context("error binding to abstract socket")?);
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let a = None;
|
||||
|
||||
let (u, g) = bind_to_unix_socket(display).context("error binding to unix socket")?;
|
||||
Ok((a, u, g))
|
||||
}
|
||||
@@ -138,7 +147,7 @@ fn setup_connection() -> anyhow::Result<X11Connection> {
|
||||
};
|
||||
|
||||
let display_name = format!(":{display}");
|
||||
let abstract_fd = OwnedFd::from(a);
|
||||
let abstract_fd = a.map(OwnedFd::from);
|
||||
let unix_fd = OwnedFd::from(u);
|
||||
|
||||
Ok(X11Connection {
|
||||
|
||||
@@ -163,27 +163,29 @@ fn setup_watch(state: &mut State) {
|
||||
event_loop.remove(token);
|
||||
}
|
||||
|
||||
let fd = satellite.x11.abstract_fd.try_clone().unwrap();
|
||||
let fd = clear_out_pending_connections(fd);
|
||||
let source = Generic::new(fd, Interest::READ, Mode::Level);
|
||||
let token = event_loop
|
||||
.insert_source(source, move |_, _, state| {
|
||||
if let Some(satellite) = &mut state.niri.satellite {
|
||||
// Remove the other source.
|
||||
if let Some(token) = satellite.unix_token.take() {
|
||||
state.niri.event_loop.remove(token);
|
||||
}
|
||||
// Clear this source.
|
||||
satellite.abstract_token = None;
|
||||
if let Some(fd) = &satellite.x11.abstract_fd {
|
||||
let fd = fd.try_clone().unwrap();
|
||||
let fd = clear_out_pending_connections(fd);
|
||||
let source = Generic::new(fd, Interest::READ, Mode::Level);
|
||||
let token = event_loop
|
||||
.insert_source(source, move |_, _, state| {
|
||||
if let Some(satellite) = &mut state.niri.satellite {
|
||||
// Remove the other source.
|
||||
if let Some(token) = satellite.unix_token.take() {
|
||||
state.niri.event_loop.remove(token);
|
||||
}
|
||||
// Clear this source.
|
||||
satellite.abstract_token = None;
|
||||
|
||||
debug!("connection to X11 abstract socket; spawning xwayland-satellite");
|
||||
let path = state.niri.config.borrow().xwayland_satellite.path.clone();
|
||||
spawn(path, satellite);
|
||||
}
|
||||
Ok(PostAction::Remove)
|
||||
})
|
||||
.unwrap();
|
||||
satellite.abstract_token = Some(token);
|
||||
debug!("connection to X11 abstract socket; spawning xwayland-satellite");
|
||||
let path = state.niri.config.borrow().xwayland_satellite.path.clone();
|
||||
spawn(path, satellite);
|
||||
}
|
||||
Ok(PostAction::Remove)
|
||||
})
|
||||
.unwrap();
|
||||
satellite.abstract_token = Some(token);
|
||||
}
|
||||
|
||||
let fd = satellite.x11.unix_fd.try_clone().unwrap();
|
||||
let fd = clear_out_pending_connections(fd);
|
||||
@@ -211,7 +213,11 @@ fn setup_watch(state: &mut State) {
|
||||
fn spawn(path: String, xwl: &Satellite) {
|
||||
let _span = tracy_client::span!("satellite::spawn");
|
||||
|
||||
let abstract_fd = xwl.x11.abstract_fd.try_clone().unwrap();
|
||||
let abstract_fd = xwl
|
||||
.x11
|
||||
.abstract_fd
|
||||
.as_ref()
|
||||
.map(|fd| fd.try_clone().unwrap());
|
||||
let unix_fd = xwl.x11.unix_fd.try_clone().unwrap();
|
||||
let to_main = xwl.to_main.clone();
|
||||
|
||||
@@ -257,15 +263,20 @@ fn spawn(path: String, xwl: &Satellite) {
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_and_wait(path: &Path, mut process: Command, abstract_fd: OwnedFd, unix_fd: OwnedFd) {
|
||||
let abstract_raw = abstract_fd.as_raw_fd();
|
||||
fn spawn_and_wait(
|
||||
path: &Path,
|
||||
mut process: Command,
|
||||
abstract_fd: Option<OwnedFd>,
|
||||
unix_fd: OwnedFd,
|
||||
) {
|
||||
let abstract_raw = abstract_fd.as_ref().map(|fd| fd.as_raw_fd());
|
||||
let unix_raw = unix_fd.as_raw_fd();
|
||||
|
||||
process
|
||||
.arg("-listenfd")
|
||||
.arg(abstract_raw.to_string())
|
||||
.arg("-listenfd")
|
||||
.arg(unix_raw.to_string());
|
||||
process.arg("-listenfd").arg(unix_raw.to_string());
|
||||
|
||||
if let Some(abstract_raw) = abstract_raw {
|
||||
process.arg("-listenfd").arg(abstract_raw.to_string());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
process.pre_exec(move || {
|
||||
@@ -273,12 +284,14 @@ fn spawn_and_wait(path: &Path, mut process: Command, abstract_fd: OwnedFd, unix_
|
||||
// that we want to pass it.
|
||||
|
||||
// We're not dropping these until after spawn().
|
||||
let abstract_fd = BorrowedFd::borrow_raw(abstract_raw);
|
||||
let unix_fd = BorrowedFd::borrow_raw(unix_raw);
|
||||
|
||||
fcntl_setfd(abstract_fd, FdFlags::empty())?;
|
||||
fcntl_setfd(unix_fd, FdFlags::empty())?;
|
||||
|
||||
if let Some(abstract_raw) = abstract_raw {
|
||||
let abstract_fd = BorrowedFd::borrow_raw(abstract_raw);
|
||||
fcntl_setfd(abstract_fd, FdFlags::empty())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user