131 lines
3.7 KiB
Rust
131 lines
3.7 KiB
Rust
use std::process::Stdio;
|
|
|
|
use smithay::{
|
|
delegate_dispatch2,
|
|
utils::{Logical, Rectangle},
|
|
wayland::xwayland_shell::{XWaylandShellHandler, XWaylandShellState},
|
|
xwayland::{
|
|
xwm::{Reorder, ResizeEdge, XwmId},
|
|
X11Surface, X11Wm, XWayland, XWaylandEvent, XwmHandler,
|
|
},
|
|
};
|
|
use wayland_server::Display;
|
|
|
|
use crate::state::{AppWrapper, State};
|
|
|
|
pub struct XWaylandState {
|
|
pub xwm: Option<X11Wm>,
|
|
pub xwayland_shell_state: XWaylandShellState,
|
|
}
|
|
impl XwmHandler for State {
|
|
fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm {
|
|
self.xwayland_state.xwm.as_mut().unwrap()
|
|
}
|
|
|
|
fn new_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
|
|
|
|
fn new_override_redirect_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
|
|
|
|
fn map_window_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
|
// grant it — the window will be mapped once you set this
|
|
window.set_mapped(true).unwrap();
|
|
|
|
let mut space = self.space.lock();
|
|
|
|
space.map_element(AppWrapper::new_x11(window), (0, 0), true);
|
|
|
|
// insert it into your Space/window management here
|
|
}
|
|
|
|
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
|
|
|
|
fn unmapped_window(&mut self, _xwm: XwmId, _window: X11Surface) {
|
|
// let mut space = self.space.lock();
|
|
}
|
|
|
|
fn destroyed_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
|
|
|
|
fn configure_request(
|
|
&mut self,
|
|
_xwm: XwmId,
|
|
window: X11Surface,
|
|
x: Option<i32>,
|
|
y: Option<i32>,
|
|
w: Option<u32>,
|
|
h: Option<u32>,
|
|
_reorder: Option<Reorder>,
|
|
) {
|
|
// Usually you just approve the requested geometry
|
|
let _ = window.configure(None);
|
|
}
|
|
|
|
fn configure_notify(
|
|
&mut self,
|
|
_xwm: XwmId,
|
|
_window: X11Surface,
|
|
_geo: Rectangle<i32, Logical>,
|
|
_above: Option<u32>,
|
|
) {
|
|
}
|
|
|
|
fn resize_request(
|
|
&mut self,
|
|
_xwm: XwmId,
|
|
_window: X11Surface,
|
|
_button: u32,
|
|
_edge: ResizeEdge,
|
|
) {
|
|
}
|
|
fn move_request(&mut self, _xwm: XwmId, _window: X11Surface, _button: u32) {}
|
|
}
|
|
|
|
impl XWaylandShellHandler for State {
|
|
fn xwayland_shell_state(
|
|
&mut self,
|
|
) -> &mut smithay::wayland::xwayland_shell::XWaylandShellState {
|
|
&mut self.xwayland_state.xwayland_shell_state
|
|
}
|
|
}
|
|
|
|
impl State {
|
|
pub fn setup_xwayland(
|
|
&mut self,
|
|
display: &Display<State>,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
let dh = display.handle();
|
|
let (xwayland, client) = XWayland::spawn(
|
|
&dh,
|
|
None,
|
|
std::iter::empty::<(String, String)>(),
|
|
std::iter::empty::<String>(),
|
|
true,
|
|
Stdio::null(),
|
|
Stdio::null(),
|
|
|_| {},
|
|
)?;
|
|
|
|
let event_loop_handle = self.event_loop_handle.clone();
|
|
event_loop_handle.insert_source(xwayland, move |event, _, state| {
|
|
match event {
|
|
XWaylandEvent::Ready {
|
|
x11_socket,
|
|
display_number,
|
|
} => {
|
|
let event_loop = state.event_loop_handle.clone();
|
|
let wm = X11Wm::start_wm(event_loop, &dh, x11_socket, client.clone())
|
|
.expect("failed to start X11 wm");
|
|
|
|
state.xwayland_state.xwm = Some(wm);
|
|
|
|
println!("XWayland started on display :{display_number}");
|
|
unsafe { std::env::set_var("DISPLAY", format!(":{display_number}")) };
|
|
}
|
|
XWaylandEvent::Error => {
|
|
// warn!("XWayland crashed on startup");
|
|
}
|
|
}
|
|
})?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|