From 61d092514470aa190d068d4a4d4b966ab2dc7d64 Mon Sep 17 00:00:00 2001 From: Martino Ferrari Date: Tue, 3 Nov 2026 10:50:55 +0100 Subject: [PATCH] docs: the readouts strip follows the collapsed state Co-Authored-By: Claude Sonnet 4.6 --- README.md | 14 +++++++------- docs/USER-GUIDE.md | 4 ++-- docs/claude/architecture.md | 12 +++++++----- docs/claude/invariants-plot-and-layout.md | 16 +++++++++------- docs/claude/invariants-readouts-and-cursors.md | 2 +- docs/claude/probe-readings.md | 13 +++++++------ docs/claude/verification.md | 5 +++-- help/C/org.udpscope.app/overview.page | 4 ++-- 8 files changed, 38 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 5926349..bdff8b3 100644 --- a/README.md +++ b/README.md @@ -159,19 +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 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 -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 +page's label and to the dock's, so the two cannot disagree. **When the dock is not beside the plot** -- hidden +with the dock button, or the window narrow enough (< 900 px, "compact mode") for the dock to be a collapsed +overlay on the plot, open or not -- 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 +same strings** (the setters that write the dock's labels write the strip's), and it is shown exactly when +`!show-sidebar || collapsed`: in a wide window it is hidden while the dock is shown beside the plot (so the +plot never loses its 26 px to both), and in a collapsed window it stays on screen even with the dock overlaid, +so the measurements and cursors remain visible in compact mode. 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 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 diff --git a/docs/USER-GUIDE.md b/docs/USER-GUIDE.md index 9987c26..8d314be 100644 --- a/docs/USER-GUIDE.md +++ b/docs/USER-GUIDE.md @@ -21,8 +21,8 @@ The window is a plot with three things around it: never resizes the plot; - 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 - 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). + page, and an **Events** block. With the dock hidden, or in a narrow window where the dock slides over the plot, 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 diff --git a/docs/claude/architecture.md b/docs/claude/architecture.md index 6b54ceb..b893637 100644 --- a/docs/claude/architecture.md +++ b/docs/claude/architecture.md @@ -135,12 +135,14 @@ touching the data path. (`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 + `left_column`; filled by `ui_dock.cpp`) carries the same readouts when the dock is not beside the plot: 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 + measurement. `sync_readouts_strip()` shows it exactly when `!adw_overlay_split_view_get_show_sidebar() || + adw_overlay_split_view_get_collapsed()` -- the Dock button put the dock away, or the window is collapsed and + the dock is an overlay on the plot (the strip stays on screen even while that overlay is open). 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); that means the `collapsed` it reads is the previous + frame's, and the strip follows a collapse or a widening one tick late, never through a wrong state. 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 diff --git a/docs/claude/invariants-plot-and-layout.md b/docs/claude/invariants-plot-and-layout.md index aa73b92..e72d415 100644 --- a/docs/claude/invariants-plot-and-layout.md +++ b/docs/claude/invariants-plot-and-layout.md @@ -148,18 +148,20 @@ 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 (`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). -- **The readouts strip is a fixed 26 px, scrolls sideways, and is shown only without the dock.** +- **The readouts strip is a fixed 26 px, scrolls sideways, and is shown whenever the dock is not beside the plot.** `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. + strip, the same as for the badge bar. It is *visible* exactly when `show-sidebar` is false **or** the split view is `collapsed` + (`sync_readouts_strip()`, from the tick after the wish is re-asserted and before `set_collapsed()` -- so + `show-sidebar` is the wish and not the split view's collapse-time write, and `collapsed` is the previous + frame's value). Hidden only with a wide window and the dock beside the plot, so the plot's 26 px go to one + pane of readouts and never both; in a collapsed window the dock is an overlay on the plot and the strip + stays, overlay open or not. The plot is 26 px shorter while it shows; that is the dock's and the window's + state moving the layout, not content. Reading `h=26` with `visible=1` (and `h=0` with `visible=0`) in + `strip:` is the assertion, and `visible_ok=1` that `visible` equals `expected`. - **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 trace at another signal. diff --git a/docs/claude/invariants-readouts-and-cursors.md b/docs/claude/invariants-readouts-and-cursors.md index 09c9ab2..b49d9e0 100644 --- a/docs/claude/invariants-readouts-and-cursors.md +++ b/docs/claude/invariants-readouts-and-cursors.md @@ -58,7 +58,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear 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. - **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 + not beside the plot (hidden, or the window collapsed so the dock is an overlay) 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 diff --git a/docs/claude/probe-readings.md b/docs/claude/probe-readings.md index c4e7773..f213677 100644 --- a/docs/claude/probe-readings.md +++ b/docs/claude/probe-readings.md @@ -1845,20 +1845,21 @@ These ride on the `[cursors-probe]` readings (every state line gets a `dock curs ## `strip:` (the readouts strip) ``` -[cursors-probe] strip: visible=0 dock_shown=1 cursors=4 measures=0 same_text=1 h=0 sens_same=1 collapsed=1 window=756 -[measures-probe] 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 ... +[cursors-probe] strip: visible=1 expected=1 visible_ok=1 dock_shown=1 cursors=4 measures=0 same_text=1 h=26 sens_same=1 collapsed=1 window=756 +[measures-probe] strip: visible=1 expected=1 visible_ok=1 dock_shown=1 cursors=0 measures=12 same_text=1 h=26 sens_same=1 collapsed=1 window=756 +[cursors-probe] dock hidden strip: visible=1 expected=1 visible_ok=1 dock_shown=0 cursors=4 measures=0 same_text=1 h=26 sens_same=1 ... +[cursors-probe] dock restored strip: visible=1 expected=1 visible_ok=1 dock_shown=1 ... collapsed=1 window=756 ``` 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. +- **`visible` equals `expected`, and `expected = !dock_shown || collapsed`** (`dock_shown` is `show-sidebar`, `collapsed` the split view's, both read in the same frame as `visible`). `visible_ok=1` is that equality; `visible_ok=0` is `sync_readouts_strip()` not run, or run before the reconciliation. A single such line right after the probe's own `update_side_visibility()` or on the very first line (the tick has not set `collapsed` yet) is the sub-frame before the next tick and not a defect. +- **`visible=1 expected=1` on every line under `xvfb-run`**, the `dock restored` line and the lines with `dock_shown=1` included: the window is 756 px, below the 900 px `kSidebarRoom`, so the split view is collapsed, the dock is an overlay on the plot, and the strip stays. `visible=0` there is the old rule (hidden whenever the dock is shown) or `collapsed` not being read. The wide case (`collapsed=0`, `dock_shown=1`, `visible=0 expected=0`) is **not reachable from a probe**, because a window with no manager cannot be resized by `gtk_window_set_default_size()`. - **`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). +- **`collapsed=1 window=756`** on every line under `xvfb-run`; the very first line can read `collapsed=0` (the tick has not set it yet), and then `expected` follows it. ## `[sidebar-probe]` diff --git a/docs/claude/verification.md b/docs/claude/verification.md index 2fee25f..1631a10 100644 --- a/docs/claude/verification.md +++ b/docs/claude/verification.md @@ -438,8 +438,9 @@ precedent, not an exception. - `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 measures probe's added / settled / final stops, each with a `strip:` line beside it (the readouts strip, - 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 + shown when `!dock_shown || collapsed`; `expected=` is that, `visible_ok=1` that the strip agrees); each probe + ends by hiding the dock for 0.6 s and reading the strip (`dock hidden`, `dock restored`: under xvfb the + window is collapsed, so `visible=1 expected=1 h=26 same_text=1` on both). **`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 children, the dock's width, the pages' sensitivity, whether the stream has signals) on every exit-dump run. diff --git a/help/C/org.udpscope.app/overview.page b/help/C/org.udpscope.app/overview.page index 8e664f3..227784e 100644 --- a/help/C/org.udpscope.app/overview.page +++ b/help/C/org.udpscope.app/overview.page @@ -116,8 +116,8 @@ shows and hides. Its Readouts are a read-only copy of the cursors and of every measurement; Edit beside each heading opens that instrument's full page. Under them, Events lists the captured events, newest first; a click - replays one and Manage opens the full list. While the dock is hidden, the - readouts show in a strip under the plot instead.

+ replays one and Manage opens the full list. While the dock is hidden, or the window is narrow and the + dock slides over the plot, the readouts show in a strip under the plot instead.

The status bar