diff options
| author | srdusr <[email protected]> | 2024-08-20 23:08:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-08-20 23:08:00 +0200 |
| commit | bb59ecfa2f1329d978fcfa8b7455db649f019f85 (patch) | |
| tree | dafd907e26c1268ce0517544e6d1ba39a25d9aba /crates | |
| parent | d124fc27826c2cdf57e46d104db5347434454a24 (diff) | |
| download | srdwm-bb59ecfa2f1329d978fcfa8b7455db649f019f85.tar.gz srdwm-bb59ecfa2f1329d978fcfa8b7455db649f019f85.zip | |
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.
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/wayland/src/state/geometry.rs | 29 | ||||
| -rw-r--r-- | crates/wayland/src/state/mod.rs | 1 |
2 files changed, 30 insertions, 0 deletions
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; |