From 3163256d2cd28eed79b78c00579d6953aad160cd Mon Sep 17 00:00:00 2001 From: iris <2+iris@noreply.localhost> Date: Sun, 6 Sep 2026 00:35:45 -0400 Subject: [PATCH] iris/android-app: opaque header background, header sizes onto dp Iris's phone report (build a9232ac): "the header buttons have nothing behind them and overlap the transcript text." Only each button's own rect painted anything, so the gaps between and around them (and the status-bar strip above) showed CLEAR_COLOR (black) one layer back, and the row's reserved height was three abs (physical-pixel) button boxes -- smaller, on a dense phone, than the dp-correct size the transcript below now uses post the previous two commits, which is what reads as overlap once the two disagree. Fixed with a HEADER_SURFACE rect stacked behind the whole button row (not just behind each button), and every non-text size in the header (button padding, row height, the report field's padding) moved from a bare number to dp(...), so the row's reserved height in the outer Span::DOWN matches what is actually painted. The list/report field already sit below the header in that same Span::DOWN, not behind it -- no stacking change needed there. Co-Authored-By: Claude Fable 5.1 --- iris/android-app/src/bench_client.rs | 46 ++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/iris/android-app/src/bench_client.rs b/iris/android-app/src/bench_client.rs index 2e98beb..beb14ca 100644 --- a/iris/android-app/src/bench_client.rs +++ b/iris/android-app/src/bench_client.rs @@ -184,7 +184,7 @@ impl AndroidAppState for BenchClient { let tree = ( top_bar, content.height(rest(2)), - report_display.height(rest(1)).pad(8), + report_display.height(rest(1)).pad(dp(8)), ) .span(Dir::DOWN) .add_strong(rsc) @@ -246,7 +246,11 @@ impl AndroidAppState for BenchClient { /// Pads the top button row by the status-bar inset -- see `top_bar`'s /// field comment. Rebuilds the row rather than mutating a stored /// `Padding` in place, since nothing here holds a handle to one. - fn on_insets_changed(&mut self, rsc: &mut AndroidRsc, insets: iris::android::LogicalInsets) { + fn on_insets_changed( + &mut self, + rsc: &mut AndroidRsc, + insets: iris::android::WindowInsets, + ) { let controls = bench_controls(rsc, insets.top); (self.top_bar)(rsc).set(controls); } @@ -254,11 +258,33 @@ impl AndroidAppState for BenchClient { type Rsc = AndroidRsc; -/// `top_pad` is the status-bar inset in logical units (0.0 until +/// The header row's own backdrop -- see `bench_controls`'s doc comment on +/// why it needs one at all. A dark neutral rather than pure black +/// (`android::render::CLEAR_COLOR`) so the row reads as a distinct panel +/// instead of a hole in the background the buttons happen to float in. +const HEADER_SURFACE: UiColor = UiColor::new(28, 28, 34, 255); + +/// `top_pad` is the status-bar inset in physical pixels (0.0 until /// `on_insets_changed` has run once) -- folded in here, rather than /// exposing the unadded builder for a caller to `.pad()` itself, because /// naming that builder's type at each call site is more machinery than a /// top-of-screen padding number is worth. +/// +/// **Backed by an opaque rect the full size of the row, not just the three +/// buttons.** Iris's phone report (docs/RUST.md's P0 box, screenshots on +/// build a9232ac): "the header buttons have nothing behind them and +/// overlap the transcript text" -- before this, only each button's own +/// `rect(...)` painted anything, so the gaps between and around them (and +/// the status-bar strip above them) showed whatever was one layer back +/// (`CLEAR_COLOR`, black), and the row's true height was three +/// physical-pixel-sized (`abs`, not `dp`) button boxes rather than the +/// density-correct size the transcript below was already using post-P0 -- +/// exactly what reads as "overlap" once the two disagree. Fixed two ways +/// together: a `HEADER_SURFACE` rect stacked behind the whole row (this +/// function), and every size below moved from a bare number (physical +/// pixels) to `dp(...)` (IRIS_TODO.md's density-independent length unit), +/// so the row's reserved height in the outer `Span::DOWN` +/// (`AndroidAppState::new`) matches what is actually painted. fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { let run_rect = rect(Color::rgb(40, 70, 40)) .on( @@ -273,7 +299,7 @@ fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { wtext("Run benchmark").size(18).text_align(Align::CENTER), ) .stack() - .pad(8) + .pad(dp(8)) .add(rsc); let copy_rect = rect(Color::rgb(50, 50, 60)) @@ -289,7 +315,7 @@ fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { wtext("Copy report").size(18).text_align(Align::CENTER), ) .stack() - .pad(8) + .pad(dp(8)) .add(rsc); let diag_rect = rect(Color::rgb(60, 45, 70)) @@ -305,12 +331,14 @@ fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { wtext("Diagnostics").size(18).text_align(Align::CENTER), ) .stack() - .pad(8) + .pad(dp(8)) .add(rsc); - (run, copy, diagnostics) - .span(Dir::RIGHT) - .height(56) + let buttons = (run, copy, diagnostics).span(Dir::RIGHT).add(rsc); + + (rect(HEADER_SURFACE), buttons) + .stack() + .height(dp(56)) .pad(Padding::top(top_pad)) .add_strong(rsc) .any()