server: give uninitialized and initialized xstate with unique types
This commit is contained in:
parent
56d5cce2d0
commit
4280639df8
4 changed files with 180 additions and 137 deletions
112
src/lib.rs
112
src/lib.rs
|
|
@ -1,7 +1,7 @@
|
|||
mod server;
|
||||
pub mod xstate;
|
||||
|
||||
use crate::server::{PendingSurfaceState, ServerState};
|
||||
use crate::server::{EarlyConnection, PendingSurfaceState, ServerState};
|
||||
use crate::xstate::{RealConnection, XState};
|
||||
use log::{error, info};
|
||||
use rustix::event::{poll, PollFd, PollFlags};
|
||||
|
|
@ -16,7 +16,6 @@ use xcb::x;
|
|||
pub trait XConnection: Sized + 'static {
|
||||
type X11Selection: X11Selection;
|
||||
|
||||
fn root_window(&self) -> x::Window;
|
||||
fn set_window_dims(&mut self, window: x::Window, dims: PendingSurfaceState);
|
||||
fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool);
|
||||
fn focus_window(&mut self, window: x::Window, output_name: Option<String>);
|
||||
|
|
@ -30,6 +29,7 @@ pub trait X11Selection {
|
|||
fn write_to(&self, mime: &str, pipe: WritePipe);
|
||||
}
|
||||
|
||||
type EarlyServerState = ServerState<EarlyConnection<<RealConnection as XConnection>::X11Selection>>;
|
||||
type RealServerState = ServerState<RealConnection>;
|
||||
|
||||
pub trait RunData {
|
||||
|
|
@ -58,8 +58,6 @@ pub fn main(mut data: impl RunData) -> Option<()> {
|
|||
let dh = display.handle();
|
||||
data.created_server();
|
||||
|
||||
let mut server_state = RealServerState::new(dh, data.server());
|
||||
|
||||
let (xsock_wl, xsock_xwl) = UnixStream::pair().unwrap();
|
||||
// Prevent creation of new Xwayland command from closing fd
|
||||
rustix::io::fcntl_setfd(&xsock_xwl, rustix::io::FdFlags::empty()).unwrap();
|
||||
|
|
@ -136,11 +134,10 @@ pub fn main(mut data: impl RunData) -> Option<()> {
|
|||
}
|
||||
};
|
||||
|
||||
let mut server_state = EarlyServerState::new(dh, data.server());
|
||||
server_state.connect(connection);
|
||||
server_state.run();
|
||||
|
||||
let mut xstate: Option<XState> = None;
|
||||
|
||||
// Remove the lifetimes on our fds to avoid borrowing issues, since we know they will exist for
|
||||
// the rest of our program anyway
|
||||
let server_fd = unsafe { BorrowedFd::borrow_raw(server_state.clientside_fd().as_raw_fd()) };
|
||||
|
|
@ -154,18 +151,74 @@ pub fn main(mut data: impl RunData) -> Option<()> {
|
|||
PollFd::from_borrowed_fd(server_fd, PollFlags::IN),
|
||||
PollFd::new(&xsock_wl, PollFlags::IN),
|
||||
PollFd::from_borrowed_fd(display_fd, PollFlags::IN),
|
||||
PollFd::new(&ready_rx, PollFlags::IN),
|
||||
PollFd::new(&quit_rx, PollFlags::IN),
|
||||
PollFd::new(&ready_rx, PollFlags::IN),
|
||||
];
|
||||
|
||||
let mut ready = false;
|
||||
loop {
|
||||
match poll(&mut fds, -1) {
|
||||
Ok(_) => {
|
||||
if !fds[3].revents().is_empty() {
|
||||
ready = true;
|
||||
let status = xwayland_exit_code(&mut quit_rx);
|
||||
if *status != ExitStatus::default() {
|
||||
error!("Xwayland exited early with {status}");
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if !fds[4].revents().is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(other) => panic!("Poll failed: {other:?}"),
|
||||
}
|
||||
|
||||
display.dispatch_clients(server_state.inner_mut()).unwrap();
|
||||
server_state.run();
|
||||
display.flush_clients().unwrap();
|
||||
}
|
||||
|
||||
let mut xstate: Option<XState> = None;
|
||||
let xstate = xstate.insert(XState::new(xsock_wl.as_fd()));
|
||||
let mut reader = BufReader::new(&ready_rx);
|
||||
{
|
||||
let mut display = String::new();
|
||||
reader.read_line(&mut display).unwrap();
|
||||
display.pop();
|
||||
display.insert(0, ':');
|
||||
info!("Connected to Xwayland on {display}");
|
||||
data.xwayland_ready(display, xwl_pid);
|
||||
}
|
||||
let mut server_state = xstate.server_state_setup(server_state);
|
||||
|
||||
#[cfg(feature = "systemd")]
|
||||
{
|
||||
match sd_notify::notify(true, &[sd_notify::NotifyState::Ready]) {
|
||||
Ok(()) => info!("Successfully notified systemd of ready state."),
|
||||
Err(e) => log::warn!("Systemd notify failed: {e:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "systemd"))]
|
||||
info!("Systemd support disabled.");
|
||||
|
||||
loop {
|
||||
xstate.handle_events(&mut server_state);
|
||||
|
||||
display.dispatch_clients(server_state.inner_mut()).unwrap();
|
||||
server_state.run();
|
||||
display.flush_clients().unwrap();
|
||||
|
||||
if let Some(sel) = server_state.new_selection() {
|
||||
xstate.set_clipboard(sel);
|
||||
}
|
||||
|
||||
if let Some(scale) = server_state.new_global_scale() {
|
||||
xstate.update_global_scale(scale);
|
||||
}
|
||||
|
||||
match poll(&mut fds, -1) {
|
||||
Ok(_) => {
|
||||
if !fds[3].revents().is_empty() {
|
||||
let status = xwayland_exit_code(&mut quit_rx);
|
||||
if *status != ExitStatus::default() {
|
||||
error!("Xwayland exited early with {status}");
|
||||
|
|
@ -175,46 +228,5 @@ pub fn main(mut data: impl RunData) -> Option<()> {
|
|||
}
|
||||
Err(other) => panic!("Poll failed: {other:?}"),
|
||||
}
|
||||
|
||||
if xstate.is_none() && ready {
|
||||
let xstate = xstate.insert(XState::new(xsock_wl.as_fd()));
|
||||
let mut reader = BufReader::new(&ready_rx);
|
||||
let mut display = String::new();
|
||||
reader.read_line(&mut display).unwrap();
|
||||
display.pop();
|
||||
display.insert(0, ':');
|
||||
info!("Connected to Xwayland on {display}");
|
||||
data.xwayland_ready(display, xwl_pid);
|
||||
xstate.server_state_setup(&mut server_state);
|
||||
|
||||
#[cfg(feature = "systemd")]
|
||||
{
|
||||
match sd_notify::notify(true, &[sd_notify::NotifyState::Ready]) {
|
||||
Ok(()) => info!("Successfully notified systemd of ready state."),
|
||||
Err(e) => log::warn!("Systemd notify failed: {e:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "systemd"))]
|
||||
info!("Systemd support disabled.");
|
||||
}
|
||||
|
||||
if let Some(xstate) = &mut xstate {
|
||||
xstate.handle_events(&mut server_state);
|
||||
}
|
||||
|
||||
display.dispatch_clients(server_state.inner_mut()).unwrap();
|
||||
server_state.run();
|
||||
display.flush_clients().unwrap();
|
||||
|
||||
if let Some(xstate) = &mut xstate {
|
||||
if let Some(sel) = server_state.new_selection() {
|
||||
xstate.set_clipboard(sel);
|
||||
}
|
||||
|
||||
if let Some(scale) = server_state.new_global_scale() {
|
||||
xstate.update_global_scale(scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue