docs: the readouts strip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-11-03 10:47:11 +01:00
1 parent c8d9d04f59
commit 3526ce0541
8 files changed
+75 -5

No files matched your search

+13 -1
View File
@@ -159,7 +159,19 @@ cells are a fixed number of characters wide and ellipsized, so the dock's width
depend on what a value reads: the **who** cell of a cursor line is 5 characters (the full text is its depend on what a value reads: the **who** cell of a cursor line is 5 characters (the full text is its
tooltip), a value cell 9 (its tooltip is the full text). The dock and the pages show **one string**: tooltip), a value cell 9 (its tooltip is the full text). The dock and the pages show **one string**:
`update_cursors_pane()` and `update_measures()` format each value once and hand that variable to the `update_cursors_pane()` and `update_measures()` format each value once and hand that variable to the
page's label and to the dock's, so the two cannot disagree. The **Events** block is a heading with a page's label and to the dock's, so the two cannot disagree. **When the dock is not on screen** -- hidden
with the dock button, or the window narrow enough (< 900 px) for the dock to be a collapsed overlay that is
not currently open -- the same readouts appear on **one line under the plot**, above the badge bar (the
*readouts strip*): a **Cursors** button (opens the `cursors` page) and one chip per cursor line (its name and
its *delta* value), then a **Measures** button (opens the `measure` page) and one chip per measurement (the
signal's colour chip, the type, the value; a click opens its dialog; "no measurements" when there are none).
It is a **fixed 26 px** high and its chips are as wide as the dock's cells (name 6 characters, type 10, value
9, the full text in the tooltip); what does not fit scrolls sideways with no bar taking height. With the
cursors off the chips are insensitive and read `--`, as the dock's cells do. It is the **third reader of the
same strings** (the setters that write the dock's labels write the strip's), and it is hidden whenever the
dock is shown, so the plot never loses its 26 px to both. **Known limit:** a *collapsed* window whose dock
button is still on has the dock overlaid over the plot (the app re-asserts the button's wish every frame, so
the overlay cannot be swiped away), and then the strip is hidden; it shows once the dock button is off. The **Events** block is a heading with a
**Manage** button over a short list of the cached events, newest first -- one compact row each, never a **Manage** button over a short list of the cached events, newest first -- one compact row each, never a
picture -- and one click on a row replays that event (see "Captured events"). The full list, with the picture -- and one click on a row replays that event (see "Captured events"). The full list, with the
pictures and the comparison actions, is the `events` slide-over page that **Manage** opens. There is no pictures and the comparison actions, is the `events` slide-over page that **Manage** opens. There is no
+2 -1
View File
@@ -21,7 +21,8 @@ The window is a plot with three things around it:
never resizes the plot; never resizes the plot;
- the **dock** on the right, which the dock button in the header bar (`s`) shows and hides: read-only - the **dock** on the right, which the dock button in the header bar (`s`) shows and hides: read-only
**Readouts** of the cursors and of the measurements, each with an **Edit** button that opens its **Readouts** of the cursors and of the measurements, each with an **Edit** button that opens its
page, and an **Events** block. page, and an **Events** block. With the dock hidden, the readouts show in a one-line strip under the
plot instead (the cursors' deltas and each measurement's value; **Cursors** and **Measures** open the pages).
## 1. Connecting ## 1. Connecting
+12
View File
@@ -134,6 +134,18 @@ touching the data path.
kind's panels (those are slide-over pages). The window's measurement editor is a dialog kind's panels (those are slide-over pages). The window's measurement editor is a dialog
(`open_measure_dialog()`), not part of the `measure` page. (`open_measure_dialog()`), not part of the `measure` page.
**The readouts strip** (`readouts_strip` in `main-window.ui`, between `plot_overlay` and `badge_bar` in
`left_column`; filled by `ui_dock.cpp`) carries the same readouts when the dock is not on screen: a flat
**Cursors** button and one chip (`who` + delta) per cursor line, then a **Measures** button and one chip per
measurement. `sync_readouts_strip()` shows it exactly when `adw_overlay_split_view_get_show_sidebar()` is
false; the tick calls it right after re-asserting `sidebar_wanted` and *before* `set_collapsed()` (so the
split view's own collapse-time `show-sidebar` write is never read, and the strip does not flash on a
narrowing). Its labels (`strip_cursor_who`, `strip_cursor_deltas`, `strip_measure_labels`) are rebuilt by
`dock_rebuild_cursors()` / `dock_rebuild_measures()` and written by `dock_cursor_cell()` /
`dock_measure_value()` from the same argument as the dock's, so there is no second formatter;
`dock_set_cursors_sensitive()` is the one writer of the cursor readouts' sensitivity (the dock's grid and
the strip's chip box).
The **Events** block (`build_events_dock()`, also `ui_dock.cpp`) is a heading with a **Manage** button The **Events** block (`build_events_dock()`, also `ui_dock.cpp`) is a heading with a **Manage** button
(`open_events_page()`) over a short list (`dock_events_list`, 112 px, scrolled, no thumbnails): one compact (`open_events_page()`) over a short list (`dock_events_list`, 112 px, scrolled, no thumbnails): one compact
row per `EventRecord`, newest first, capped at `kDockEventsMax` (24) with a dim "... N more, see Manage" row per `EventRecord`, newest first, capped at `kDockEventsMax` (24) with a dim "... N more, see Manage"
+12
View File
@@ -148,6 +148,18 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
characters, which made the readouts' minimum width 304 px; that pushed the sidebar to 304 px characters, which made the readouts' minimum width 304 px; that pushed the sidebar to 304 px
(`dock_w=304`) and defeated the 280 pin. Widening any cell is the same (`dock_w=304`) and defeated the 280 pin. Widening any cell is the same
trap -- read `[readouts] ... dock_w=` (must be 280) and the `dock cursors:` / `dock measures:` `fits=`, and for the Events block `dock events: ... dock_w=` (268). trap -- read `[readouts] ... dock_w=` (must be 280) and the `dock cursors:` / `dock measures:` `fits=`, and for the Events block `dock events: ... dock_w=` (268).
- **The readouts strip is a fixed 26 px, scrolls sideways, and is shown only without the dock.**
`readouts_strip` (a `GtkScrolledWindow`, `height-request` 26, horizontal `external`, vertical `never`) sits
in `left_column` between `plot_overlay` and `badge_bar`. Its height is a request and not a measurement of
its chips (the buttons are trimmed by `button.udpscope-strip-button` in `ui_widgets.cpp`, or Adwaita's
34 px flat button would push it past 26), the chips' cells are fixed-width ellipsized labels like the
dock's, and an overflow scrolls with no bar taking height: "layout must not depend on content" for the
strip, the same as for the badge bar. It is *visible* exactly when `show-sidebar` is false
(`sync_readouts_strip()`, from the tick after the wish is re-asserted and before `set_collapsed()` --
read after the collapse it would show for a frame each time the window narrowed), and hidden when the dock
is on screen, overlaid included, so the plot's 26 px go to one pane of readouts and never both. The plot
is 26 px shorter while it shows; that is the dock's state moving the layout, not content. Reading
`h=26` with `visible=1` (and `h=0` with `visible=0`) in `strip:` is the assertion.
- **Trace slots are identified by signal name, not channel index.** Enabling a signal - **Trace slots are identified by signal name, not channel index.** Enabling a signal
or a new CONFIG renumbers the channel list, so an index would silently re-point a or a new CONFIG renumbers the channel list, so an index would silently re-point a
trace at another signal. trace at another signal.
@@ -57,6 +57,18 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
pin). `[cursors-probe] ... dock cursors:` and `[measures-probe] ... dock measures:` assert it: `same_text=1` pin). `[cursors-probe] ... dock cursors:` and `[measures-probe] ... dock measures:` assert it: `same_text=1`
compares `gtk_label_get_text()` (the untruncated text) of every dock label with the page's, and compares `gtk_label_get_text()` (the untruncated text) of every dock label with the page's, and
`fits=1` that the Readouts box is no wider than the dock. `fits=1` that the Readouts box is no wider than the dock.
- **The readouts strip is a third reader of the same string, never a second formatter.** When the dock is
not on screen the readouts are shown in the strip under the plot (`readouts_strip`, `src/ui_dock.cpp`): the
cursor chips' `who` and *delta* labels and the measurement chips' value labels. They are written **in the
same call** as the dock's -- `dock_cursor_cell()` and `dock_measure_value()` set the strip's label from the
argument they were handed, and `dock_rebuild_cursors()` / `dock_rebuild_measures()` rebuild its chips
beside the dock's lines -- so a value is still formatted once, into one local, and a feature that writes a
dock cell without going through those two setters leaves the strip stale. The strip keeps the dock's
rules: the same fixed-width ellipsized cells (who 6, type 10, value 9 characters, full text in the
tooltip), the delta cell reads `--` on the same branches, and the cursor chips are *insensitive* with the
cursors off and never hidden -- through `dock_set_cursors_sensitive()`, which writes the dock's grid and the
strip's chip box together; a second `gtk_widget_set_sensitive()` on either is two spellings of one state.
`[cursors-probe]` / `[measures-probe]` `strip: ... same_text=1` asserts it.
- **`format_measure()` is the one formatter for both panes, and its SI prefix does not depend on - **`format_measure()` is the one formatter for both panes, and its SI prefix does not depend on
there being a unit.** The cursors pane's values and the measurements pane's `text=` go through there being a unit.** The cursors pane's values and the measurements pane's `text=` go through
it, so a change reaches both. The prefix ladder used to be inside `if (!unit.empty())`, which it, so a change reaches both. The prefix ladder used to be inside `if (!unit.empty())`, which
+18
View File
@@ -1842,6 +1842,24 @@ These ride on the `[cursors-probe]` readings (every state line gets a `dock curs
- **`dock_sensitive=1`** (cursors only): the dock's cursor grid is live whenever the stream has signals; `0` before them ("disable, do not hide"), `0` with signals is the dock never coming back. - **`dock_sensitive=1`** (cursors only): the dock's cursor grid is live whenever the stream has signals; `0` before them ("disable, do not hide"), `0` with signals is the dock never coming back.
- On a session with no cursors line, or with no measurements, `lines=0 page_lines=0 same_text=1` is correct: the dock then shows `no measurements` for the measurements (one non-value label, not counted in `lines`). - On a session with no cursors line, or with no measurements, `lines=0 page_lines=0 same_text=1` is correct: the dock then shows `no measurements` for the measurements (one non-value label, not counted in `lines`).
## `strip:` (the readouts strip)
```
[cursors-probe] <what> strip: visible=0 dock_shown=1 cursors=4 measures=0 same_text=1 h=0 sens_same=1 collapsed=1 window=756
[measures-probe] <what> strip: visible=0 dock_shown=1 cursors=0 measures=12 same_text=1 h=0 sens_same=1 collapsed=1 window=756
[cursors-probe] dock hidden strip: visible=1 dock_shown=0 cursors=4 measures=0 same_text=1 h=26 sens_same=1 ...
[cursors-probe] dock restored strip: visible=0 dock_shown=1 ...
```
One `strip:` line follows every `dock cursors:` / `dock measures:` line, and each probe ends with a drive that puts the dock away through the wish (`sidebar_wanted = false`), reads the strip 600 ms later (`dock hidden`), restores the wish and reads again (`dock restored`).
- **`visible` is the opposite of `dock_shown`** (`dock_shown` is `show-sidebar`) on every settled line. `visible=0 dock_shown=0` or `visible=1 dock_shown=1` is `sync_readouts_strip()` not run (or run before the reconciliation); a single such line right after the probe's own `update_side_visibility()` is the sub-frame before the next tick and not a defect.
- **`h` is 26 with `visible=1`, 0 with `visible=0`.** Any other visible height is the chips setting the strip's height (the button trim in `ui_widgets.cpp` or the `height-request` lost).
- **`same_text=1` is the assertion**: every strip label (the cursors' `who` and delta, the measurements' values) has the dock's text, and the counts of chips match the dock's lines. `0` is a value written to one view only -- a dock cell set without `dock_cursor_cell()` / `dock_measure_value()`, or a rebuild that did not mirror.
- **`cursors` / `measures`** are the chip counts and equal the dock's `lines`.
- **`sens_same=1`**: the strip's cursor chips and the dock's cursor grid have the same sensitivity (`dock_set_cursors_sensitive()`).
- **`collapsed=1 window=756`** on every line under `xvfb-run`: the window is below the 900 px `kSidebarRoom`, so these lines are all the *collapsed* case (a wished dock stays overlaid, `visible=0`; a hidden one shows the strip). The non-collapsed case is not reachable from a probe, because a window with no manager cannot be resized by `gtk_window_set_default_size()`. The very first line can read `collapsed=0` (the tick has not set it yet).
## `[sidebar-probe]` ## `[sidebar-probe]`
``` ```
+4 -2
View File
@@ -437,8 +437,10 @@ precedent, not an exception.
no scroll and no padding.) no scroll and no padding.)
- `UDPSCOPE_PROBE_CURSORS_MS` and `UDPSCOPE_PROBE_MEASURES_MS` also print the dock's copy of what they read: - `UDPSCOPE_PROBE_CURSORS_MS` and `UDPSCOPE_PROBE_MEASURES_MS` also print the dock's copy of what they read:
a `dock cursors:` line after every `[cursors-probe]` report and a `dock measures:` line at the a `dock cursors:` line after every `[cursors-probe]` report and a `dock measures:` line at the
measures probe's added / settled / final stops. **`same_text=1` on every one** is the assertion that the measures probe's added / settled / final stops, each with a `strip:` line beside it (the readouts strip,
dock and the page show one string; `fits=1` that the Readouts box is no wider than the dock. Entries in shown only without the dock); each probe ends by hiding the dock for 0.6 s and reading the strip (`dock hidden`:
`visible=1 h=26 same_text=1`; `dock restored`: `visible=0`). **`same_text=1` on every one** is the assertion that the
dock, the strip and the page show one string; `fits=1` that the Readouts box is no wider than the dock. Entries in
`probe-readings.md`. The exit chain also prints one `[readouts]` line (pages registered, the dock page's three `probe-readings.md`. The exit chain also prints one `[readouts]` line (pages registered, the dock page's three
children, the dock's width, the pages' sensitivity, whether the stream has signals) on every exit-dump run. children, the dock's width, the pages' sensitivity, whether the stream has signals) on every exit-dump run.
- `UDPSCOPE_PROBE_DOCK_SESSION_MS=2500` with `UDPSCOPE_EXIT_AFTER_MS=8000` -- the session file's `dock` key, - `UDPSCOPE_PROBE_DOCK_SESSION_MS=2500` with `UDPSCOPE_EXIT_AFTER_MS=8000` -- the session file's `dock` key,
+2 -1
View File
@@ -116,7 +116,8 @@
shows and hides. Its <gui>Readouts</gui> are a read-only copy of the cursors and of shows and hides. Its <gui>Readouts</gui> are a read-only copy of the cursors and of
every measurement; <gui>Edit</gui> beside each heading opens that instrument's full every measurement; <gui>Edit</gui> beside each heading opens that instrument's full
page. Under them, <gui>Events</gui> lists the captured events, newest first; a click page. Under them, <gui>Events</gui> lists the captured events, newest first; a click
replays one and <gui>Manage</gui> opens the full list.</p> replays one and <gui>Manage</gui> opens the full list. While the dock is hidden, the
readouts show in a strip under the plot instead.</p>
</item> </item>
<item> <item>
<title>The status bar</title> <title>The status bar</title>