A horizontal swipe commits on a fling; App::overlay_namespace; flat Quick Settings slots in the default theme; the on-screen keyboard's rows twice as far apart, with presses between keys kept; LTK_PERF_RASTER
CI / build + test (push) Canceled after 0s
CI / cargo audit (push) Canceled after 0s

Flings. A horizontal swipe committed only past `swipe_horizontal_threshold` of the surface width, so a quick flick that stopped short, the usual way to turn a page on a phone, snapped back. The new `input/gesture/fling.rs` holds a `FlingTracker` that measures the finger's speed along one axis over the last 100 ms from the events' own timestamps, so a finger that rested before lifting reads as still. `GestureState` keeps one for the x axis, `fling_x`, cleared on every press; the touch handler feeds it on down, motion and up with the `wl_touch` time, which it used to ignore. On release a horizontal swipe also commits when the finger leaves at 500 logical px/s or more in the direction of travel after at least 24 px, and does not commit when it leaves that fast the other way, whatever the distance; both thresholds scale with the surface. Pointer drags and the vertical swipes keep the distance rule, and the gesture tests, which never feed the tracker, are unchanged. Two tests cover the speed and a rest before lifting.
`App::overlay_namespace`. Every layer overlay was created with the namespace `ltk-overlay`, so a compositor could not tell one panel from another. The new method returns the namespace of overlay `id`, read when its surface is created, and `None`, the default, keeps `ltk-overlay`. It follows `overlay_title` and `overlay_opaque_region` and breaks no app. Crustace names its Quick Settings and launcher overlays with it, and forge draws a blurred backdrop behind them.
Flat Quick Settings slots. The default theme gains `surface-qs-tile`, `surface-qs-tile-active`, `surface-qs-slider-track` and `surface-qs-slider-fill` in both modes: a solid translucent fill, white or navy for the tiles and tracks and cyan for the active tile and the fill, with no shadows, no inset shadows and no gradients. The glass slots the panel used put a blurred shadow, one to five inset shadows, some with blend modes, and a gradient under each of its nineteen surfaces, all rasterised on every frame of its slide. The shared slots are untouched, so the dock and other applications look as before.
The on-screen keyboard. The rows are now `ROW_GAP`, twice `GAP`, apart, 12 logical px against the 6 between keys; `height` counts it, so the panel grows by 18 to 24 px depending on its rows and a host that reserves its height follows. A press between keys, which the wider gap would have made more common, no longer goes nowhere: `key_at` gives it to the nearest key within one row gap.
`LTK_PERF_RASTER`. With it set, every GLES raster, full, partial or subsurface, logs its surface size, the time to submit and, after a `glFinish`, the time until the GPU finished. The `glFinish` stalls the pipeline, so it is for measuring only; it gave the cost of the old Quick Settings panel, 27 to 40 ms a raster on the Librem 5 with peaks of 57 to 143 ms.
This commit is contained in:
2026-09-30 10:17:22 +02:00
parent a0ceef51ef
commit 88f69ebffe
10 changed files with 218 additions and 14 deletions
+34
View File
@@ -37,6 +37,40 @@ fn perf_warn_enabled() -> bool
)
}
/// Wall time of one GLES raster, split at submission and at GPU completion.
/// Opt-in via `LTK_PERF_RASTER`; the `glFinish` it adds stalls the pipeline.
pub( crate ) struct RasterTrace
{
start: Instant,
}
impl RasterTrace
{
pub( crate ) fn begin() -> Option<Self>
{
static ENABLED: OnceLock<bool> = OnceLock::new();
let enabled = *ENABLED.get_or_init( ||
std::env::var( "LTK_PERF_RASTER" )
.map( |v| !v.is_empty() && v != "0" )
.unwrap_or( false )
);
enabled.then( || Self { start: Instant::now() } )
}
pub( crate ) fn end( self, gl: &glow::Context, label: &str, pw: u32, ph: u32 )
{
use glow::HasContext;
let submitted = self.start.elapsed();
unsafe { gl.finish(); }
let done = self.start.elapsed();
eprintln!(
"[ltk][raster] {label} {pw}x{ph} cpu={:.2}ms gpu_done={:.2}ms",
submitted.as_secs_f64() * 1000.0,
done.as_secs_f64() * 1000.0,
);
}
}
/// Per-runtime performance-guard state. Lives on `AppData`.
pub struct PerfState
{