atagen

monolith

public
Star0
Watch0

Commit ceab46c322ef

tarball

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

2 files changed+25-1
monolith: follow window geometry changes in the input space

Windows were mapped into the Space at their placed rect minus geometry().loc only during apply_layout, while drawing reads the geometry every frame. GTK sends its first buffer with shadow margins and drops them once configured as tiled, so caja was drawn at its rect but hit-tested a shadow width up and left until something re-laid out its output.
Modified file: crates/monolith/src/commit.rs+1 additions
@@ -65,6 +65,7 @@ impl CompositorHandler for State {
6565 self.count_commit(&root);
6666 if let Some(id) = self.window_id(&root) {
6767 self.refresh_identity(id);
68+ self.realign(id);
6869 if self.services.captures.wants_damage() {
6970 self.services.captures.window_damaged(id);
7071 }
Modified file: crates/monolith/src/windows.rs+24 additions−1 deletions
@@ -9,7 +9,7 @@ use smithay::desktop::Window;
99 use smithay::reexports::calloop::timer::{TimeoutAction, Timer};
1010 use smithay::reexports::wayland_server::Resource;
1111 use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
12-use smithay::utils::{Logical, Rectangle};
12+use smithay::utils::{Logical, Point, Rectangle};
1313 use std::time::Duration;
1414
1515 impl State {
@@ -252,6 +252,29 @@ impl State {
252252
253253 /// Brings a window's tag into view when it is the tag's first window,
254254 /// whether it mapped there, was moved there or was placed by activation.
255+ /// Moves a mapped window's input region to follow its window geometry.
256+ /// GTK drops its shadow margins once told it is tiled, shifting the
257+ /// geometry after `apply_layout` placed it, so clicks landed a shadow's
258+ /// width away from what was drawn.
259+ pub fn realign(&mut self, id: WindowId) {
260+ let Some(s) = self.wm.get(id) else {
261+ return;
262+ };
263+ let Some((_, rect, _)) = s.placed else {
264+ return;
265+ };
266+ let window = &s.window;
267+ let Some(mapped) = self.wm.space.element_location(window) else {
268+ return;
269+ };
270+ let at =
271+ Point::from((rect.x.round() as i32, rect.y.round() as i32)) - window.geometry().loc;
272+ if at != mapped {
273+ let window = window.clone();
274+ self.wm.space.relocate_element(&window, at);
275+ }
276+ }
277+
255278 pub fn view_if_first(&mut self, id: WindowId) {
256279 if self.settings.config.general.view_tag_on_first_window {
257280 self.wm.layout.view_if_alone(id);