diff options
| author | srdusr <[email protected]> | 2026-05-11 16:57:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2026-05-11 16:57:00 +0200 |
| commit | 646b37e7e3aa5931079c6b9e804f420bb43c74d5 (patch) | |
| tree | 159825fae0086c162b36edc6e78da07d975ab6b0 /crates/config/src/engine | |
| parent | caec1e7c355bbe6437afe87cd3dab6b64fb91e0a (diff) | |
| download | srdwm-646b37e7e3aa5931079c6b9e804f420bb43c74d5.tar.gz srdwm-646b37e7e3aa5931079c6b9e804f420bb43c74d5.zip | |
Fix spawn placement under the top bar, add per-window minimum sizes, and clean up maximize
Four reports after restarting into today's build, with a screenshot. The
screenshot was measured, not eyeballed: top bar y=0..29, a 4px accent border
at y=30..33, titlebar from y=34, bottom border at y=1027..1030, and 49px of
bare desktop below it.
Windows spawning too close to the top bar. A remembered position was
validated only by asking whether it landed on some monitor's full_geometry,
which includes the strip a top bar reserves, so an app whose remembered y was
small reopened with its titlebar under the bar. That is why it was
"sometimes": it depended on the stored value, and the live store holds
wezterm at y=44 and firefox at y=69 against a 30px bar. Remembered positions
are now clamped into the monitor's usable area.
Placement not surviving a logout. Window memory does persist, but five of the
eleven entries in the live store were saved with a second monitor attached,
at x >= 2000. Those points match no current monitor and were discarded
outright, falling back to a fresh cascade, so those apps appeared to remember
nothing. Such a position is now clamped onto a monitor that exists instead.
Per-window minimum sizes. One global floor is wrong in both directions.
Three sources now, in increasing precedence: the global floor, the client's
own declared minimum (xdg_toplevel.set_min_size or ICCCM hints), and a
min_width/min_height window rule overriding both. A rule wins permanently --
the backend refreshes the client's declared minimum on every decoration
redraw and must not undo a deliberate override.
Maximize, three faults in one report. A maximized window now draws no
border: its edges are the screen's edges, and the only place maximize stops
short is the bar strip, which is exactly where the measured line was.
maximize_geometry_for no longer subtracts a bottom-anchored dock's exclusive
zone, so maximize runs to the bottom of the screen and the dock floats over
it; top, left and right are still honoured.
general.maximize_covers_dock = false restores the old behaviour. With the
border gone the window sits flush under the bar instead of with an accent
line crowding it.
Verified: seven new tests on the real numbers from the live store, and
maximize geometry measured live in a nested instance (a window maximized on a
split half reports exactly that half's rect). NOT confirmed on screen: the
border removal and the dock behaviour - the nested backend has no bar or
dock to reserve a zone, and an attempt to check the border produced a failing
control, since srd set border_width only affects windows created after it.
515 tests pass, clippy clean.
Diffstat (limited to 'crates/config/src/engine')
| -rw-r--r-- | crates/config/src/engine/general.rs | 18 | ||||
| -rw-r--r-- | crates/config/src/engine/support.rs | 3 |
2 files changed, 21 insertions, 0 deletions
diff --git a/crates/config/src/engine/general.rs b/crates/config/src/engine/general.rs index c10ecf0..c8a136f 100644 --- a/crates/config/src/engine/general.rs +++ b/crates/config/src/engine/general.rs @@ -172,6 +172,23 @@ impl Engine { _ => None, } }; + // `min_width`/`min_height` - the smallest this window may be + // resized to, overriding whatever the client itself declared. + // Two plain numbers rather than a `"WxH"` string: unlike an + // aspect ratio, a size is not conventionally written as one + // token, and `width`/`height` above already set the precedent + // for separate keys. + let min_size: Option<(u32, u32)> = { + let min_width: Option<u32> = actions.get("min_width")?; + let min_height: Option<u32> = actions.get("min_height")?; + match (min_width, min_height) { + (None, None) => None, + // One alone is meaningful - a terminal that needs + // width but no particular height, say. The unset axis + // keeps the global floor. + (w, h) => Some((w.unwrap_or(srdwm_core::MIN_WINDOW_WIDTH), h.unwrap_or(srdwm_core::MIN_WINDOW_HEIGHT))), + } + }; // `aspect_ratio = "9:16"` - the "phone monitor / special // workspace" ask's own real, scoped answer (see `Window:: // aspect_ratio`'s own doc comment in `crates/core`): a rule @@ -210,6 +227,7 @@ impl Engine { opacity: actions.get("opacity")?, resize_margin: actions.get("resize_margin")?, aspect_ratio, + min_size, }, }; state.borrow().wm.borrow_mut().add_rule(rule); diff --git a/crates/config/src/engine/support.rs b/crates/config/src/engine/support.rs index a2423d2..76bcf5e 100644 --- a/crates/config/src/engine/support.rs +++ b/crates/config/src/engine/support.rs @@ -182,6 +182,9 @@ pub(super) fn default_config() -> HashMap<String, ConfigValue> { // Re-read `init.lua` when it changes on disk, no reload key needed. // See `main.rs`'s `config_mtime`/`CONFIG_POLL_INTERVAL`. set("general.config_reload_on_write", Bool(true)); + // Maximize runs to the bottom of the screen, under a dock, rather than + // stopping above it. A top bar is still always honoured. + set("general.maximize_covers_dock", Bool(true)); set("general.smart_placement", Bool(true)); set("general.window_gap", Number(8.0)); set("general.animations", Bool(true)); |