From bb59ecfa2f1329d978fcfa8b7455db649f019f85 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:08:00 +0200 Subject: Send tiled xdg_toplevel state so GTK stops reserving its own shadow No configure this compositor ever sent set any xdg_toplevel::State bit at all - confirmed by grepping the whole crate, zero hits before this. GTK4 (Firefox concretely) reads the tiled bits to decide whether to reserve an invisible client-side shadow margin around its own content, independent of server- vs client-side decoration; with none ever sent it always assumed "floating, might need a shadow" and kept reserving one. That margin sits inside the committed buffer but is functionally invisible, so this compositor's own border - drawn at the full geometry, margin included, since nothing here knew the margin existed - ended up visibly offset from where the client's real chrome began. Root-caused from a live screenshot: Firefox's srdwm-drawn border sat clearly up-and-left of its actual toolbar, not framing it. Reported as "border is not with the window at start" and, more generally, borders never feeling like part of the window they're drawn around - which this is: decoration and content genuinely disagreeing about where the window's edge is. Sets all four Tiled* bits unconditionally on every xdg_toplevel configure - the same technique river/dwl use, telling every window it's flush against something and should skip its own shadow regardless of whether it's in a literal tiling layout, which is the outcome actually wanted here: this compositor draws the frame, nothing else should also be reserving room for one. Not visually verified against a live client yet - this needs an actual GTK app rendering under a restarted session to confirm the shadow margin is really gone, which no offline test can substitute for. --- crates/wayland/src/state/geometry.rs | 29 +++++++++++++++++++++++++++++ crates/wayland/src/state/mod.rs | 1 + 2 files changed, 30 insertions(+) (limited to 'crates/wayland/src/state') diff --git a/crates/wayland/src/state/geometry.rs b/crates/wayland/src/state/geometry.rs index b902d16..c3de7fa 100644 --- a/crates/wayland/src/state/geometry.rs +++ b/crates/wayland/src/state/geometry.rs @@ -64,6 +64,35 @@ impl CompState { if size_changed { top.with_pending_state(|state| { state.size = Some(size.into()); + // No configure from this compositor, ever, set any + // `xdg_toplevel` state bit at all before this -- + // confirmed by grepping the whole crate for + // `xdg_toplevel::State`, zero hits. GTK4 (Firefox + // concretely) reads the tiled bits to decide whether + // to reserve its own invisible client-side shadow + // margin around its actual content, independent of + // whether decoration is server- or client-side -- + // with none ever sent, it always assumed "floating, + // might need a shadow" and kept reserving one. That + // margin sits inside the committed buffer but is + // functionally invisible, so this compositor's own + // border - drawn at the *full* geometry, margin + // included, since nothing here knew the margin + // existed - ended up visibly offset from where the + // client's real chrome began. Reported live as + // Firefox's border "not with the window," and more + // generally never feeling like part of it. Setting + // all four unconditionally (the same technique + // river/dwl use) tells every window it's flush + // against something and should skip its own shadow, + // regardless of whether it's actually in a tiled + // layout - which is the outcome actually wanted: + // this compositor draws the frame, so nothing else + // should also be reserving room for one. + state.states.set(xdg_toplevel::State::TiledLeft); + state.states.set(xdg_toplevel::State::TiledRight); + state.states.set(xdg_toplevel::State::TiledTop); + state.states.set(xdg_toplevel::State::TiledBottom); }); top.send_configure(); } diff --git a/crates/wayland/src/state/mod.rs b/crates/wayland/src/state/mod.rs index 9e2c136..ff7ef74 100644 --- a/crates/wayland/src/state/mod.rs +++ b/crates/wayland/src/state/mod.rs @@ -33,6 +33,7 @@ use smithay::wayland::selection::primary_selection::{set_primary_focus, PrimaryS use smithay::wayland::selection::wlr_data_control::DataControlState; use smithay::wayland::session_lock::SessionLockManagerState; use smithay::wayland::shell::wlr_layer::{KeyboardInteractivity, LayerSurfaceData, WlrLayerShellState}; +use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; use smithay::wayland::shell::xdg::{ToplevelSurface, XdgShellState, XdgToplevelSurfaceData}; use smithay::wayland::shell::xdg::decoration::XdgDecorationState; use smithay::wayland::dmabuf::DmabufState; -- cgit v1.2.3