atagen

monolith

public
Star0
Watch0

Commit c92022840707

tarball

atagen <boss@atagen.co>2026-10-19 10:50 UTC

4 files changed+31-37
windows: share one fullscreen toggle between xdg, X11 and taskbars

The three copies had drifted. Only the taskbar path skipped focus_if_covering, and only the xdg path could move the window to a requested output.
Modified file: crates/monolith/src/toplevels.rs+1 additions−8 deletions
@@ -50,14 +50,7 @@ impl ForeignToplevelHandler for State {
5050 }
5151 Action::Fullscreen(k, on) => {
5252 let Some(id) = id_of(k) else { return };
53- if self
54- .wm
55- .layout
56- .window(id)
57- .is_some_and(|w| w.fullscreen != on)
58- {
59- self.wm.layout.toggle_fullscreen(id);
60- }
53+ self.set_window_fullscreen(id, on, None);
6154 if on && self.wm.layout.visible(id) {
6255 self.wm.layout.focus(id);
6356 }
Modified file: crates/monolith/src/windows.rs+27 additions
@@ -128,6 +128,33 @@ impl State {
128128 self.window_id(&parent)
129129 }
130130
131+ /// Makes a window fullscreen or not, on `output` when it names one, for
132+ /// every route a client or taskbar has to ask. Returns whether anything
133+ /// changed, for the caller to lay out again.
134+ pub(crate) fn set_window_fullscreen(
135+ &mut self,
136+ id: WindowId,
137+ on: bool,
138+ output: Option<OutputId>,
139+ ) -> bool {
140+ let layout = &mut self.wm.layout;
141+ let Some(win) = layout.window(id) else {
142+ return false;
143+ };
144+ let (toggled, moved) = (
145+ win.fullscreen != on,
146+ output.filter(|&o| win.output != Some(o)),
147+ );
148+ if let Some(o) = moved {
149+ layout.send_to_output(id, o);
150+ }
151+ if toggled {
152+ layout.toggle_fullscreen(id);
153+ layout.focus_if_covering(id);
154+ }
155+ toggled || moved.is_some()
156+ }
157+
131158 /// Feeds the window's modal state to the layout and lets focus follow.
132159 pub(crate) fn sync_modal(&mut self, id: WindowId) {
133160 let modal = self.wm.window(id).is_some_and(is_modal);
Modified file: crates/monolith/src/xdg.rs+2 additions−22 deletions
@@ -233,28 +233,8 @@ impl State {
233233 });
234234 return;
235235 };
236- let target = output
237- .as_ref()
238- .and_then(|o| self.layout_output(o))
239- .filter(|&o| {
240- self.wm
241- .layout
242- .window(id)
243- .is_some_and(|w| w.output != Some(o))
244- });
245- if let Some(o) = target {
246- self.wm.layout.send_to_output(id, o);
247- }
248- let toggled = self
249- .wm
250- .layout
251- .window(id)
252- .is_some_and(|w| w.fullscreen != on);
253- if toggled {
254- self.wm.layout.toggle_fullscreen(id);
255- self.wm.layout.focus_if_covering(id);
256- }
257- if target.is_some() || toggled {
236+ let target = output.as_ref().and_then(|o| self.layout_output(o));
237+ if self.set_window_fullscreen(id, on, target) {
258238 self.apply_layout();
259239 }
260240 }
Modified file: crates/monolith/src/xwayland.rs+1 additions−7 deletions
@@ -564,14 +564,8 @@ impl State {
564564
565565 fn x11_fullscreen(&mut self, window: &X11Surface, on: bool) {
566566 if let Some(id) = self.x11_window_id(window)
567- && self
568- .wm
569- .layout
570- .window(id)
571- .is_some_and(|w| w.fullscreen != on)
567+ && self.set_window_fullscreen(id, on, None)
572568 {
573- self.wm.layout.toggle_fullscreen(id);
574- self.wm.layout.focus_if_covering(id);
575569 self.apply_layout();
576570 }
577571 }