1
0
Fork 0
forked from wry/wry

state: split xwayland handling

This commit is contained in:
kossLAN 2026-05-29 19:44:20 -04:00
parent cd1f049a3e
commit c2d86dcd7f
No known key found for this signature in database
2 changed files with 104 additions and 83 deletions

View file

@ -2,10 +2,12 @@ mod animations;
mod connectors; mod connectors;
mod idle; mod idle;
mod rendering; mod rendering;
mod xwayland;
pub(crate) use animations::LayoutAnimationCandidate; pub(crate) use animations::LayoutAnimationCandidate;
pub use connectors::{ConnectorData, DrmDevData, OutputData}; pub use connectors::{ConnectorData, DrmDevData, OutputData};
pub use idle::IdleState; pub use idle::IdleState;
pub use xwayland::XWaylandState;
use { use {
crate::{ crate::{
@ -51,7 +53,6 @@ use {
}, },
data_transfer::{ data_transfer::{
DataOfferIds, DataSourceIds, data_control::DataControlDeviceIds, DataOfferIds, DataSourceIds, data_control::DataControlDeviceIds,
x_data_device::XTransferDeviceIds,
}, },
jay_render_ctx::JayRenderCtx, jay_render_ctx::JayRenderCtx,
jay_seat_events::JaySeatEvents, jay_seat_events::JaySeatEvents,
@ -66,7 +67,6 @@ use {
NoneSurfaceExt, NoneSurfaceExt,
tray::TrayItemIds, tray::TrayItemIds,
wl_subsurface::SubsurfaceIds, wl_subsurface::SubsurfaceIds,
x_surface::xwindow::{Xwindow, XwindowId},
xdg_surface::XdgSurfaceConfigureEvent, xdg_surface::XdgSurfaceConfigureEvent,
zwp_idle_inhibitor_v1::IdleInhibitorIds, zwp_idle_inhibitor_v1::IdleInhibitorIds,
zwp_input_popup_surface_v2::ZwpInputPopupSurfaceV2, zwp_input_popup_surface_v2::ZwpInputPopupSurfaceV2,
@ -122,7 +122,6 @@ use {
JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId, ZwlrForeignToplevelManagerV1Id, JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId, ZwlrForeignToplevelManagerV1Id,
ZwpLinuxDmabufFeedbackV1Id, ZwpLinuxDmabufFeedbackV1Id,
}, },
xwayland::{self, XWaylandEvent},
}, },
ahash::AHashMap, ahash::AHashMap,
bstr::ByteSlice, bstr::ByteSlice,
@ -135,7 +134,7 @@ use {
sync::Arc, sync::Arc,
time::SystemTime, time::SystemTime,
}, },
uapi::{OwnedFd, c}, uapi::c,
}; };
pub struct State { pub struct State {
@ -308,20 +307,6 @@ pub struct ScreenlockState {
pub lock: CloneCell<Option<Rc<ExtSessionLockV1>>>, pub lock: CloneCell<Option<Rc<ExtSessionLockV1>>>,
} }
pub struct XWaylandState {
pub enabled: Cell<bool>,
pub running: Cell<bool>,
pub pidfd: CloneCell<Option<Rc<OwnedFd>>>,
pub handler: RefCell<Option<SpawnedFuture<()>>>,
pub queue: Rc<AsyncQueue<XWaylandEvent>>,
pub ipc_device_ids: XTransferDeviceIds,
pub use_wire_scale: Cell<bool>,
pub wire_scale: Cell<Option<i32>>,
pub windows: CopyHashMap<XwindowId, Rc<Xwindow>>,
pub client: CloneCell<Option<Rc<Client>>>,
pub display: CloneCell<Option<Rc<String>>>,
}
pub struct InputDeviceData { pub struct InputDeviceData {
pub _handler: SpawnedFuture<()>, pub _handler: SpawnedFuture<()>,
pub id: InputDeviceId, pub id: InputDeviceId,
@ -772,41 +757,6 @@ impl State {
} }
} }
pub fn start_xwayland(self: &Rc<Self>) {
if !self.xwayland.enabled.get() {
return;
}
let mut handler = self.xwayland.handler.borrow_mut();
if handler.is_none() {
*handler = Some(self.eng.spawn("xwayland", xwayland::manage(self.clone())));
}
}
pub fn stop_xwayland(&self) {
if self.xwayland.running.get() {
return;
}
self.xwayland.handler.take();
}
pub fn set_xwayland_enabled(self: &Rc<Self>, enabled: bool) {
if self.xwayland.enabled.replace(enabled) == enabled {
return;
}
if enabled {
self.start_xwayland();
} else {
self.stop_xwayland();
}
}
pub fn set_xwayland_use_wire_scale(&self, use_wire_scale: bool) {
if self.xwayland.use_wire_scale.replace(use_wire_scale) == use_wire_scale {
return;
}
self.update_xwayland_wire_scale();
}
pub fn next_serial(&self, client: Option<&Client>) -> u64 { pub fn next_serial(&self, client: Option<&Client>) -> u64 {
let serial = self.serial.fetch_add(1); let serial = self.serial.fetch_add(1);
if let Some(client) = client { if let Some(client) = client {
@ -1152,36 +1102,6 @@ impl State {
dx * dx + dy * dy > self.ui_drag_threshold_squared.get() dx * dx + dy * dy > self.ui_drag_threshold_squared.get()
} }
pub fn update_xwayland_wire_scale(&self) {
let scale = self
.scales
.lock()
.iter()
.map(|v| v.0.round_up())
.max()
.unwrap_or(1);
let wire_scale = match self.xwayland.use_wire_scale.get() {
true => Some(scale as i32),
false => None,
};
self.xwayland.wire_scale.set(wire_scale);
for client in self.clients.clients.borrow().values() {
let client = &client.data;
if !client.is_xwayland {
continue;
}
if client.wire_scale.replace(wire_scale) == wire_scale {
continue;
}
for output in client.objects.outputs.lock().values() {
output.send_updates();
}
for surface in client.objects.surfaces.lock().values() {
surface.handle_xwayland_wire_scale_change();
}
}
}
pub fn tray_icon_size(&self) -> i32 { pub fn tray_icon_size(&self) -> i32 {
if !self.show_bar.get() { if !self.show_bar.get() {
return 0; return 0;

101
src/state/xwayland.rs Normal file
View file

@ -0,0 +1,101 @@
use {
crate::{
async_engine::SpawnedFuture,
client::Client,
ifs::{
data_transfer::x_data_device::XTransferDeviceIds,
wl_surface::x_surface::xwindow::{Xwindow, XwindowId},
},
utils::{clonecell::CloneCell, copyhashmap::CopyHashMap, queue::AsyncQueue},
xwayland::{self, XWaylandEvent},
},
std::{
cell::{Cell, RefCell},
rc::Rc,
},
uapi::OwnedFd,
};
use super::State;
pub struct XWaylandState {
pub enabled: Cell<bool>,
pub running: Cell<bool>,
pub pidfd: CloneCell<Option<Rc<OwnedFd>>>,
pub handler: RefCell<Option<SpawnedFuture<()>>>,
pub queue: Rc<AsyncQueue<XWaylandEvent>>,
pub ipc_device_ids: XTransferDeviceIds,
pub use_wire_scale: Cell<bool>,
pub wire_scale: Cell<Option<i32>>,
pub windows: CopyHashMap<XwindowId, Rc<Xwindow>>,
pub client: CloneCell<Option<Rc<Client>>>,
pub display: CloneCell<Option<Rc<String>>>,
}
impl State {
pub fn start_xwayland(self: &Rc<Self>) {
if !self.xwayland.enabled.get() {
return;
}
let mut handler = self.xwayland.handler.borrow_mut();
if handler.is_none() {
*handler = Some(self.eng.spawn("xwayland", xwayland::manage(self.clone())));
}
}
pub fn stop_xwayland(&self) {
if self.xwayland.running.get() {
return;
}
self.xwayland.handler.take();
}
pub fn set_xwayland_enabled(self: &Rc<Self>, enabled: bool) {
if self.xwayland.enabled.replace(enabled) == enabled {
return;
}
if enabled {
self.start_xwayland();
} else {
self.stop_xwayland();
}
}
pub fn set_xwayland_use_wire_scale(&self, use_wire_scale: bool) {
if self.xwayland.use_wire_scale.replace(use_wire_scale) == use_wire_scale {
return;
}
self.update_xwayland_wire_scale();
}
pub fn update_xwayland_wire_scale(&self) {
let scale = self
.scales
.lock()
.iter()
.map(|v| v.0.round_up())
.max()
.unwrap_or(1);
let wire_scale = match self.xwayland.use_wire_scale.get() {
true => Some(scale as i32),
false => None,
};
self.xwayland.wire_scale.set(wire_scale);
for client in self.clients.clients.borrow().values() {
let client = &client.data;
if !client.is_xwayland {
continue;
}
if client.wire_scale.replace(wire_scale) == wire_scale {
continue;
}
for output in client.objects.outputs.lock().values() {
output.send_updates();
}
for surface in client.objects.surfaces.lock().values() {
surface.handle_xwayland_wire_scale_change();
}
}
}
}