atagen

monolith

public
Star0
Watch0

Commit 92d5331c9dd9

tarball

atagen <boss@atagen.co>2026-10-17 03:59 UTC

4 files changed+3-24
monolith: keep client snapshots current before anyone binds

Publishing skipped building the workspace and toplevel snapshots while no client was bound. With publishing gated on the dirty flag, a client binding into a quiet desktop got the empty snapshot and was never sent the windows, so wlrctl saw nothing to act on. Snapshots are now rebuilt whenever they are dirty, which the gate already keeps cheap.
Modified file: crates/monolith/src/state.rs+1 additions−6 deletions
@@ -553,9 +553,6 @@ impl State {
553553 }
554554
555555 fn publish_workspaces(&mut self) {
556- if !self.protocols.workspaces.has_clients() {
557- return;
558- }
559556 let l = &self.wm.layout;
560557 let occupied: HashSet<(OutputId, monolith_layout::TagId)> = l
561558 .windows()
@@ -630,9 +627,7 @@ impl State {
630627 }
631628 let fullscreen = self.wm.layout.outputs().any(|(o, out)| {
632629 let a = out.area;
633- (a.x..a.right()).contains(&pos.x)
634- && (a.y..a.bottom()).contains(&pos.y)
635- && self.wm.layout.arrange(o).fullscreen.is_some()
630+ a.contains(pos.x, pos.y) && self.wm.layout.arrange(o).fullscreen.is_some()
636631 });
637632 let above: &[Layer] = if fullscreen {
638633 &[Layer::Overlay]
Modified file: crates/monolith/src/toplevels.rs+2 additions−10 deletions
@@ -2,7 +2,6 @@
22 //! and wlr-foreign-toplevel-management for taskbars that also act on them.
33
44 use crate::state::State;
5-use monolith_layout::WindowId;
65 use monolith_protocols::toplevel::{
76 Action, ForeignToplevelHandler, ForeignToplevelState, Snapshot, Toplevel,
87 };
@@ -10,10 +9,6 @@ use smithay::wayland::foreign_toplevel_list::{
109 ForeignToplevelListHandler, ForeignToplevelListState,
1110 };
1211
13-pub fn key(id: WindowId) -> u64 {
14- slotmap::Key::data(&id).as_ffi()
15-}
16-
1712 impl ForeignToplevelListHandler for State {
1813 fn foreign_toplevel_list_state(&mut self) -> &mut ForeignToplevelListState {
1914 &mut self.protocols.toplevel_list
@@ -26,7 +21,7 @@ impl ForeignToplevelHandler for State {
2621 }
2722
2823 fn foreign_toplevel_action(&mut self, action: Action) {
29- let id_of = |k: u64| self.wm.iter().map(|(id, _)| id).find(|&id| key(id) == k);
24+ let id_of = |k: u64| self.wm.by_key(k);
3025 match action {
3126 Action::Activate(k) => {
3227 let Some(id) = id_of(k) else { return };
@@ -90,9 +85,6 @@ impl State {
9085 }
9186 list.cleanup_closed_handles();
9287
93- if !self.protocols.foreign_toplevels.has_clients() {
94- return;
95- }
9688 let focused = self.wm.layout.focused();
9789 let toplevels = self
9890 .wm
@@ -101,7 +93,7 @@ impl State {
10193 let (app_id, title) = (w.app_id.clone(), w.title.clone());
10294 let w = self.wm.layout.window(id);
10395 Toplevel {
104- key: key(id),
96+ key: crate::wm::key(id),
10597 title,
10698 app_id,
10799 outputs: w
Modified file: crates/protocols/src/toplevel.rs−4 deletions
@@ -85,10 +85,6 @@ impl ForeignToplevelState {
8585 self.global.clone()
8686 }
8787
88- pub fn has_clients(&self) -> bool {
89- !self.managers.is_empty()
90- }
91-
9288 pub fn update<D>(&mut self, dh: &DisplayHandle, snapshot: Snapshot)
9389 where
9490 D: Dispatch<ZwlrForeignToplevelHandleV1, HandleData> + 'static,
Modified file: crates/protocols/src/workspace.rs−4 deletions
@@ -109,10 +109,6 @@ impl WorkspaceState {
109109 self.global.clone()
110110 }
111111
112- pub fn has_clients(&self) -> bool {
113- !self.managers.is_empty()
114- }
115-
116112 /// Publishes a snapshot. Clients only hear about differences, including
117113 /// wl_outputs they bound after the manager.
118114 pub fn update<D>(&mut self, dh: &DisplayHandle, snapshot: Snapshot)