Commit c7e08bac3e01
tarball14 files changed+134-94
@@ -104,12 +104,15 @@ impl ImageCopyCaptureHandler for State {
104104
}105105
106106
fn new_session(&mut self, session: Session) {107
- self.captures.sessions.push(session);107
+ self.services.captures.sessions.push(session);108108
}109109
110110
fn frame(&mut self, session: &SessionRef, frame: Frame) {111111
if session.user_data().get::<Delivered>().is_some() {112
- self.captures.waiting.push((session.clone(), frame));112
+ self.services113
+ .captures114
+ .waiting115
+ .push((session.clone(), frame));113116
self.needs_redraw = true;114117
} else {115118
self.capture(session, frame);@@ -117,7 +120,7 @@ impl ImageCopyCaptureHandler for State {
117120
}118121
119122
fn session_destroyed(&mut self, session: SessionRef) {120
- let c = &mut self.captures;123
+ let c = &mut self.services.captures;121124
c.sessions.retain(|s| *s != session);122125
c.waiting.retain(|(s, _)| *s != session);123126
}@@ -126,17 +129,17 @@ impl ImageCopyCaptureHandler for State {
126129
impl State {127130
/// Completes waiting frames whose target showed something new.128131
pub fn complete_captures(&mut self) {129
- if self.captures.damaged.is_empty() {132
+ if self.services.captures.damaged.is_empty() {130133
return;131134
}132
- let damaged = std::mem::take(&mut self.captures.damaged);133
- let (ready, waiting) = std::mem::take(&mut self.captures.waiting)135
+ let damaged = std::mem::take(&mut self.services.captures.damaged);136
+ let (ready, waiting) = std::mem::take(&mut self.services.captures.waiting)134137
.into_iter()135138
.partition::<Vec<_>, _>(|(s, _)| {136139
self.target(&s.source())137140
.is_some_and(|t| damaged.contains(&t))138141
});139
- self.captures.waiting = waiting;142
+ self.services.captures.waiting = waiting;140143
for (session, frame) in ready {141144
self.capture(&session, frame);142145
}@@ -275,7 +278,7 @@ impl State {
275278
));276279
}277280
}278
- match crate::lock::elements(&self.lock, &mut self.renderer, output) {281
+ match crate::lock::elements(&self.services.lock, &mut self.renderer, output) {279282
Some(locked) => elements.extend(locked),280283
None => elements.extend(crate::scene::build(281284
&self.layout,@@ -287,7 +290,10 @@ impl State {
287290
&self.settings.config.decoration,288291
&mut self.borders,289292
Some(output),290
- self.xwayland.as_ref().map_or(&[], |x| &x.unmanaged),293
+ self.services294
+ .xwayland295
+ .as_ref()296
+ .map_or(&[], |x| &x.unmanaged),291297
)),292298
}293299
elements@@ -173,14 +173,14 @@ impl State {
173173
cmd.args(args)174174
.env("WAYLAND_DISPLAY", &self.core.socket_name)175175
.stdin(Stdio::null());176
- if let Some(sock) = &self.ipc.path {176
+ if let Some(sock) = &self.services.ipc.path {177177
cmd.env("MONOLITH_SOCKET", sock);178178
}179179
if self.drm.is_some() {180180
cmd.env("XDG_CURRENT_DESKTOP", "monolith")181181
.env("XDG_SESSION_TYPE", "wayland");182182
}183
- if let Some(x) = &self.xwayland {183
+ if let Some(x) = &self.services.xwayland {184184
cmd.env("DISPLAY", format!(":{}", x.display));185185
}186186
let token = self.launch_token();@@ -189,7 +189,7 @@ impl State {
189189
let mut child = cmd.spawn().map_err(|e| format!("{program}: {e}"))?;190190
tracing::info!(pid = child.id(), ?argv, "spawned");191191
let (output, tag) = self.launch_context();192
- self.launches.record(child.id(), output, tag);192
+ self.services.launches.record(child.id(), output, tag);193193
std::thread::spawn(move || child.wait());194194
Ok(())195195
}@@ -3,6 +3,7 @@
33
//! each rendered when its own vblank lands.44
55
use crate::scene::Draw;6
+use crate::state::Services;67
use crate::state::{State, now_ns};78
use monolith_config::Vrr;89
use monolith_layout::{OutputId, Rect};@@ -599,9 +600,13 @@ fn render_surface(state: &mut State, crtc: crtc::Handle, target: u64) -> bool {
599600
cursor,600601
cursor_status,601602
pointer_pos,602
- lock,603
- captures,604
- xwayland,603
+ services:604
+ Services {605
+ lock,606
+ captures,607
+ xwayland,608
+ ..609
+ },605610
..606611
} = state607612
else {@@ -6,14 +6,12 @@ use monolith_protocols::toplevel::ForeignToplevelState;
66
use monolith_protocols::workspace::WorkspaceState;77
use monolith_render_vk::VulkanRenderer;88
use smithay::backend::renderer::ImportDma;9
-use smithay::reexports::calloop::LoopHandle;109
use smithay::reexports::wayland_server::DisplayHandle;1110
use smithay::wayland::compositor::CompositorState;1211
use smithay::wayland::cursor_shape::CursorShapeManagerState;1312
use smithay::wayland::dmabuf::{DmabufGlobal, DmabufState};1413
use smithay::wayland::foreign_toplevel_list::ForeignToplevelListState;1514
use smithay::wayland::idle_inhibit::IdleInhibitManagerState;16
-use smithay::wayland::idle_notify::IdleNotifierState;1715
use smithay::wayland::image_capture_source::{1816
ImageCaptureSourceState, OutputCaptureSourceState, ToplevelCaptureSourceState,1917
};@@ -43,7 +41,6 @@ pub struct Protocols {
4341
pub wlr_data_control_state: WlrDataControlState,4442
pub ext_data_control_state: ExtDataControlState,4543
pub session_lock_state: SessionLockManagerState,46
- pub idle_notifier: IdleNotifierState<State>,4744
pub shm_state: ShmState,4845
pub dmabuf_state: DmabufState,4946
pub data_device_state: DataDeviceState,@@ -60,11 +57,7 @@ pub struct Protocols {
6057
}6158
6259
impl Protocols {63
- pub fn new(64
- dh: &DisplayHandle,65
- handle: LoopHandle<'static, State>,66
- renderer: &VulkanRenderer,67
- ) -> Self {60
+ pub fn new(dh: &DisplayHandle, renderer: &VulkanRenderer) -> Self {6861
let mut dmabuf_state = DmabufState::new();6962
let dmabuf_global = dmabuf_state.create_global::<State>(dh, renderer.dmabuf_formats());7063
let primary_selection_state = PrimarySelectionState::new::<State>(dh);@@ -88,7 +81,6 @@ impl Protocols {
8881
),8982
primary_selection_state,9083
session_lock_state: SessionLockManagerState::new::<State, _>(dh, |_| true),91
- idle_notifier: IdleNotifierState::new(dh, handle),9284
shm_state: ShmState::new::<State>(dh, vec![]),9385
dmabuf_state,9486
data_device_state: DataDeviceState::new::<State>(dh),@@ -80,10 +80,10 @@ impl CompositorHandler for State {
8080
{8181
window.on_commit();8282
}83
- if self.captures.wants_damage()83
+ if self.services.captures.wants_damage()8484
&& let Some(id) = self.window_id(&root)8585
{86
- self.captures.window_damaged(id);86
+ self.services.captures.window_damaged(id);8787
}8888
}8989
if let Some(i) = self@@ -2,26 +2,44 @@
22
//! when the user went away and video players can keep the screen on.33
44
use crate::state::State;5
-use smithay::reexports::wayland_server::Resource;5
+use smithay::reexports::calloop::LoopHandle;66
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;7
+use smithay::reexports::wayland_server::{DisplayHandle, Resource};78
use smithay::wayland::compositor::get_parent;89
use smithay::wayland::idle_inhibit::IdleInhibitHandler;910
use smithay::wayland::idle_notify::{IdleNotifierHandler, IdleNotifierState};11
+use std::collections::HashSet;12
+13
+pub struct Idle {14
+ pub notifier: IdleNotifierState<State>,15
+ pub inhibitors: HashSet<WlSurface>,16
+ pub inhibited: bool,17
+}18
+19
+impl Idle {20
+ pub fn new(dh: &DisplayHandle, handle: LoopHandle<'static, State>) -> Self {21
+ Self {22
+ notifier: IdleNotifierState::new(dh, handle),23
+ inhibitors: HashSet::new(),24
+ inhibited: false,25
+ }26
+ }27
+}1028
1129
impl IdleNotifierHandler for State {1230
fn idle_notifier_state(&mut self) -> &mut IdleNotifierState<Self> {13
- &mut self.protocols.idle_notifier31
+ &mut self.services.idle.notifier1432
}1533
}1634
1735
impl IdleInhibitHandler for State {1836
fn inhibit(&mut self, surface: WlSurface) {19
- self.inhibitors.insert(surface);37
+ self.services.idle.inhibitors.insert(surface);2038
self.update_inhibit();2139
}2240
2341
fn uninhibit(&mut self, surface: WlSurface) {24
- self.inhibitors.remove(&surface);42
+ self.services.idle.inhibitors.remove(&surface);2543
self.update_inhibit();2644
}2745
}@@ -29,14 +47,14 @@ impl IdleInhibitHandler for State {
2947
impl State {3048
pub fn activity(&mut self) {3149
let seat = self.seat.clone();32
- self.protocols.idle_notifier.notify_activity(&seat);50
+ self.services.idle.notifier.notify_activity(&seat);3351
}3452
3553
/// An inhibitor only counts while its surface is on screen, as the3654
/// protocol asks, so a video on a hidden tag lets the screen blank.3755
pub fn update_inhibit(&mut self) {38
- self.inhibitors.retain(|s| s.is_alive());39
- let shown = self.inhibitors.iter().any(|s| {56
+ self.services.idle.inhibitors.retain(|s| s.is_alive());57
+ let shown = self.services.idle.inhibitors.iter().any(|s| {4058
let mut root = s.clone();4159
while let Some(parent) = get_parent(&root) {4260
root = parent;@@ -46,9 +64,9 @@ impl State {
4664
.any(|w| crate::state::root(w).as_ref() == Some(&root))4765
|| self.layer_maps_contain(&root)4866
});49
- if shown != self.inhibited {50
- self.inhibited = shown;51
- self.protocols.idle_notifier.set_is_inhibited(shown);67
+ if shown != self.services.idle.inhibited {68
+ self.services.idle.inhibited = shown;69
+ self.services.idle.notifier.set_is_inhibited(shown);5270
}5371
}5472
}@@ -88,7 +88,7 @@ impl State {
8888
let _ = notifier.successful::<State>();8989
return;9090
}91
- self.imports.start(buffer).notifiers.push(notifier);91
+ self.services.imports.start(buffer).notifiers.push(notifier);9292
}9393
9494
/// A blocker for a commit whose dmabuf the renderer has not imported yet.@@ -96,13 +96,13 @@ impl State {
9696
if self.renderer.has_dmabuf(buffer) {9797
return None;9898
}99
- let waiters = self.imports.start(buffer);99
+ let waiters = self.services.imports.start(buffer);100100
waiters.clients.push(client);101101
Some(ImportBlocker(waiters.done.clone()))102102
}103103
104104
fn imported(&mut self, buffer: Dmabuf, result: Result<VulkanTexture, String>) {105
- let Some(waiters) = self.imports.waiting.remove(&buffer.weak()) else {105
+ let Some(waiters) = self.services.imports.waiting.remove(&buffer.weak()) else {106106
return;107107
};108108
let result = result.and_then(|t| {@@ -38,7 +38,7 @@ impl State {
3838
if pressed == ButtonState::Released && self.drag.take().is_some() {3939
return;4040
}41
- if pressed == ButtonState::Pressed && !self.lock.active() {41
+ if pressed == ButtonState::Pressed && !self.services.lock.active() {4242
focus_under_pointer(self);4343
if start_drag(self, button) {4444
return;@@ -100,7 +100,7 @@ impl State {
100100
let vt = (sym - xkb::keysyms::KEY_XF86Switch_VT_1 + 1) as i32;101101
return FilterResult::Intercept(Some(Action::Vt(vt)));102102
}103
- if state.lock.active() {103
+ if state.services.lock.active() {104104
return FilterResult::Forward;105105
}106106
match state.settings.binds.find(mods, &handle.raw_syms()) {@@ -40,9 +40,9 @@ pub fn init(event_loop: &EventLoop<'static, State>, state: &mut State) -> std::i
4040
let listener = UnixListener::bind(&path)?;4141
listener.set_nonblocking(true)?;4242
tracing::info!(path = %path.display(), "control socket");43
- state.ipc.path = Some(path);43
+ state.services.ipc.path = Some(path);4444
let handle = event_loop.handle();45
- state.ipc.handle = Some(handle.clone());45
+ state.services.ipc.handle = Some(handle.clone());4646
handle4747
.insert_source(4848
Generic::new(listener, Interest::READ, Mode::Level),@@ -62,7 +62,7 @@ pub fn init(event_loop: &EventLoop<'static, State>, state: &mut State) -> std::i
6262
}6363
6464
fn add_client(state: &mut State, stream: UnixStream) {65
- let Some(handle) = state.ipc.handle.clone() else {65
+ let Some(handle) = state.services.ipc.handle.clone() else {6666
return;6767
};6868
if stream.set_nonblocking(true).is_err() {@@ -117,7 +117,7 @@ fn handle_line(state: &mut State, stream: &UnixStream, line: &[u8]) -> Option<En
117117
return Some(Envelope::new(id, Reply::Error("cannot subscribe".into())));118118
};119119
send(&sub, &Envelope::new(None, Reply::Event(snapshot(state))));120
- state.ipc.subscribers.push(sub);120
+ state.services.ipc.subscribers.push(sub);121121
return None;122122
}123123
};@@ -134,16 +134,16 @@ fn send(mut stream: &UnixStream, msg: &Envelope<Reply>) -> bool {
134134
135135
/// Sends subscribers the new state whenever it differs from the last one.136136
pub fn broadcast(state: &mut State) {137
- if state.ipc.subscribers.is_empty() {137
+ if state.services.ipc.subscribers.is_empty() {138138
return;139139
}140140
let now = snapshot(state);141
- if state.ipc.last.as_ref() == Some(&now) {141
+ if state.services.ipc.last.as_ref() == Some(&now) {142142
return;143143
}144144
let msg = Envelope::new(None, Reply::Event(now.clone()));145
- state.ipc.subscribers.retain(|s| send(s, &msg));146
- state.ipc.last = Some(now);145
+ state.services.ipc.subscribers.retain(|s| send(s, &msg));146
+ state.services.ipc.last = Some(now);147147
}148148
149149
fn snapshot(state: &State) -> monolith_ipc::State {@@ -55,8 +55,8 @@ impl SessionLockHandler for State {
5555
5656
fn lock(&mut self, confirmation: SessionLocker) {5757
tracing::info!("session lock requested");58
- self.lock.pending = Some(confirmation);59
- self.lock.blanked.clear();58
+ self.services.lock.pending = Some(confirmation);59
+ self.services.lock.blanked.clear();6060
self.drag = None;6161
self.sync_focus();6262
self.needs_redraw = true;@@ -64,7 +64,7 @@ impl SessionLockHandler for State {
6464
6565
fn unlock(&mut self) {6666
tracing::info!("session unlocked");67
- self.lock = Lock::default();67
+ self.services.lock = Lock::default();6868
self.sync_focus();6969
self.needs_redraw = true;7070
}@@ -74,10 +74,11 @@ impl SessionLockHandler for State {
7474
return;7575
};7676
configure(&surface, &output);77
- self.lock77
+ self.services78
+ .lock7879
.surfaces7980
.retain(|(o, s)| o != &output && s.alive());80
- self.lock.surfaces.push((output, surface));81
+ self.services.lock.surfaces.push((output, surface));8182
self.sync_focus();8283
self.needs_redraw = true;8384
}@@ -97,23 +98,23 @@ impl State {
9798
/// windows, so nothing private is left on screen when the locker is told9899
/// it holds the session.99100
pub fn confirm_lock(&mut self) {100
- if self.lock.pending.is_none() {101
+ if self.services.lock.pending.is_none() {101102
return;102103
}103104
let all = self104105
.space105106
.outputs()106
- .all(|o| self.lock.blanked.contains(&o.name()));107
- if all && let Some(locker) = self.lock.pending.take() {107
+ .all(|o| self.services.lock.blanked.contains(&o.name()));108
+ if all && let Some(locker) = self.services.lock.pending.take() {108109
locker.lock();109
- self.lock.locked = true;110
+ self.services.lock.locked = true;110111
tracing::info!("session locked");111112
}112113
}113114
114115
/// Resends sizes after an output changed mode.115116
pub fn reconfigure_lock(&self) {116
- for (output, surface) in &self.lock.surfaces {117
+ for (output, surface) in &self.services.lock.surfaces {117118
configure(surface, output);118119
}119120
}@@ -121,9 +122,10 @@ impl State {
121122
pub fn lock_keyboard_focus(&self) -> Option<WlSurface> {122123
let under = self.space.output_under(self.pointer_pos).next();123124
under124
- .and_then(|o| self.lock.surface_on(o))125
+ .and_then(|o| self.services.lock.surface_on(o))125126
.or_else(|| {126
- self.lock127
+ self.services128
+ .lock127129
.surfaces128130
.iter()129131
.map(|(_, s)| s)@@ -138,7 +140,7 @@ impl State {
138140
) -> Option<(WlSurface, Point<f64, Logical>)> {139141
let output = self.space.output_under(pos).next()?;140142
let origin = self.space.output_geometry(output)?.loc;141
- let surface = self.lock.surface_on(output)?;143
+ let surface = self.services.lock.surface_on(output)?;142144
under_from_surface_tree(143145
surface.wl_surface(),144146
pos - origin.to_f64(),@@ -164,6 +164,7 @@ fn export_session(state: &State) {
164164
.arg("XDG_SESSION_TYPE=wayland")165165
.args(166166
state167
+ .services167168
.xwayland168169
.as_ref()169170
.map(|x| format!("DISPLAY=:{}", x.display)),@@ -5,6 +5,7 @@
55
66
mod input;77
8
+use crate::state::Services;89
use crate::state::State;910
use calloop_wayland_source::WaylandSource;1011
use monolith_layout::Rect;@@ -179,9 +180,13 @@ pub fn render(state: &mut State) {
179180
borders,180181
settings,181182
output_id,182
- lock,183
- captures,184
- xwayland,183
+ services:184
+ Services {185
+ lock,186
+ captures,187
+ xwayland,188
+ ..189
+ },185190
..186191
} = state;187192
let Some(host) = host.as_mut() else { return };@@ -62,8 +62,7 @@ pub struct State {
6262
pub drag: Option<crate::input::Drag>,6363
/// Global logical position, shared by every backend.6464
pub pointer_pos: Point<f64, Logical>,65
- pub ipc: crate::ipc::Server,66
- pub launches: crate::launch::Launches,65
+ pub services: Services,6766
pub list_handles: crate::toplevels::ListHandles,6867
pub anim: Animator,6968
pub borders: crate::scene::Borders,@@ -75,14 +74,8 @@ pub struct State {
7574
pub placed_by_rule: HashSet<WindowId>,7675
/// A layer surface given the keyboard by a click, like a launcher.7776
pub layer_focus: Option<WlSurface>,78
- pub xwayland: Option<crate::xwayland::Xwayland>,79
- pub captures: crate::capture::Captures,80
- pub imports: crate::import::Imports,8177
/// The render node clients get dmabufs for, known on bare metal.8278
pub render_node: Option<smithay::backend::drm::DrmNode>,83
- pub lock: crate::lock::Lock,84
- pub inhibitors: HashSet<WlSurface>,85
- pub inhibited: bool,8679
pub seat_state: SeatState<State>,8780
pub seat: Seat<State>,8881
}@@ -96,6 +89,17 @@ pub struct Core {
9689
pub start: Instant,9790
}9891
92
+/// Subsystems with state of their own.93
+pub struct Services {94
+ pub lock: crate::lock::Lock,95
+ pub captures: crate::capture::Captures,96
+ pub imports: crate::import::Imports,97
+ pub xwayland: Option<crate::xwayland::Xwayland>,98
+ pub launches: crate::launch::Launches,99
+ pub ipc: crate::ipc::Server,100
+ pub idle: crate::idle::Idle,101
+}102
+99103
/// The config and what is derived from it, swapped whole on reload.100104
pub struct Settings {101105
pub config: Config,@@ -151,8 +155,9 @@ impl State {
151155
layout.gaps = gaps(&config);152156
let animation = config.animation.clone();153157
let imports = crate::import::Imports::new(&handle, renderer.dmabuf_importer())?;158
+ let idle = crate::idle::Idle::new(&dh, handle.clone());154159
Ok(Self {155
- protocols: Protocols::new(&dh, handle.clone(), &renderer),160
+ protocols: Protocols::new(&dh, &renderer),156161
core: Core {157162
display: dh,158163
handle,@@ -183,8 +188,15 @@ impl State {
183188
move_inverted: false,184189
drag: None,185190
pointer_pos: Point::default(),186
- ipc: crate::ipc::Server::default(),187
- launches: Default::default(),191
+ services: Services {192
+ lock: Default::default(),193
+ captures: Default::default(),194
+ imports,195
+ xwayland: None,196
+ launches: Default::default(),197
+ ipc: Default::default(),198
+ idle,199
+ },188200
list_handles: Default::default(),189201
anim: Animator::new(animation),190202
borders: Default::default(),@@ -192,13 +204,7 @@ impl State {
192204
awaiting: HashSet::new(),193205
placed_by_rule: HashSet::new(),194206
layer_focus: None,195
- xwayland: None,196
- captures: Default::default(),197
- imports,198207
render_node: None,199
- lock: Default::default(),200
- inhibitors: HashSet::new(),201
- inhibited: false,202208
seat_state,203209
seat,204210
})@@ -249,7 +255,7 @@ impl State {
249255
.and_then(|c| c.get_credentials(&self.core.display).ok())250256
.map(|c| c.pid as u32),251257
};252
- let launch = pid.and_then(|pid| self.launches.find(pid));258
+ let launch = pid.and_then(|pid| self.services.launches.find(pid));253259
let output = rule254260
.output255261
.as_deref()@@ -517,7 +523,7 @@ impl State {
517523
t.send_pending_configure();518524
}519525
}520
- let target: Option<Focus> = if self.lock.active() {526
+ let target: Option<Focus> = if self.services.lock.active() {521527
self.lock_keyboard_focus().map(Focus::from)522528
} else {523529
self.layer_keyboard_focus().map(Focus::from).or_else(|| {@@ -597,10 +603,14 @@ impl State {
597603
&self,598604
pos: Point<f64, Logical>,599605
) -> Option<(WlSurface, Point<f64, Logical>)> {600
- if self.lock.active() {606
+ if self.services.lock.active() {601607
return self.lock_surface_under(pos);602608
}603
- let unmanaged = self.xwayland.iter().flat_map(|x| x.unmanaged.iter().rev());609
+ let unmanaged = self610
+ .services611
+ .xwayland612
+ .iter()613
+ .flat_map(|x| x.unmanaged.iter().rev());604614
for x in unmanaged {605615
let geo = x.geometry();606616
if let Some(s) = x.wl_surface()@@ -113,7 +113,7 @@ pub fn init(state: &mut State) {
113113
}114114
}115115
tracing::info!("X11 clients will start Xwayland on :{number}");116
- state.xwayland = Some(Xwayland {116
+ state.services.xwayland = Some(Xwayland {117117
display: number,118118
listeners,119119
watch,@@ -125,7 +125,7 @@ pub fn init(state: &mut State) {
125125
126126
/// Waits for the next X client to knock.127127
fn rearm(state: &mut State) {128
- let Some(x) = state.xwayland.as_mut() else {128
+ let Some(x) = state.services.xwayland.as_mut() else {129129
return;130130
};131131
x.running = false;@@ -147,7 +147,7 @@ fn set_inherit(listeners: &[UnixListener], inherit: bool) {
147147
}148148
149149
fn start(state: &mut State, fired: usize) {150
- let Some(x) = state.xwayland.as_mut() else {150
+ let Some(x) = state.services.xwayland.as_mut() else {151151
return;152152
};153153
if x.running {@@ -195,7 +195,7 @@ fn start(state: &mut State, fired: usize) {
195195
match X11Wm::start_wm(state.core.handle.clone(), &dh, x11_socket, client.clone()) {196196
Ok(wm) => {197197
tracing::info!("Xwayland ready");198
- if let Some(x) = state.xwayland.as_mut() {198
+ if let Some(x) = state.services.xwayland.as_mut() {199199
x.wm = Some(wm);200200
}201201
}@@ -225,7 +225,8 @@ impl XWaylandShellHandler for State {
225225
226226
impl XwmHandler for State {227227
fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm {228
- self.xwayland228
+ self.services229
+ .xwayland229230
.as_mut()230231
.and_then(|x| x.wm.as_mut())231232
.expect("X11 events only arrive while the WM runs")@@ -245,7 +246,7 @@ impl XwmHandler for State {
245246
}246247
247248
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) {248
- if let Some(x) = self.xwayland.as_mut() {249
+ if let Some(x) = self.services.xwayland.as_mut() {249250
x.unmanaged.retain(|w| w != &window);250251
x.unmanaged.push(window);251252
}@@ -327,7 +328,7 @@ impl XwmHandler for State {
327328
for id in gone {328329
self.remove_window(id);329330
}330
- if let Some(x) = self.xwayland.as_mut() {331
+ if let Some(x) = self.services.xwayland.as_mut() {331332
x.wm = None;332333
x.unmanaged.clear();333334
}@@ -363,7 +364,7 @@ impl State {
363364
}364365
365366
fn forget_x11(&mut self, window: &X11Surface) {366
- if let Some(x) = self.xwayland.as_mut() {367
+ if let Some(x) = self.services.xwayland.as_mut() {367368
x.unmanaged.retain(|w| w != window);368369
}369370
if let Some(id) = self.x11_window_id(window) {