docs: the readouts strip hides when empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-11-03 11:15:19 +01:00
1 parent 5653a3a66b
commit d82d9f8213
9 files changed
+46 -22

No files matched your search

+8 -3
View File
@@ -164,12 +164,17 @@ with the dock button, or the window narrow enough (< 900 px, "compact mode") for
overlay on the plot, open or not -- the same readouts appear on **one line under the plot**, above the badge bar (the 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 *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 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). signal's colour chip, the type, the value; a click opens its dialog). Each of the two groups is there only
with something to read -- the Cursors group with the cursors switched on, the Measures group with at least one
measurement, the separator with both -- and **with neither, the strip is not shown at all**.
It is a **fixed 26 px** high and its chips are as wide as the dock's cells (name 6 characters, type 10, value 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 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 cursors off their chips are insensitive and read `--`, as the dock's cells do (the group is hidden then, so this is
not seen). It is the **third reader of the
same strings** (the setters that write the dock's labels write the strip's), and it is shown exactly when 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 `(!show-sidebar || collapsed)` **and** (the cursors are on **or** there is a measurement) -- a deliberate
exception to "disable, do not hide": an empty line under the plot is 26 px of nothing, and the dock, which keeps
both blocks on screen, is where the empty state is shown. 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, 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 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 **Manage** button over a short list of the cached events, newest first -- one compact row each, never a
+1 -1
View File
@@ -22,7 +22,7 @@ The window is a plot with three things around it:
- 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. With the dock hidden, or in a narrow window where the dock slides over the plot, the readouts show in a 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). one-line strip under the plot instead (the cursors' deltas and each measurement's value; **Cursors** and **Measures** open the pages); the strip is there only while the cursors are on or there is a measurement.
## 1. Connecting ## 1. Connecting
+7 -3
View File
@@ -137,9 +137,13 @@ touching the data path.
**The readouts strip** (`readouts_strip` in `main-window.ui`, between `plot_overlay` and `badge_bar` in **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 beside the plot: 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 **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() || 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 adw_overlay_split_view_get_collapsed())` **and** (the cursors toggle is active **or** `app.measures` is
the dock is an overlay on the plot (the strip stays on screen even while that overlay is open). The tick non-empty) -- 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), and there is something to read. Inside, the
Cursors group (`strip_cursor_group`) is shown with the cursors on, the Measures group (`strip_measure_group`)
with measurements, the separator (`strip_sep`) with both; with neither the strip is hidden. Besides the tick,
the cursors toggle handler and `rebuild_measures_pane()` call it, so a toggle or an add/delete shows at once. The tick
calls it right after re-asserting `sidebar_wanted` and *before* `set_collapsed()` (so the split view's own 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 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 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
+10 -5
View File
@@ -148,20 +148,25 @@ 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 whenever the dock is not beside the plot.** - **The readouts strip is a fixed 26 px, scrolls sideways, and is shown only when the dock is not beside the plot and there is something to read.**
`readouts_strip` (a `GtkScrolledWindow`, `height-request` 26, horizontal `external`, vertical `never`) sits `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 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 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 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 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 **or** the split view is `collapsed` strip, the same as for the badge bar. It is *visible* exactly when (`show-sidebar` is false **or** the split view is `collapsed`)
**and** (the cursors are on **or** there is a measurement)
(`sync_readouts_strip()`, from the tick after the wish is re-asserted and before `set_collapsed()` -- so (`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 `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 frame's value). Hidden 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 pane of readouts and never both, and hidden with nothing to read (cursors off, no measurement). That last
is a deliberate, user-requested exception to "disable, do not hide": an empty strip is 26 px of nothing, and
the dock keeps both blocks on screen so the empty state is never invisible; the strip's two groups and the
separator follow the same rule (`strip_cursor_group` with the cursors, `strip_measure_group` with
measurements, `strip_sep` with 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 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 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`. `strip:` is the assertion, `visible_ok=1` that `visible` equals `expected` and `groups_ok=1` that the groups agree.
- **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.
@@ -66,8 +66,12 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
dock cell without going through those two setters leaves the strip stale. The strip keeps the dock's 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 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 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 cursors off -- 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. strip's chip box together; a second `gtk_widget_set_sensitive()` on either is two spellings of one state.
The one place the strip hides what the dock only disables: with the cursors off the strip's Cursors group is
not shown, with no measurement its Measures group is not, and with neither the strip is not (the dock keeps
both blocks, `no measurements` included; the strip has no placeholder). That is
`sync_readouts_strip()`, not a sensitivity.
`[cursors-probe]` / `[measures-probe]` `strip: ... same_text=1` asserts it. `[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
+8 -4
View File
@@ -1845,16 +1845,20 @@ These ride on the `[cursors-probe]` readings (every state line gets a `dock curs
## `strip:` (the readouts strip) ## `strip:` (the readouts strip)
``` ```
[cursors-probe] <what> 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 [cursors-probe] <what> 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 groups=100 groups_ok=1
[measures-probe] <what> 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 [measures-probe] <what> 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 groups=010 groups_ok=1
[measures-probe] start strip: visible=0 expected=0 visible_ok=1 dock_shown=1 cursors=0 measures=0 same_text=1 h=0 sens_same=1 collapsed=1 window=756 groups=000 groups_ok=1
[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 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 [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`). 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` 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` equals `expected`, and `expected = (!dock_shown || collapsed) && (cursors on || measures non-empty)`** (`dock_shown` is `show-sidebar`, `collapsed` the split view's, both read in the same frame as `visible`; "cursors on" is the cursors toggle, not the `cursors=` chip count, which is a rebuild's and is 1 even with them off). `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()`. - **What each leg reads.** `[measures-probe] start` (before the probe adds anything, from a **fresh** config: a stored session brings its measurements back) is the "neither" state: `visible=0 expected=0 groups=000 h=0`. The measures probe's later lines have measurements and the cursors off: `groups=010`. The cursors probe alone has the cursors on and no measurements: `groups=100`; run after the measures probe in the same session it has both: `groups=111`. A line with the strip visible and `groups=000`, or hidden with a group on, is `sync_readouts_strip()` not called from that path.
- **`groups=<cursors><measures><separator>`** is which of `strip_cursor_group`, `strip_measure_group` and `strip_sep` are visible; **`groups_ok=1`** is that they equal (cursors on, a measurement, both). `0` is a group left over from the previous state.
- **`h=0` with `visible=1` on the `cursors-probe ... on` and `measures-probe ... added` lines** is the strip shown in the same frame the probe reads it, before its first allocation; the next line reads 26. It is not a `visible_ok` miss: the toggle handler and `rebuild_measures_pane()` call `sync_readouts_strip()` themselves, so `visible` is already right.
- **`visible=1 expected=1` on every line that has something to read, 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). - **`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. - **`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`. - **`cursors` / `measures`** are the chip counts and equal the dock's `lines`.
+2 -2
View File
@@ -438,9 +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: - `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, each with a `strip:` line beside it (the readouts strip, measures probe's added / settled / final stops, each with a `strip:` line beside it (the readouts strip,
shown when `!dock_shown || collapsed`; `expected=` is that, `visible_ok=1` that the strip agrees); each probe shown when `(!dock_shown || collapsed)` and the cursors are on or there is a measurement; `expected=` is that, `visible_ok=1` that the strip agrees, `groups=`/`groups_ok=1` the same for its Cursors / Measures groups and separator; the measures probe's `start` line, before it adds anything, is the hidden "neither" state -- run it from a fresh config); each probe
ends by hiding the dock for 0.6 s and reading the strip (`dock hidden`, `dock restored`: under xvfb the 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 window is collapsed, so `visible=1 expected=1 h=26 same_text=1` on both, given something to read). **`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 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.
+1 -1
View File
@@ -117,7 +117,7 @@
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. While the dock is hidden, or the window is narrow and the replays one and <gui>Manage</gui> 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.</p> dock slides over the plot, the readouts show in a strip under the plot instead, as long as the cursors are on or there is a measurement.</p>
</item> </item>
<item> <item>
<title>The status bar</title> <title>The status bar</title>
+4 -2
View File
@@ -611,7 +611,8 @@ struct App {
/// One value label per measurement, in `measures` order (the dock's copy of `measure_labels`). /// One value label per measurement, in `measures` order (the dock's copy of `measure_labels`).
std::vector<GtkWidget*> dock_measure_labels; std::vector<GtkWidget*> dock_measure_labels;
/// The readouts strip under the plot (`main-window.ui` `readouts_strip`, `src/ui_dock.cpp`): shown /// The readouts strip under the plot (`main-window.ui` `readouts_strip`, `src/ui_dock.cpp`): shown
/// whenever the dock is not beside the plot (`!show-sidebar || collapsed`). Its value labels mirror the dock's one for one -- `strip_cursor_deltas` the /// whenever the dock is not beside the plot (`!show-sidebar || collapsed`) *and* there is something to
/// read (the cursors on, or a measurement; `sync_readouts_strip()`). Its value labels mirror the dock's one for one -- `strip_cursor_deltas` the
/// `d` cell of each `dock_cursor_lines` entry, `strip_measure_labels` each of `dock_measure_labels` -- /// `d` cell of each `dock_cursor_lines` entry, `strip_measure_labels` each of `dock_measure_labels` --
/// and `strip_cursor_who` the cursor lines' `who` cells, all written from the dock setters' arguments. /// and `strip_cursor_who` the cursor lines' `who` cells, all written from the dock setters' arguments.
GtkWidget* readouts_strip = nullptr; GtkWidget* readouts_strip = nullptr;
@@ -1801,7 +1802,8 @@ void dock_measure_value(App& app, std::size_t i, const std::string& text);
/// The readouts strip under the plot (`src/ui_dock.cpp`): the third reader of the same strings. It is /// The readouts strip under the plot (`src/ui_dock.cpp`): the third reader of the same strings. It is
/// filled by the `dock_*` rebuilds and written by the `dock_*` setters above (so nothing here formats), /// filled by the `dock_*` rebuilds and written by the `dock_*` setters above (so nothing here formats),
/// and shown whenever the dock is not beside the plot (`!show-sidebar || collapsed`, a collapsed dock being /// and shown whenever the dock is not beside the plot (`!show-sidebar || collapsed`, a collapsed dock being
/// an overlay on it): `sync_readouts_strip()` is called by the tick after the show-sidebar reconciliation /// an overlay on it) and there is something to read (cursors on or a measurement; each group follows its own
/// feature, and with neither the strip is hidden): `sync_readouts_strip()` is called by the tick after the show-sidebar reconciliation
/// and before `set_collapsed()`, so it reads the previous frame's `collapsed`. `dock_set_cursors_sensitive()` is the one writer of the cursor readouts' /// and before `set_collapsed()`, so it reads the previous frame's `collapsed`. `dock_set_cursors_sensitive()` is the one writer of the cursor readouts'
/// sensitivity, for the dock's grid and the strip's chips together. /// sensitivity, for the dock's grid and the strip's chips together.
void sync_readouts_strip(App& app); void sync_readouts_strip(App& app);