iris-android-app: Copy report always copies; restore the header's text size
Two of the phone's 2026-09-07 night reports (docs/IRIS_TODO.md):
Copy report used to silently decline ("nothing to copy -- run the
benchmark first") whenever no benchmark had run yet, which read on the
phone as the button being unhittable until Diagnostics was pressed first
-- UI_RULES's "a failure is reported where it happened" failure, since it
declined with no visible effect. It now always copies something: with no
benchmark run yet it copies the diagnostics pane's own text instead (which
needs no prior button press either), with a first line saying so, and in
every case appends the ring's tail (LogRing::tail_text,
COPY_REPORT_TAIL_LINES lines, previous commit) instead of the whole ring,
which was the other half of "causes a lot of lag" pasting it into a
message box. app_log.rs wires iris::diagnostics::trace_enabled into the
ring filter that commit added.
The header's four controls no longer fit one row at HEADER_TEXT = 18, and
a previous agent had shrunk it to 13 to make room -- exactly what
UI_RULES forbids (never shrink text to fit a layout). Restored to 18 and
split bench_controls into two rows instead (run+copy, diagnostics+trace),
doubling the header's own height rather than the outer layout's reserved
space (top_bar already sizes to its own content). Checked on this
checkout's emulator: ui-trace's --field box shows two clean, non-
overlapping rows, and a screenshot shows the restored size reading
clearly; a Copy report tap with nothing run yet now logs "copied to
clipboard" instead of declining.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
7485d78d50
commit
b8ea723718
2 files changed
+59
-23
No files matched your search
@@ -27,7 +27,13 @@ pub fn install(max_level: log::LevelFilter) {
|
|||||||
.with_max_level(max_level)
|
.with_max_level(max_level)
|
||||||
.with_tag("iris-android-app"),
|
.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,
|
// Not a panic: a logger already installed means logging works,
|
||||||
// just without the ring, and taking the app down over a
|
// just without the ring, and taking the app down over a
|
||||||
// diagnostic would be worse than the diagnostic being missing.
|
// diagnostic would be worse than the diagnostic being missing.
|
||||||
|
|||||||
@@ -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.
|
/// The size every label in the header row is drawn at.
|
||||||
///
|
///
|
||||||
/// One constant for all four rather than a number per button, because the
|
/// 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
|
/// whole row has to be sized together. Adding the trace switch made four
|
||||||
/// adding the trace switch made four labels overlap each other on a
|
/// controls too wide for one row at the size three had used (18), and an
|
||||||
/// 1080px screen. Shrinking *one* label to fit is what the UI rules
|
/// earlier pass shrank this constant to 13 to make them fit -- exactly
|
||||||
/// forbid -- a label a different size from its neighbours for a reason the
|
/// what UI_RULES forbids ("never shrink text to make it fit": a label a
|
||||||
/// reader cannot see; changing the row's own type size is a layout
|
/// different size from its neighbours elsewhere in the app for a reason
|
||||||
/// decision, and all four still match. Whoever adds a fifth control has
|
/// the reader cannot see). The fix is [`bench_controls`]'s two rows
|
||||||
/// one number to reconsider rather than four.
|
/// instead, which leaves room to put this back. Whoever adds a fifth
|
||||||
const HEADER_TEXT: f32 = 13.0;
|
/// 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 {
|
fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget {
|
||||||
let run_rect = rect(Color::rgb(40, 70, 40))
|
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))
|
let copy_rect = rect(Color::rgb(50, 50, 60))
|
||||||
.on(
|
.on(
|
||||||
CursorSense::click(),
|
CursorSense::click(),
|
||||||
|ctx: EventIdCtx<'_, Rsc, _, _>, _rsc: &mut Rsc| {
|
|ctx: EventIdCtx<'_, Rsc, _, _>, rsc: &mut Rsc| {
|
||||||
ctx.state.copy_report();
|
ctx.state.copy_report(rsc);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.label("Copy report");
|
.label("Copy report");
|
||||||
@@ -566,11 +573,19 @@ fn bench_controls(rsc: &mut Rsc, top_pad: f32) -> StrongWidget {
|
|||||||
.pad(dp(8))
|
.pad(dp(8))
|
||||||
.add(rsc);
|
.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)
|
(rect(HEADER_SURFACE), buttons)
|
||||||
.stack()
|
.stack()
|
||||||
.height(dp(56))
|
.height(dp(2.0 * HEADER_ROW_HEIGHT_DP))
|
||||||
.pad(Padding::top(top_pad))
|
.pad(Padding::top(top_pad))
|
||||||
.add_strong(rsc)
|
.add_strong(rsc)
|
||||||
.any()
|
.any()
|
||||||
@@ -672,23 +687,38 @@ impl BenchClient {
|
|||||||
log::info!("iris keyboard diagnostics:\n{report}");
|
log::info!("iris keyboard diagnostics:\n{report}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_report(&mut self) {
|
/// Always copies something, and never depends on `Diagnostics` or
|
||||||
let Some(report) = self.last_report.clone() else {
|
/// `Run benchmark` having been pressed first (docs/IRIS_TODO.md,
|
||||||
log::info!("iris bench report: nothing to copy -- run the benchmark first");
|
/// 2026-09-07 night: "the copy report button seemed impossible to hit
|
||||||
return;
|
/// 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 {
|
let Some(platform) = &self.platform else {
|
||||||
log::info!("iris bench report: no platform handle, can't reach the clipboard");
|
log::info!("iris bench report: no platform handle, can't reach the clipboard");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// The ring goes on the clipboard, not into the pane: the pane is
|
let report = match self.last_report.clone() {
|
||||||
// on screen and a thousand log lines in it would bury the report
|
Some(report) => report,
|
||||||
// somebody pressed the button for, while the clipboard is going
|
None => format!(
|
||||||
// straight into a message to be read elsewhere.
|
"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!(
|
let report = format!(
|
||||||
"{report}\n\n=== app log ({}) ===\n{}",
|
"{report}\n\n=== app log ({}) ===\n{}",
|
||||||
crate::app_log::ring().summary(),
|
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) {
|
if platform.copy_to_clipboard("iris bench report", &report) {
|
||||||
log::info!("iris bench report: copied to clipboard");
|
log::info!("iris bench report: copied to clipboard");
|
||||||
|
|||||||
Reference in new issue
Block a user