The dock button's tooltip, the guided-tour menu row's tooltip and the m / g shortcut labels still described a side panel and tabs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The dock's Events block, the events slide-over page, the availability-rule deviation, the probe lines and the removal of the left pane are described; the false remembered-width claim is gone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The dock tour stop names the Events block (one click replays, Manage opens the list) and the event-history and record hints point at the page and the dock instead of a left pane.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The dock tour stop describes the read-only readouts and their Edit buttons, and the cursors and measures hints point to the dock copy and the pages.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both views are written from the same variable at the same call site, so the dock cannot disagree with the full panels.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Converts every --buffer-mb / buffer_mb mention to --buffer-samples / buffer_samples,
records the unit change as a deviation (README, SPECS, CLAUDE.md), documents the
buffer: and planner: dump lines and the new Preferences row, and updates the help
pages and the help-shot script.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
--buffer-samples (k/M/G) replaces --buffer-mb: the request is rounded down to a
power of two for every signal and the shared time ring. A separate memory limit
(--memory-limit-mb, a Preferences row, default 8 GiB) halves the plan until the
real ring bytes fit and says so on stderr and in the status line. The per-source
key buffer_mb becomes buffer_samples; an old buffer_mb is ignored.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
A Source pill that opens nothing (UDPS, Flat UDP, files) was noise. It is now shown only while the slide-over has a source page; the [badges] source line gains visible=.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The link state is the status bar's, so the Source badge loses its state text. The signals have no lock
(the badges and signal pages are direct manipulation), and the signals page lists only unacquired
signals and uncomputed math channels (plus the acquired ones while the badge bar has overflowed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Also wrap the signals page's hint line, which at 375 px minimum widened the whole slide-over panel to 376.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The per-signal page bypassed the signals lock for the acquire tick and the math
Edit/Delete buttons, and offered "Plot on r" for a plot the signal was already on.
A removed page also let another signal's page show during the close animation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The session old-file probe and save_scheduled now discriminate, Esc is read through the real key path, the dock-section probe proves the Measure section starts out of view, and the tour's spotlight is measured independently of the helper it is drawn from. A target scrolled out of its scroller no longer leaves the previous hole standing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The two drawn tab glyphs were judged not understandable enough; the
switcher goes to the wide policy with titles only, and the glyphs,
their gresource entries and the icon-naming code are removed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multicast was verified on a loopback group (239.255.42.99 on 127.0.0.1); a real network was not exercised.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The E-1608 source marks every restart as lost and logs each overrun; its form stops touching
siblings after the chooser destroys them; the link skips command id 0, retries a full-buffer
discover send and ignores a zero-length scan read. Session files escape \n and \r; get_int and
get_double reject out-of-range values; the UDPS port spin reports changes; a skipped source panel
says why on stderr. The E-1608 probe now checks the signal names and the reconnect itself.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Over SSH with X11 forwarding the app does not appear: no usable Vulkan device means GTK cannot
create a swapchain, and `--renderer cairo` fixes that half only -- the plot is a GtkGLArea and asks
for its own GL context, so indirect GLX is the second wall. A virtual X server on the machine that
runs the app sidesteps both, because the GL context then lives next door to the samples.
`tools/udpscope-remote.sh` starts Xvfb on a free display, runs the app there with
`--renderer cairo`, and serves the screen through x11vnc bound to localhost only -- the SSH tunnel
is the authentication, so `-nopw` is deliberate and `-localhost` is what keeps a mistake from being
a remotely reachable screen. It prints the tunnel and viewer commands rather than assuming a
client, mentions the websockify/noVNC route for a browser, and takes the X and VNC servers with it
when the app exits. `--no-vnc` leaves just the virtual display, for another viewer; the preflight
names the install command instead of a bare "command not found".
Verified: the preflight refuses with exit 1 and the install line when x11vnc is absent; with
`--no-vnc` the app runs against the virtual display and reads `buffer allocated: 4 channels` with
no Vulkan warning and no critical, and no Xvfb is left behind when the timeout ends it. That run
also exercises what the earlier log showed by omission: nothing is enabled, so a working app
plots nothing.
The README's Limitations gains the bullet a person actually needs -- the exact warning string, that
both halves need the software preset, the script itself, and that a window which appears but stays
empty usually means no signal is enabled.
GTK4 defaults to Vulkan, and an X11-forwarded display has no device to make a
swapchain from; the plot is a GtkGLArea, so it then asks for a GL context that
is not there either. --renderer cairo is the software preset for that display:
it exports GSK_RENDERER=cairo and LIBGL_ALWAYS_SOFTWARE=1 in main() before
gtk_init()/adw_init(), because both are read when the renderer and the context
are created. --renderer gl is the faster choice when indirect GL works, and
--renderer vulkan makes the default explicit. Nothing is exported, and GTK's
own choice stands, when the option is absent.
The once-a-second header line is now behind UDPSCOPE_PROBE_HEADER, following
the [notrace] rule: its widths are still sampled for the exit dump, but the
line is detail behind that reading rather than output every run prints.
UDPSCOPE_PROBE_RENDERER prints the exported pair before GTK starts and the
GskRenderer GTK actually built.
README, the manual's overview and docs/claude record the two symptoms and the
cure.
The plotter caps a density grid at kDensityCellCap now (deps/plotter), so a 2 s
window with persistence on no longer scales the image with the window: the
probe's four one-signal rows read 1 044 714 cells / 4 178 856 bytes where they
read 2 226 150 / 8 904 600, and a moved frame uploads 1 044 714 bytes where it
uploaded 2 226 150. The probe's own legs are unchanged (on peak=1.0000,
step-acquisitions peak=1.5000, step-time ratio=0.367879).
The paint probe no longer counts a frame the density is drawing as *traceless*.
`Renderer::draw_traces()` returns while the ink is the image, so every frame of
a persistence display stages no trace: the dump read `traceless paints: 653
(637 after the first bind)` for a run whose real figure is 4 (0), and the
`[notrace]` line printed for each of those frames. It is now behind
UDPSCOPE_PROBE_NOTRACE -- a per-paint line is a log flood and not a reading --
while the counters it details stay in every build, and the line stays reachable
for the state it was written for (a bound row that draws nothing).
Docs corrected where they stated the old rule: the README, the trigger
invariants, the density probe's readings, the verification list (the new
variable) and the manual page behind the panel's tooltip.
The plotter now deposits every acquisition -- the newest included -- into one grid per trace and
draws no solid trace over it, each grid in that trace's colour and with a one-sweep ceiling (its own
commit, **1b8b55d**). This side needed almost no change of its own, because the colour was already
the trace's and the trace's colour is `RowSet::signal_color()` -- the invariants' one route -- but the
figures it reads back are now per trace:
- **The ceiling is left at the library's default of one sweep**, no longer derived from the fade.
Deriving it from the steady state is the gain offset the user reported between the latest
acquisition and the persistent image; a signal crossing the same place every acquisition now settles
at the trace's colour, at full strength, and the newest sweep reads as the trace it is a picture of.
- **`cells`/`grid_bytes` are the sum over the row's traces** -- one grid each, a trace with no series
holding none -- and both the probe and the exit dump carry `traces=` beside `rows=`. That is what
makes the per-signal memory figure read: **556 537 cells and 2.2 MB per signal**, at 8904600 bytes
over the four one-signal rows of the probe's run.
The probes, re-read on this build (the `verification.md` command, `--rate 500000 --batch 1000`):
[density-probe] off enabled=0 ... rows=0 traces=0 cells=0 ink=0.0 peak=0.0000
[density-probe] on enabled=1 ... rows=4 traces=4 cells=2226150 ink=226786.0 peak=1.0000
[density-probe] step-acquisitions ... peak=1.5000
[density-probe] time-before ... peak=2.1359
[density-probe] step-time ... ratio=0.367879
[density-probe] frame cost: tick 0.62 -> 6.96 ms (184/23 frames), draw 2.02 -> 6.16 ms (177/18)
[udpscope] density: frames=748 rows=4 traces=4 cells=2226150 grid_bytes=8904600 ink=489400.2 peak=2.2 upload_bytes=2226150
`on` `peak=1.0000`, `step-acquisitions` `peak=1.5000` and `step-time` `ratio=0.367879` are the legs
that were expected, unchanged; the *draw* mean is now **below** the run before the split (2.02 -> 6.16
against 2.09 -> 20.91), because the solid traces are no longer drawn over the image.
Docs updated with it: the trigger manual page (`persistence` is the trace, one image per signal, the
newest included), the README's persistence section, `invariants-trigger-and-pinning.md` (five rules,
the ceiling and the no-stroke rule among them), `verification.md` and `probe-readings.md` (the lines
above), the trigger panel's comment and tooltips, and the plotter submodule.
`cmake --build build --clean-first -j4`: **0 errors, the documented three warnings** (two
`MathNode::source`, one `-Woverlength-strings` at 12352); `make -C build test-ui` **13 ok**;
`make -C build test-help` **green** (15 pages); the self-check **0 `Gtk-WARNING`/`Gtk-CRITICAL`** and
`gtk warnings: 0`, two `buffer allocated:` lines.
The library's `full_scale` now defaults to the default fade's steady state and `gamma` to 1.0 (its
own commit); this side states the ceiling for the fade *it* configured, because that is what the
ceiling means: the ink the display settles at, so the newest acquisition is a fraction of full ink
and white is reached only where acquisitions agree.
- **acquisitions**: `1/(1 - factor)` -- the geometric sum, 2.0 at the panel's 0.5, and 1.0 at 0
(only the newest sweep, at full ink).
- **time**: the library's default of two sweeps. A time fade has no fixed steady state -- it
settles where the trigger's rate and the constant meet, which is the *point* of it -- so a fast
trigger reads brighter than a slow one the way a phosphor's does.
- `gamma` is left at the library's 1.0: a cell is a count of sweeps, so half as many must read as
half the ink. With the ceiling at one sweep and gamma at 0.45 (the library's first defaults) one
sweep was already full white and every display looked the same -- which is exactly what the user
reported seeing, and why the assertion for it is a framebuffer one in the library's case
(`empty=21 full=83 quarter=54`) rather than anything `ink`/`peak` can say.
The probe's own figures are unchanged in kind (they are the grid's): `on` `peak=1.0000`,
`step-acquisitions` `peak=1.5000`, `step-time` `ratio=0.367879`, `off` all zeros -- re-read on this
build, with the frame cost `tick 0.53 -> 7.49 ms`, `draw 1.89 -> 16.78 ms` and `gtk warnings: 0` in
the same run. The trigger/pinning invariants carry the ceiling rule and why the eye found it.