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.
110 lines
3.9 KiB
YAML
110 lines
3.9 KiB
YAML
# Gitea Actions CI for ltk.
|
|
#
|
|
# 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, 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. 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/`
|
|
# by default, but `.gitea/workflows/` is preferred for clarity.
|
|
|
|
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [ main ]
|
|
pull_request:
|
|
branches: [ main ]
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
# Surface the MSRV that `Cargo.toml` declares so the runner pins the
|
|
# toolchain to the same version the package is published against.
|
|
RUST_TOOLCHAIN: "1.85"
|
|
|
|
jobs:
|
|
test:
|
|
name: build + test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install system dependencies
|
|
# ltk links against Wayland / EGL / xkbcommon at compile time
|
|
# through smithay-client-toolkit, wayland-egl and khronos-egl.
|
|
# The runner image does not ship these headers by default.
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y --no-install-recommends \
|
|
libwayland-dev libegl-dev libxkbcommon-dev pkg-config
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
|
components: clippy
|
|
|
|
- name: Cache cargo registry and target
|
|
uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Build
|
|
run: cargo build --workspace --all-targets --features test-support
|
|
|
|
- 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
|
|
# against directly. The script discovers the freshly-built rlib
|
|
# from the `Build` step's `target/debug/` and runs `rustdoc --test`
|
|
# over each `.md`. Snippets are `no_run` so this only typechecks —
|
|
# the goal is to catch API drift, not integration-test the runtime.
|
|
- name: Markdown doctests
|
|
run: ./scripts/doctest-md.sh
|
|
|
|
- name: Style check
|
|
run: ./scripts/style-check.sh
|
|
|
|
audit:
|
|
name: cargo audit
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Cache cargo registry
|
|
uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Install cargo-audit
|
|
# `--locked` so the audit tool itself does not pick up an
|
|
# advisory-affected transitive dep at install time.
|
|
run: cargo install cargo-audit --locked
|
|
|
|
- name: Run cargo audit
|
|
# Default behaviour: fail on any active advisory. Add
|
|
# `--ignore RUSTSEC-...` here for advisories that have a
|
|
# documented mitigation upstream we cannot avoid yet.
|
|
run: cargo audit
|