render, types, ci: resolution-time dp with per-canvas density, bounded GLES image cache, clippy gate, backend capability matrix
Length::dp no longer collapses to absolute pixels at construction: the design value travels in a new LengthBase::Dp variant and the density multiplication happens when the length is resolved. Previously dp( n ) baked in whatever density() returned at view-build time, so correctness across output changes depended on the view being rebuilt after set_density and in that order; now a density change is picked up by the very next paint with no reconstruction. Length::resolve keeps its signature (process density), and the new Length::resolve_with_density takes an explicit factor. dp becomes const in the bargain. Density also becomes overridable per canvas, the first step towards surface-local responsive state. SoftwareCanvas and GlesCanvas carry a density: Option<f32> analogous to the layout_viewport introduced for sub-canvas fluid resolution: None means "use the process global", Canvas::set_density pins a local factor, and sub-canvases inherit it. All canvas-routed resolution honours it — geom_px / font_px for stock-widget design pixels, and the new Canvas::resolve_geom / resolve_font for explicit Length values, which every widget now uses in place of the raw l.resolve( canvas.viewport_layout(), EM ) pattern (row, column, wrap_grid, spacer, container, separator, button, text, rich_text, text_edit, list_item, vslider, image, and the container draw path). Overlay sizing keeps resolving against the main surface with the global density, which is what it describes. New tests cover explicit-density resolution, resolution-time application, the local-over-global override and sub-canvas inheritance. The GLES image texture cache is now bounded. It was content-keyed but unbounded and never evicted, so a stream of distinct buffers — a photo carousel, video thumbnails — grew GPU memory for the lifetime of the canvas. The cache now tracks an estimated byte total (RGBA8, w × h × 4) against a 32 MiB budget and evicts least-recently-drawn textures on insert; the most recent entry is never evicted, so a single texture larger than the whole budget still draws and simply owns the cache until replaced. Drop-time cleanup is unchanged: drain deletes whatever the map holds. CI gains a Clippy step (workspace, all targets, test-support, -D warnings) sharing the build cache of the test job, with make clippy mirroring the invocation locally and CONTRIBUTING listing it. Run make clippy locally before pushing the first time — the gate has not seen the tree yet and pre-existing lints will fail CI until addressed. docs/backends.md formalises the software/GLES capability matrix that was previously scattered across per-method rustdoc: parity set (fills, strokes, text, images, paths, path clips), graceful degradations on software (flat-fill gradients, no shadows, no backdrop blur, hard bottom edge), GPU-only features (external textures), the shared Oklab-fallback limitation, and the cross-backend blit panic. Linked from README, onboarding and architecture's known-gaps list, which now states the parity gaps explicitly. The dp/density prose in architecture.md, lib.rs and the Length rustdoc is updated for resolution-time semantics and the per-canvas override.
This commit is contained in:
@@ -3,14 +3,16 @@
|
||||
# Runs on every push and pull request against `main`. Two independent
|
||||
# jobs share the cache layer but otherwise execute in parallel:
|
||||
#
|
||||
# - `test` builds the workspace and runs the full test corpus.
|
||||
# - `test` builds the workspace, runs the full test corpus and lints
|
||||
# with Clippy (`-D warnings`, sharing the build cache).
|
||||
# - `audit` runs `cargo audit` against the RustSec advisory database to
|
||||
# catch dependency CVEs without waiting for a human to remember to run
|
||||
# it locally.
|
||||
#
|
||||
# Note: ltk uses Modified Allman style (not rustfmt's default), so there
|
||||
# is no `cargo fmt --check` step here on purpose. If rustfmt ever ships
|
||||
# a stable Allman config, add a third `fmt` job.
|
||||
# a stable Allman config, add a third `fmt` job. Clippy is unaffected by
|
||||
# the formatting style — it lints semantics, not layout.
|
||||
#
|
||||
# Compatible syntax with GitHub Actions, so swapping host providers does
|
||||
# not require touching this file. Gitea also reads `.github/workflows/`
|
||||
@@ -51,6 +53,7 @@ jobs:
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
components: clippy
|
||||
|
||||
- name: Cache cargo registry and target
|
||||
uses: Swatinem/rust-cache@v2
|
||||
@@ -61,6 +64,13 @@ jobs:
|
||||
- name: Test
|
||||
run: cargo test --workspace --all-targets --features test-support
|
||||
|
||||
- name: Clippy
|
||||
# Same flags as the build so the artifact cache is reused and
|
||||
# test code is linted too. Warnings are errors: an allow with a
|
||||
# justification at the offending site is the escape hatch, not
|
||||
# a CI-level mute.
|
||||
run: cargo clippy --workspace --all-targets --features test-support -- -D warnings
|
||||
|
||||
# External-Markdown doctests. `cargo test --doc` only sees doctests
|
||||
# inside `src/`; the cookbook and widget reference under `docs/`
|
||||
# are stand-alone Markdown files that rustdoc has to be invoked
|
||||
|
||||
Reference in New Issue
Block a user