Skip to main content

max / quasi

Budget the strip, so a long part stops eating what follows it The defect: `capped` gave a text leaf `max_width: ui.available_width()`, so a long primary took the whole row and the badge and the count after it started past the right edge and were clipped. Gone with no ellipsis and no sign they had ever been there. Now each part is drawn with the rest of the run reserved. What a part needs is measured in the frame that draws it, never remembered between frames: the standing promise is that the same description at the same width is the same picture, and a measurement carried over from a narrower frame is exactly how that stops being true. Measured rather than guessed, per widget. A token is its words plus token_padding on both sides, which is widget::token's own arithmetic; a control is a Button and really does take the style's button padding. Taking the button padding for both would have been close enough to look right and wrong enough to lose the last part in the run -- it was, for one commit. Anything this crate cannot measure makes the whole reservation None and no budget is claimed. A budget built on a guess about an unknown widget is worse than none: too small and the flexible part is elided for room nobody used. The reservation is only taken when it leaves something behind, which is quasi-tui's rule arriving from the other end. A budget that cannot fit the tail anyway would elide the one thing on screen to make room for parts that are still past the edge. The half that made all of this necessary and nearly silent: a Label re-lays a LayoutJob it is given, overwriting max_width with the Ui's available width. The budget was computed, passed, and then thrown away by egui. Laying the galley out here and building the Label from it is what makes what was measured be what is drawn.
Author: Max Johnson <me@maxj.phd> · 2026-08-18 01:01 UTC
Signed with PGP, not checked
Commit: 02a53128193a52e3e87c1aac135b5a7a397c772b
Parent: a2e86cc
13 files changed, +214 insertions, -55 deletions
M Cargo.lock +14 -14
@@ -3100,11 +3100,11 @@
3100 3100
3101 3101 [[package]]
3102 3102 name = "quasi"
3103 - version = "0.23.0"
3103 + version = "0.24.0"
3104 3104
3105 3105 [[package]]
3106 3106 name = "quasi-axum"
3107 - version = "0.23.0"
3107 + version = "0.24.0"
3108 3108 dependencies = [
3109 3109 "axum",
3110 3110 "http",
@@ -3118,7 +3118,7 @@
3118 3118
3119 3119 [[package]]
3120 3120 name = "quasi-basics"
3121 - version = "0.23.0"
3121 + version = "0.24.0"
3122 3122 dependencies = [
3123 3123 "makeover-layout",
3124 3124 "quasi-http",
@@ -3128,7 +3128,7 @@
3128 3128
3129 3129 [[package]]
3130 3130 name = "quasi-bench"
3131 - version = "0.23.0"
3131 + version = "0.24.0"
3132 3132 dependencies = [
3133 3133 "dhat",
3134 3134 "makeover",
@@ -3143,7 +3143,7 @@
3143 3143
3144 3144 [[package]]
3145 3145 name = "quasi-http"
3146 - version = "0.23.0"
3146 + version = "0.24.0"
3147 3147 dependencies = [
3148 3148 "form_urlencoded",
3149 3149 "http",
@@ -3152,7 +3152,7 @@
3152 3152
3153 3153 [[package]]
3154 3154 name = "quasi-immediate"
3155 - version = "0.23.0"
3155 + version = "0.24.0"
3156 3156 dependencies = [
3157 3157 "docengine",
3158 3158 "egui",
@@ -3162,7 +3162,7 @@
3162 3162
3163 3163 [[package]]
3164 3164 name = "quasi-router"
3165 - version = "0.23.0"
3165 + version = "0.24.0"
3166 3166 dependencies = [
3167 3167 "makeover-layout",
3168 3168 ]
@@ -3179,7 +3179,7 @@
3179 3179
3180 3180 [[package]]
3181 3181 name = "quasi-tauri"
3182 - version = "0.23.0"
3182 + version = "0.24.0"
3183 3183 dependencies = [
3184 3184 "http",
3185 3185 "quasi-http",
@@ -3190,7 +3190,7 @@
3190 3190
3191 3191 [[package]]
3192 3192 name = "quasi-tui"
3193 - version = "0.23.0"
3193 + version = "0.24.0"
3194 3194 dependencies = [
3195 3195 "docengine",
3196 3196 "makeover",
@@ -3202,7 +3202,7 @@
3202 3202
3203 3203 [[package]]
3204 3204 name = "quasi-webview"
3205 - version = "0.23.0"
3205 + version = "0.24.0"
3206 3206 dependencies = [
3207 3207 "docengine",
3208 3208 "makeover-layout",
@@ -5632,10 +5632,6 @@
5632 5632 source = "registry+https://github.com/rust-lang/crates.io-index"
5633 5633 checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
5634 5634
5635 - [[patch.unused]]
5636 - name = "quasi-type"
5637 - version = "0.1.0"
5638 -
5639 5635 [[patch.unused]]
5640 5636 name = "synckit-client"
5641 5637 version = "0.8.0"
@@ -5644,6 +5640,10 @@
5644 5640 name = "synckit-config"
5645 5641 version = "0.2.0"
5646 5642
5643 + [[patch.unused]]
5644 + name = "quasi-type"
5645 + version = "0.1.0"
5646 +
5647 5647 [[patch.unused]]
5648 5648 name = "kberg"
5649 5649 version = "0.1.0"
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-axum"
3 - version = "0.23.0"
3 + version = "0.24.0"
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,14 +13,14 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.23.0" }
17 - quasi-http = { path = "../quasi-http", version = "0.23.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.24.0" }
17 + quasi-http = { path = "../quasi-http", version = "0.24.0" }
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.23.0" }
23 + quasi-webview = { path = "../quasi-webview", version = "0.24.0" }
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,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-basics"
3 - version = "0.23.0"
3 + version = "0.24.0"
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,12 +13,12 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.23.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.24.0" }
17 17 makeover-layout = "0.28.2"
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.23.0" }
24 - quasi-http = { path = "../quasi-http", version = "0.23.0" }
23 + quasi-webview = { path = "../quasi-webview", version = "0.24.0" }
24 + quasi-http = { path = "../quasi-http", version = "0.24.0" }
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-bench"
3 - version = "0.23.0"
3 + version = "0.24.0"
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,13 +22,13 @@
22 22 count = ["dep:dhat"]
23 23
24 24 [dependencies]
25 - quasi-router = { path = "../quasi-router", version = "0.23.0" }
26 - quasi-webview = { path = "../quasi-webview", version = "0.23.0" }
27 - quasi-tui = { path = "../quasi-tui", version = "0.23.0" }
25 + quasi-router = { path = "../quasi-router", version = "0.24.0" }
26 + quasi-webview = { path = "../quasi-webview", version = "0.24.0" }
27 + quasi-tui = { path = "../quasi-tui", version = "0.24.0" }
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.23.0" }
31 + quasi-http = { path = "../quasi-http", version = "0.24.0" }
32 32 makeover-layout = "0.28.2"
33 33 makeover-tui = { version = "0.27.0", features = ["theme"] }
34 34 # Only to load a bundled theme file. `makeover_tui::Theme` is `#[non_exhaustive]`,
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-http"
3 - version = "0.23.0"
3 + version = "0.24.0"
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,6 +13,6 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.23.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.24.0" }
17 17 http = "1.3.1"
18 18 form_urlencoded = "1.2.2"
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-immediate"
3 - version = "0.23.0"
3 + version = "0.24.0"
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,7 +12,7 @@
12 12 categories = ["gui"]
13 13
14 14 [dependencies]
15 - quasi-router = { path = "../quasi-router", version = "0.23.0" }
15 + quasi-router = { path = "../quasi-router", version = "0.24.0" }
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,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-router"
3 - version = "0.23.0"
3 + version = "0.24.0"
4 4 description = "Host-agnostic router: a request in, a renderer-agnostic description out"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-tauri"
3 - version = "0.23.0"
3 + version = "0.24.0"
4 4 description = "The Tauri custom-protocol host adapter for quasi-router: a webview request in, a rendered description out"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,8 +13,8 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.23.0" }
17 - quasi-http = { path = "../quasi-http", version = "0.23.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.24.0" }
17 + quasi-http = { path = "../quasi-http", version = "0.24.0" }
18 18 http = "1.3.1"
19 19 # Default features off: this crate uses tauri's protocol registration and its
20 20 # blocking pool, and nothing else. An app brings the features it wants, and the
@@ -22,7 +22,7 @@
22 22 tauri = { version = "2.11.5", default-features = false }
23 23
24 24 [dev-dependencies]
25 - quasi-webview = { path = "../quasi-webview", version = "0.23.0" }
25 + quasi-webview = { path = "../quasi-webview", version = "0.24.0" }
26 26 # The doctest names a concrete `Runtime`, and `Wry` is behind a default feature
27 27 # this crate does not otherwise ask for. Only the example needs it: nothing in
28 28 # the test module builds a window, which is what keeps them runnable with no