ui: the tour and the contextual help follow the badge bar, the slide-over and the dock
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
4b65197f56
commit
2826042156
5 files changed
+254
-119
No files matched your search
@@ -489,7 +489,7 @@ Two lines of the self-check output are assertions in disguise:
|
||||
column and says there is one scroller and no stack. These are captured on the tick or at the exit probe:
|
||||
the dump runs after the window is destroyed. A source with extra panels adds *no* dock section: its panels
|
||||
are slide-over pages (`source-<id>`), so the line reads the same on the E-1608 and the probe kind.
|
||||
- `help layer: contextual=on hints=12 ids={events plot status cursors measures trigger trigger_advanced events_record trigger_search signals signals_config window} icon=dialog-information-symbolic(ok) hint=12x12; tour=idle steps=5 step=0 auto=1 requested=0` (in the exit
|
||||
- `help layer: contextual=on hints=12 ids={events plot status cursors measures trigger trigger_advanced events_record trigger_search signals signals_config window} icon=dialog-information-symbolic(ok) hint=12x12; tour=idle steps=6 step=0 auto=1 requested=0` (in the exit
|
||||
dump, beside `dock:`) — the help affordance layer as the last tick found it. **`hints=` must equal
|
||||
the number of ids**, and the ids are the surfaces the contextual help is on: eleven of the window
|
||||
itself, and `math` only while the math editor is open (its heading lives in a builder that is rebuilt
|
||||
@@ -534,14 +534,18 @@ Two lines of the self-check output are assertions in disguise:
|
||||
[invariants-gtk-and-chrome.md](invariants-gtk-and-chrome.md)). The writer chains to
|
||||
`g_log_writer_default()`, so every message still reaches stderr exactly as before and the documented
|
||||
baselines are read the same way.
|
||||
- `help figures: trigger_head=X,Y,W,H trigger_summary=… trigger_panel=… signal_list=… side_stack=… window_button=… status_label=… header_bar=… plot=…` (in the exit
|
||||
- `help figures: trigger_head=X,Y,W,H trigger_summary=… trigger_panel=… signal_list=… badge_bar=… dock=… window_button=… status_label=… header_bar=… plot=…` (in the exit
|
||||
dump, beside `help layer:`) — the **window-coordinate** rectangle of each surface the help's annotated
|
||||
figures label, `x,y,width,height`, or `-1,-1,0,0` for a surface that is **not on screen**. It is
|
||||
measured on the tick while the window is alive (nothing in the dump may call `gtk_widget_*` — see
|
||||
[verification.md](verification.md)) and with `gtk_widget_is_visible()`, not `get_visible()`: a widget
|
||||
under a hidden parent — `trigger_summary` while the pane is in *configuration* mode, the Measure page
|
||||
while the Signals tab is showing — keeps its own flag true and reads `0x0`, and a crop box drawn from
|
||||
that is a box over the wrong thing. The figures are produced by cropping a real screenshot, so these
|
||||
[verification.md](verification.md)) and with `gtk_widget_is_visible()` **and** `gtk_widget_get_mapped()`,
|
||||
not `get_visible()`: a widget under a hidden parent — `trigger_summary` while the pane is in
|
||||
*configuration* mode, and **every `trigger_*` surface while the slide-over is closed** (a revealer
|
||||
unmaps its child without touching its visible flag) — keeps its own flag true and reads `0x0`, and a crop
|
||||
box drawn from that is a box over the wrong thing. So the three `trigger_*` rectangles read real numbers
|
||||
only while the `trigger` page is open (the exit probe has it open; `UDPSCOPE_PROBE_HELPUI_MS` opens it for
|
||||
its figures legs), and `-1,-1,0,0` otherwise. `badge_bar` is the badge row under the plot and `dock` the
|
||||
right-hand column (these replaced `side_stack`, the old sidebar stack). The figures are produced by cropping a real screenshot, so these
|
||||
numbers **are** the crop boxes; their values depend on the window's size, which under the documented
|
||||
`xvfb-run` is the window's 756x894 minimum (the 640x480 screen is smaller than the content), so a run
|
||||
on a larger screen reads different numbers for the same panels. `trigger_summary` reading
|
||||
@@ -878,7 +882,7 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
||||
every row then reports `h=0`. It turns autohide off for its own measurement — a popover dismisses
|
||||
itself when it loses the grab, and `xvfb-run` has no window manager to hand it one — and restores
|
||||
it afterwards.
|
||||
- `[helpui] auto_started=1 visible=1 steps=5 step=0 (first run)` (stderr, `UDPSCOPE_PROBE_HELPUI_MS`) —
|
||||
- `[helpui] auto_started=1 visible=1 steps=6 step=0 (first run)` (stderr, `UDPSCOPE_PROBE_HELPUI_MS`) —
|
||||
the help affordance layer end to end, in ten steps 300-400 ms apart (every reading is an
|
||||
*allocation*, and a step that read its own predecessor's geometry would read a rectangle from before
|
||||
the frame that placed it). The line above is the **first-run auto-start**, read before the probe
|
||||
@@ -910,21 +914,25 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
||||
affordances are *gone*, not greyed, so anything else is a row that hid its buttons instead of
|
||||
removing them. The count comes back to the same twelve, which is the other half — a toggle that
|
||||
removed and could not restore is a one-way switch.
|
||||
- `[helpui] tour started from the probe: visible=1 steps=5 step=0` — the tour started the way
|
||||
`Ctrl+T` starts it. `steps=5` is the plan: the table's five steps whose surface is on screen or
|
||||
selectable into it (`gtk_widget_get_mapped()` -- a wrong *page* is kept, because selecting its
|
||||
page reveals it, while a *collapsed pane* is still dropped; see the surface bullets in
|
||||
[invariants-gtk-and-chrome.md](invariants-gtk-and-chrome.md)).
|
||||
- `[helpui] step=1/5 visible=1 slideover=none spot=[x,y WxH] target=[…] contains=1 card=[…] clear=C`
|
||||
- `[helpui] tour started from the probe: visible=1 steps=6 step=0` — the tour started the way
|
||||
`Ctrl+T` starts it. `steps=6` is the plan: the table's six stops (plot, badges, trigger, dock,
|
||||
signals, status) whose surface is on screen or can be opened into view. A stop that names a
|
||||
slide-over page is always kept (the `on_page` hook opens it whatever the dock is doing), a target
|
||||
that is mapped is kept, and a stop in a *collapsed dock* is dropped (`gtk_widget_get_mapped()`; see
|
||||
the surface bullets in [invariants-gtk-and-chrome.md](invariants-gtk-and-chrome.md)).
|
||||
- `[helpui] step=1/6 visible=1 slideover=none spot=[x,y WxH] target=[…] contains=1 card=[…] clear=C`
|
||||
— **in window coordinates**, the frame a screenshot is cropped in, with the slide-over's open page
|
||||
(`none`, or a page id) beside it; see `[toursurface]` below.
|
||||
(`none`, or a page id) beside it; see `[toursurface]` below. The `target=` rectangle is the part of the
|
||||
target that is *on screen* (intersected with the scrolled windows above it, `tour_target_bounds()`): a
|
||||
form taller than the panel's scroller on a short window is spotlit down to the scroller's edge and no
|
||||
further.
|
||||
**`contains` must be 1** on every step: the spotlight is the target's own rectangle grown three
|
||||
pixels. `clear` is the card missing the target, and it is 1 wherever the window has room for the
|
||||
card beside or above/below the hole — at the documented run's window (see `help figures:` below)
|
||||
the plot's step is *the whole content*, because at 756 px the split view overlays the side panel
|
||||
rather than putting it beside the plot, so `clear=0` there is the geometry and not a placement
|
||||
bug. The side panel's step reads `clear=1`.
|
||||
- `[helpui] after Next: step=2/5 visible=1`, `[helpui] after Back: step=1/5 visible=1`,
|
||||
bug. The badges step reads `clear=1`.
|
||||
- `[helpui] after Next: step=2/6 visible=1`, `[helpui] after Back: step=1/6 visible=1`,
|
||||
`[helpui] after Skip: visible=0 dims_hidden=1 spot_hidden=1 card_hidden=1 controllers=12 (was 12)
|
||||
click_gestures=2` — the three controls. **`controllers=` equal to `(was N)` is the "no lingering
|
||||
input grab" reading**: a tour of ordinary overlay widgets takes no grab at all, and a count that
|
||||
@@ -935,7 +943,9 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
||||
trigger pane's modes, by clicking its [edit] button. This exists because one of the help's figures
|
||||
is the *locked* pane's summary grid (`trigger_summary`), which in configuration mode is not on
|
||||
screen at all and reads `-1,-1,0,0`; the two lines give the geometry agent both states' numbers
|
||||
rather than leaving them to find the mode. `trigger_panel`'s height differs between them (508 px in
|
||||
rather than leaving them to find the mode. The probe opens the slide-over's `trigger` page for these
|
||||
legs (and for the collapsed-search leg after them) and closes it at the end: with the panel shut
|
||||
every `trigger_*` reads `-1,-1,0,0`. `trigger_panel`'s height differs between them (532 px in
|
||||
configuration mode against 72 locked — the body is replaced by the summary), which is the check
|
||||
that the mode really moved.
|
||||
- `[helpui] collapsed search: expanded=0 mapped=1 mapped_header=1 hint=12x12` (the last step, in
|
||||
@@ -945,28 +955,40 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
||||
read `mapped=0` (and `0x0`), which is exactly why the header box exists (`search_head` in
|
||||
`src/ui/trigger-panel.ui`) and why the hint joins it as its last child. `mapped_header=` is the
|
||||
header box beside it, and `hint=WxH` is the same 12x12 the layer's own line reads.
|
||||
- `[toursurface] …` (stderr, `UDPSCOPE_PROBE_TOUR_SURFACE_MS`) -- a stop that stands on a surface it is
|
||||
not on, entered from the state it is not in. Since the sidebar's tabs became the dock the probe opens the
|
||||
`trigger` slide-over page instead of switching a tab, starts the window's tour and walks it a stop per tick
|
||||
(400 ms). **The tour's own rework for the slide-over is Task 5's**: until its page hook exists the tour
|
||||
has no page stack, so a stop whose target is on a slide-over page is dropped, and the lines below read the
|
||||
dock only. The lines:
|
||||
- `[toursurface] …` (stderr, `UDPSCOPE_PROBE_TOUR_SURFACE_MS`) -- a stop that opens a surface it is not
|
||||
on, entered from the state it is not in. The probe opens the `trigger` slide-over page, starts the
|
||||
window's tour from there and walks the whole table a stop per tick (400 ms, past the panel's 120 ms
|
||||
slide); the `on_page` hook is what opens the page for the trigger stop and closes the panel for every
|
||||
stop that names none. The lines:
|
||||
|
||||
- `[toursurface] before: slideover=none signal_list_mapped=1 running=1` -- the state a first run starts in
|
||||
(the dock is on screen), then the auto-started walk is dismissed.
|
||||
- `[toursurface] on trigger: slideover=trigger signal_list_mapped=1 side_box_mapped=1` -- a frame after the
|
||||
page was opened: the dock is still on screen under the slide-over (they are not alternatives).
|
||||
- `[toursurface] tour: visible=1 steps=N step=0 signals_stop=1` -- **`signals_stop=1` is the filter's
|
||||
reading**: the signal list is in the dock, which is mapped, so its stop is in the plan.
|
||||
- `[toursurface] step=N/M slideover=<page> target_mapped=D[ target=signal_list]` -- one per stop;
|
||||
**the `signals` stop reads `target_mapped=1`**.
|
||||
- `[toursurface] signals stop=N/M visible=1 slideover=… spot=[…] target=[…] contains=1 card=[…] clear=1` --
|
||||
the `tour_geometry_line()` the helpui probe uses: **`contains=1` is the assertion** that the spotlight
|
||||
and the card are on the list.
|
||||
- `[toursurface] collapsed: side_box_mapped=0 steps=2 signals_stop=0 side_stop=0` -- the other half of
|
||||
the filter, read: with `sidebar_wanted` off (`update_side_visibility()` re-asserts it, so this is how a
|
||||
probe puts the sidebar away for good) the split view unmaps the column and the stops that need the
|
||||
dock are dropped while the page-less ones stay. This is what says a *collapsed pane* is dropped.
|
||||
- `[toursurface] before: slideover=none signal_list_mapped=1 running=1` -- the state a first run starts
|
||||
in (panel closed, dock on screen); the auto-started walk is dismissed.
|
||||
- `[toursurface] on trigger: slideover=trigger trigger_body_mapped=1 side_box_mapped=1` -- a frame after
|
||||
the page was opened: the dock is still on screen under the panel (they are not alternatives).
|
||||
- `[toursurface] tour: visible=1 steps=6 step=0 trigger_stop=1 signals_stop=1` -- the plan: **six
|
||||
stops, the trigger stop and the signals stop both in it**.
|
||||
- `[toursurface] step=N/6 title='…' slideover=<page> target_mapped=D` -- one per stop, in order: *The
|
||||
plot*, *The badges*, *The trigger*, *The dock*, *The signals*, *The status line*. **Step 1 reads
|
||||
`slideover=none` although the probe started with the panel open** (a stop with no page closes it),
|
||||
**step 3 reads `slideover=trigger`, and step 4 reads `slideover=none` again**; every `target_mapped`
|
||||
is 1.
|
||||
- `[toursurface] stop=N/6 visible=1 slideover=… spot=[…] target=[…] contains=1 card=[…] clear=C` -- the
|
||||
`tour_geometry_line()` the helpui probe uses, one per stop, read a frame after the stop was entered
|
||||
(the spotlight is withheld until the panel has finished sliding in, `page_settled`): **`contains=1` on
|
||||
every stop is the assertion** that the spotlight is on the target. `clear=0` is read as geometry, not
|
||||
as a placement bug, on the plot stop (the target is the whole content) and on the trigger stop at the
|
||||
documented 756 px window (the panel is 360 px of it, so the card has no side wide enough and goes flush
|
||||
left over the plot, overlapping the panel's edge by a few pixels).
|
||||
- `[toursurface] finished: running=0 slideover=none` -- the last Next ended the walk and **the panel is
|
||||
closed with it**.
|
||||
- `[toursurface] restarted at trigger: running=1 slideover=trigger` then
|
||||
`[toursurface] skipped: running=0 slideover=none` -- the walk parked on the trigger stop and dismissed
|
||||
(the Skip/Esc route): **`slideover=none` after the dismissal** is the tour not leaving a panel behind.
|
||||
- `[toursurface] collapsed: side_box_mapped=0 steps=4 trigger_stop=1 signals_stop=0 side_stop=0` -- the
|
||||
filter with the dock put away (`sidebar_wanted` off; `update_side_visibility()` re-asserts it, so this
|
||||
is how a probe puts the dock away for good): the dock's two stops are dropped, **and the trigger stop is
|
||||
kept** because the slide-over does not depend on the dock -- four stops remain (plot, badges, trigger,
|
||||
status).
|
||||
- `[keys] a: armed 0->1 | space: paused 0->1 | t: trigger panel: 0->1 | c: cursors: 0->1 | m: dock 0->243 (cursors_y=243 reach=2256 at_cursors=1) | g: dock 243->0 at_top=1 | … | editable focused: 'm' refused=1` (stderr, `UDPSCOPE_PROBE_KEYS_MS`) — **every `X->Y` pair must differ** (`g` returns, so its pair reads `243->0`) and **`refused` must be 1**.
|
||||
The `m`/`g` readings are the dock scroller's vertical adjustment before and after (the probe pads the dock to 3000 px so there is something to scroll, and undoes it at the end): **`m` must land on `cursors_y`, the cursors panel's y in the dock (`at_cursors=1`), and `g` must return to 0 (`at_top=1`)**, which is what says those two keys scroll to a section rather than toggling a pane; a `reach` of 0 would mean the dock fit its viewport and the probe's padding was lost; `t`/`c` read the toolbar toggle's own state, because those two enable a feature and the button is where that state is visible. The refusal is the whole reason the controller is in the bubble phase: every bare-letter accel is also a character, so an accel that fires while a `GtkEditable` has focus makes the window entry unusable. A pair reading `0->0` is an action whose dispatch does not reach the handler a click reaches. Note the format is `<key>: <widget-description>: <before>-><after>` — the name passed to `before_after()` includes the widget's description, so `t: trigger panel: 0->1` is the correct form (not `t: trigger panel 0->1` without the colon before the values).
|
||||
- `[color] '<name>' at row R slot S: trace=#RRGGBB chip_agrees=1 (want 1)`, then `[color] override: trace=#123456 chip_agrees=1`, `[color] session: entries=1 rgb=#123456` and `[color] default: trace=#RRGGBB chip_agrees=1` (stderr, `UDPSCOPE_PROBE_COLOR_MS`) — **all three `chip_agrees` must be 1**, the override line's `trace` must be `#123456`, the session line must read `entries=1 rgb=#123456`, and the default line's `trace` must be back to the first line's. Run it with `UDPSCOPE_ENABLE_ALL_MS` ahead of it, or there is no bound trace and the probe prints `no bound trace to recolour` instead of asserting anything; on the standard mock the first line reads `'sine' at row 0 slot 0: trace=#4FA3FF`. Two things make this an assertion rather than a tautology. The colours are read out of **`plot::Plot::trace().color`** — what the renderer will stroke, reached through `Row::plot` *after* `relayout_areas()`, since a new colour is a new figure — and out of the chip's own `<span foreground="…">` markup, not by asking `RowSet::signal_color()` twice, which would pass against a chip that never reached the trace. And the override is `#123456`, deliberately in no palette slot: an override equal to the entry it replaces passes against an implementation that ignores overrides entirely. The session leg round-trips `collect_layout()` → `save_layout()` → `load_layout()` on a temp path and deletes it, because a probe must not leave a colour in the real session file for a later run to inherit.
|
||||
|
||||
Reference in new issue
Block a user