0.69.1: an overlay does not stack on itself
`900865dd`. A binding that opens an overlay is matched before any layer is
drawn and an open overlay does not suppress it, so `f1 -> /help -> Over` opened
a second help over the first and five presses cost five Escapes. Every press is
a fresh route call, so it was not even the same screen value being duplicated.
The brief offered three answers and this is the second, at no cost to the
vocabulary, which is why it is a patch and not a minor.
What decided it: a webview never had the bug. `Outcome::Over` lands in one
overlay container and replaces what is in it, while quasi-immediate and
quasi-tui both pushed unconditionally. One description behaving two ways across
three hosts is the drift this stack exists to end, and the host that was already
right says what right is.
The identity was already in hand. The brief said deduplicating needs something
to deduplicate on and that a `Screen` has no identity, reading that as the
absence `1d4f288e` and `720c117b` circle. It is not the same absence: `apply` is
handed the `Request` it fired, so the runtime can record what opened the top
layer without the description saying anything. That is `here`'s shape for a
layer that is not a place, which is why `remember` is not called for one.
`Runtime::over`, with `Layer::over` saving the outer one on the way down so a
nested overlay restores it rather than losing it. The guard is the request and
not the screen, because two screens from two calls are equal by accident. Top
layer only, so a confirm over a palette still stacks. Cleared wherever the stack
is dropped wholesale: `Outcome::Screen`, and a call carrying `Action::navigates`.
The toggling binding is refused for now on the standing rule rather than on
taste: `Act::toggles` has one consumer, audiofiles' F1, and one consumer is a
shape. The dedupe already fixes the defect that was filed; what it does not
restore is F1 closing help, which is a nicety.
Four tests, two per stacking renderer, each checked to fail with the guard
removed.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
16 files changed,
+268 insertions,
-51 deletions
| 3425 |
3425 |
|
|
| 3426 |
3426 |
|
[[package]]
|
| 3427 |
3427 |
|
name = "quasi"
|
| 3428 |
|
- |
version = "0.68.0"
|
|
3428 |
+ |
version = "0.69.1"
|
| 3429 |
3429 |
|
|
| 3430 |
3430 |
|
[[package]]
|
| 3431 |
3431 |
|
name = "quasi-axum"
|
| 3432 |
|
- |
version = "0.68.0"
|
|
3432 |
+ |
version = "0.69.1"
|
| 3433 |
3433 |
|
dependencies = [
|
| 3434 |
3434 |
|
"axum",
|
| 3435 |
3435 |
|
"http",
|
| 3443 |
3443 |
|
|
| 3444 |
3444 |
|
[[package]]
|
| 3445 |
3445 |
|
name = "quasi-basics"
|
| 3446 |
|
- |
version = "0.68.0"
|
|
3446 |
+ |
version = "0.69.1"
|
| 3447 |
3447 |
|
dependencies = [
|
| 3448 |
3448 |
|
"makeover-layout",
|
| 3449 |
3449 |
|
"quasi-http",
|
| 3453 |
3453 |
|
|
| 3454 |
3454 |
|
[[package]]
|
| 3455 |
3455 |
|
name = "quasi-bench"
|
| 3456 |
|
- |
version = "0.68.0"
|
|
3456 |
+ |
version = "0.69.1"
|
| 3457 |
3457 |
|
dependencies = [
|
| 3458 |
3458 |
|
"dhat",
|
| 3459 |
3459 |
|
"makeover",
|
| 3468 |
3468 |
|
|
| 3469 |
3469 |
|
[[package]]
|
| 3470 |
3470 |
|
name = "quasi-http"
|
| 3471 |
|
- |
version = "0.68.0"
|
|
3471 |
+ |
version = "0.69.1"
|
| 3472 |
3472 |
|
dependencies = [
|
| 3473 |
3473 |
|
"form_urlencoded",
|
| 3474 |
3474 |
|
"http",
|
| 3477 |
3477 |
|
|
| 3478 |
3478 |
|
[[package]]
|
| 3479 |
3479 |
|
name = "quasi-immediate"
|
| 3480 |
|
- |
version = "0.68.0"
|
|
3480 |
+ |
version = "0.69.1"
|
| 3481 |
3481 |
|
dependencies = [
|
| 3482 |
3482 |
|
"docengine",
|
| 3483 |
3483 |
|
"egui",
|
| 3488 |
3488 |
|
|
| 3489 |
3489 |
|
[[package]]
|
| 3490 |
3490 |
|
name = "quasi-notifs"
|
| 3491 |
|
- |
version = "0.68.0"
|
|
3491 |
+ |
version = "0.69.1"
|
| 3492 |
3492 |
|
dependencies = [
|
| 3493 |
3493 |
|
"quasi-router",
|
| 3494 |
3494 |
|
"synckit-config",
|
| 3496 |
3496 |
|
|
| 3497 |
3497 |
|
[[package]]
|
| 3498 |
3498 |
|
name = "quasi-router"
|
| 3499 |
|
- |
version = "0.68.0"
|
|
3499 |
+ |
version = "0.69.1"
|
| 3500 |
3500 |
|
dependencies = [
|
| 3501 |
3501 |
|
"makeover-layout",
|
| 3502 |
3502 |
|
]
|
| 3513 |
3513 |
|
|
| 3514 |
3514 |
|
[[package]]
|
| 3515 |
3515 |
|
name = "quasi-tauri"
|
| 3516 |
|
- |
version = "0.68.0"
|
|
3516 |
+ |
version = "0.69.1"
|
| 3517 |
3517 |
|
dependencies = [
|
| 3518 |
3518 |
|
"http",
|
| 3519 |
3519 |
|
"quasi-http",
|
| 3526 |
3526 |
|
|
| 3527 |
3527 |
|
[[package]]
|
| 3528 |
3528 |
|
name = "quasi-tui"
|
| 3529 |
|
- |
version = "0.68.0"
|
|
3529 |
+ |
version = "0.69.1"
|
| 3530 |
3530 |
|
dependencies = [
|
| 3531 |
3531 |
|
"docengine",
|
| 3532 |
3532 |
|
"makeover",
|
| 3539 |
3539 |
|
|
| 3540 |
3540 |
|
[[package]]
|
| 3541 |
3541 |
|
name = "quasi-webview"
|
| 3542 |
|
- |
version = "0.68.0"
|
|
3542 |
+ |
version = "0.69.1"
|
| 3543 |
3543 |
|
dependencies = [
|
| 3544 |
3544 |
|
"docengine",
|
| 3545 |
3545 |
|
"makeover-layout",
|
| 6211 |
6211 |
|
"winnow 1.0.4",
|
| 6212 |
6212 |
|
]
|
| 6213 |
6213 |
|
|
| 6214 |
|
- |
[[patch.unused]]
|
| 6215 |
|
- |
name = "quasi-type"
|
| 6216 |
|
- |
version = "0.1.0"
|
| 6217 |
|
- |
|
| 6218 |
|
- |
[[patch.unused]]
|
| 6219 |
|
- |
name = "synckit-client"
|
| 6220 |
|
- |
version = "0.9.1"
|
| 6221 |
|
- |
|
| 6222 |
6214 |
|
[[patch.unused]]
|
| 6223 |
6215 |
|
name = "kberg"
|
| 6224 |
6216 |
|
version = "0.1.0"
|
| 6234 |
6226 |
|
[[patch.unused]]
|
| 6235 |
6227 |
|
name = "tagtree"
|
| 6236 |
6228 |
|
version = "0.4.1"
|
|
6229 |
+ |
|
|
6230 |
+ |
[[patch.unused]]
|
|
6231 |
+ |
name = "synckit-client"
|
|
6232 |
+ |
version = "0.9.1"
|
|
6233 |
+ |
|
|
6234 |
+ |
[[patch.unused]]
|
|
6235 |
+ |
name = "quasi-type"
|
|
6236 |
+ |
version = "0.1.0"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.69.0"
|
|
3 |
+ |
version = "0.69.1"
|
| 4 |
4 |
|
description = "The axum host adapter for quasi-router: an HTTP request in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.69.0" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.69.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.69.1" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.69.1" }
|
| 18 |
18 |
|
axum = "0.8.8"
|
| 19 |
19 |
|
http = "1.3.1"
|
| 20 |
20 |
|
tokio = { version = "1.50.0", features = ["rt"] }
|
| 21 |
21 |
|
|
| 22 |
22 |
|
[dev-dependencies]
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.69.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.69.1" }
|
| 24 |
24 |
|
tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
|
| 25 |
25 |
|
tower = { version = "0.5.3", features = ["util"] }
|
| 26 |
26 |
|
http-body-util = "0.1.3"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-basics"
|
| 3 |
|
- |
version = "0.69.0"
|
|
3 |
+ |
version = "0.69.1"
|
| 4 |
4 |
|
description = "The first-party widget set: named assemblies of primitives, shared across our apps"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.69.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.69.1" }
|
| 17 |
17 |
|
makeover-layout = "0.35.0"
|
| 18 |
18 |
|
|
| 19 |
19 |
|
[dev-dependencies]
|
| 20 |
20 |
|
# A widget's guarantees are claims about what a renderer draws, so they are
|
| 21 |
21 |
|
# tested against a real one rather than by walking the tree the assembly just
|
| 22 |
22 |
|
# built. The webview is the renderer that recognises names today.
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.69.0" }
|
| 24 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.69.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.69.1" }
|
|
24 |
+ |
quasi-http = { path = "../quasi-http", version = "0.69.1" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.69.0"
|
|
3 |
+ |
version = "0.69.1"
|
| 4 |
4 |
|
description = "What a described screen costs to render, in time and in allocations"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 22 |
22 |
|
count = ["dep:dhat"]
|
| 23 |
23 |
|
|
| 24 |
24 |
|
[dependencies]
|
| 25 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.69.0" }
|
| 26 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.69.0" }
|
| 27 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.69.0" }
|
|
25 |
+ |
quasi-router = { path = "../quasi-router", version = "0.69.1" }
|
|
26 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.69.1" }
|
|
27 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.69.1" }
|
| 28 |
28 |
|
# `Serves` is the trait carrying `screen` and `fragment`, which is what the
|
| 29 |
29 |
|
# webview is measured through. Taken directly rather than through quasi-webview
|
| 30 |
30 |
|
# because a bench calling a trait method should name the trait it calls.
|
| 31 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.69.0" }
|
|
31 |
+ |
quasi-http = { path = "../quasi-http", version = "0.69.1" }
|
| 32 |
32 |
|
makeover-layout = "0.35.0"
|
| 33 |
33 |
|
makeover-tui = { version = "0.35.0", features = ["theme"] }
|
| 34 |
34 |
|
# Only to load a bundled theme file. `makeover_tui::Theme` is `#[non_exhaustive]`,
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-http"
|
| 3 |
|
- |
version = "0.69.0"
|
|
3 |
+ |
version = "0.69.1"
|
| 4 |
4 |
|
description = "The http-shaped seam quasi's webview host adapters share: decoding in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.69.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.69.1" }
|
| 17 |
17 |
|
http = "1.3.1"
|
| 18 |
18 |
|
form_urlencoded = "1.2.2"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-immediate"
|
| 3 |
|
- |
version = "0.69.0"
|
|
3 |
+ |
version = "0.69.1"
|
| 4 |
4 |
|
edition = "2024"
|
| 5 |
5 |
|
description = "The immediate-mode renderer for quasi-router: a described screen in, an egui frame out. Immediate mode is the constraint that matters, not the library."
|
| 6 |
6 |
|
license = "MIT"
|
| 12 |
12 |
|
categories = ["gui"]
|
| 13 |
13 |
|
|
| 14 |
14 |
|
[dependencies]
|
| 15 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.69.0" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.69.1" }
|
| 16 |
16 |
|
# The node drawing, which is the makeover layer's and not this crate's. Every
|
| 17 |
17 |
|
# widget here that is not a container comes from it: a screen walk that painted
|
| 18 |
18 |
|
# its own meter would be the divergence the suite exists to end, one copy per
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-notifs"
|
| 3 |
|
- |
version = "0.69.0"
|
|
3 |
+ |
version = "0.69.1"
|
| 4 |
4 |
|
description = "Declared notification kinds and the registry that holds them: what a notification says and what it is for, apart from how it reaches a person"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 24 |
24 |
|
describe = ["dep:quasi-router"]
|
| 25 |
25 |
|
|
| 26 |
26 |
|
[dependencies]
|
| 27 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.69.0", optional = true }
|
|
27 |
+ |
quasi-router = { path = "../quasi-router", version = "0.69.1", optional = true }
|
| 28 |
28 |
|
synckit-config = { git = "https://makenot.work/git/max/synckit.git", version = "0.2", optional = true }
|