diff --git a/iris/android-app/src/app_log.rs b/iris/android-app/src/app_log.rs index 2b83147..7a41589 100644 --- a/iris/android-app/src/app_log.rs +++ b/iris/android-app/src/app_log.rs @@ -27,7 +27,13 @@ pub fn install(max_level: log::LevelFilter) { .with_max_level(max_level) .with_tag("iris-android-app"), ); - if log_ring::install_process_logger(Box::new(inner), max_level).is_err() { + if log_ring::install_process_logger( + Box::new(inner), + max_level, + iris::diagnostics::trace_enabled, + ) + .is_err() + { // Not a panic: a logger already installed means logging works, // just without the ring, and taking the app down over a // diagnostic would be worse than the diagnostic being missing. diff --git a/iris/android-app/src/bench_client.rs b/iris/android-app/src/bench_client.rs index 0c59ecf..78ac2c9 100644 --- a/iris/android-app/src/bench_client.rs +++ b/iris/android-app/src/bench_client.rs @@ -468,14 +468,21 @@ const HEADER_SURFACE: UiColor = UiColor::new(28, 28, 34, 255); /// The size every label in the header row is drawn at. /// /// One constant for all four rather than a number per button, because the -/// whole row has to be sized together: it was 18 with three controls, and -/// adding the trace switch made four labels overlap each other on a -/// 1080px screen. Shrinking *one* label to fit is what the UI rules -/// forbid -- a label a different size from its neighbours for a reason the -/// reader cannot see; changing the row's own type size is a layout -/// decision, and all four still match. Whoever adds a fifth control has -/// one number to reconsider rather than four. -const HEADER_TEXT: f32 = 13.0; +/// whole row has to be sized together. Adding the trace switch made four +/// controls too wide for one row at the size three had used (18), and an +/// earlier pass shrank this constant to 13 to make them fit -- exactly +/// what UI_RULES forbids ("never shrink text to make it fit": a label a +/// different size from its neighbours elsewhere in the app for a reason +/// the reader cannot see). The fix is [`bench_controls`]'s two rows +/// instead, which leaves room to put this back. Whoever adds a fifth +/// control reconsiders the row split, not this number. +const HEADER_TEXT: f32 = 18.0; + +/// The height of one row of header controls, in dp. `bench_controls` now +/// stacks two of these, so this is the one number to change if a control's +/// own padding ever changes instead of `dp(56)` and `dp(112)` needing to +/// be kept in sync by hand. +const HEADER_ROW_HEIGHT_DP: f32 = 56.0; fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { let run_rect = rect(Color::rgb(40, 70, 40)) @@ -499,8 +506,8 @@ fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { let copy_rect = rect(Color::rgb(50, 50, 60)) .on( CursorSense::click(), - |ctx: EventIdCtx<'_, Rsc, _, _>, _rsc: &mut Rsc| { - ctx.state.copy_report(); + |ctx: EventIdCtx<'_, Rsc, _, _>, rsc: &mut Rsc| { + ctx.state.copy_report(rsc); }, ) .label("Copy report"); @@ -566,11 +573,19 @@ fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget { .pad(dp(8)) .add(rsc); - let buttons = (run, copy, diagnostics, trace).span(Dir::RIGHT).add(rsc); + // Two rows rather than one: four controls at the restored `HEADER_TEXT` + // no longer fit a 1080px-wide row (that was the shrink this replaces -- + // see the constant's own doc). Grouped by what they act on: the first + // row starts a benchmark and copies its result; the second is the + // diagnostics pane and the switch that decides what it will contain + // next time. + let row1 = (run, copy).span(Dir::RIGHT).add(rsc); + let row2 = (diagnostics, trace).span(Dir::RIGHT).add(rsc); + let buttons = (row1, row2).span(Dir::DOWN).add(rsc); (rect(HEADER_SURFACE), buttons) .stack() - .height(dp(56)) + .height(dp(2.0 * HEADER_ROW_HEIGHT_DP)) .pad(Padding::top(top_pad)) .add_strong(rsc) .any() @@ -672,23 +687,38 @@ impl BenchClient { log::info!("iris keyboard diagnostics:\n{report}"); } - fn copy_report(&mut self) { - let Some(report) = self.last_report.clone() else { - log::info!("iris bench report: nothing to copy -- run the benchmark first"); - return; - }; + /// Always copies something, and never depends on `Diagnostics` or + /// `Run benchmark` having been pressed first (docs/IRIS_TODO.md, + /// 2026-09-07 night: "the copy report button seemed impossible to hit + /// until I hit the diagnostics one" -- it was silently declining + /// instead of reporting where it had failed, the UI_RULES failure "a + /// failure is reported where it happened"). With no benchmark run yet, + /// it copies the diagnostics pane's own text instead, with a first + /// line saying so -- `diagnostics_text` needs no prior button press + /// either, so this is never actually empty-handed. + fn copy_report(&mut self, rsc: &mut Rsc) { let Some(platform) = &self.platform else { log::info!("iris bench report: no platform handle, can't reach the clipboard"); return; }; - // The ring goes on the clipboard, not into the pane: the pane is - // on screen and a thousand log lines in it would bury the report - // somebody pressed the button for, while the clipboard is going - // straight into a message to be read elsewhere. + let report = match self.last_report.clone() { + Some(report) => report, + None => format!( + "no benchmark has run yet -- these are the diagnostics instead:\n\n{}", + self.diagnostics_text(rsc) + ), + }; + // The ring's tail goes on the clipboard, not the full ring, and + // not into the on-screen pane either: the full ring can be over a + // thousand lines with tracing on, and pasting that into a phone's + // message box was Iris's own "causes a lot of lag" report. The + // full ring is still reachable through Dev Updater's Runtime tab + // (`devlog`'s provider reads the same ring) -- this only bounds + // what gets inlined here. let report = format!( "{report}\n\n=== app log ({}) ===\n{}", crate::app_log::ring().summary(), - crate::app_log::ring().to_text() + crate::app_log::ring().tail_text(client_core::log_ring::COPY_REPORT_TAIL_LINES) ); if platform.copy_to_clipboard("iris bench report", &report) { log::info!("iris bench report: copied to clipboard");