Files
udpscope/help/C/org.udpscope.app/sessions.page
T
Martino Ferrari c1460a6977 feat: the manual is a Mallard set opened in Yelp, not a GResource in the binary
The help was 14 Pango-markup `.txt` bodies in a second GResource, drawn into a paged `GtkWindow`
built in `help_window.cpp`. That made F1 a viewer of ours with no search index, no cross-references
and no translation, and it kept the manual in the *binary* when every other desktop application's is
a document on disk. It is now a real Mallard set:

  help/C/org.udpscope.app/  index.page + 14 topic pages + figures/*.png

and `show_help()` hands `help:org.udpscope.app` to whatever the desktop registered for the `help:`
scheme -- Yelp on GNOME -- through a `GtkUriLauncher`, reporting a launch failure with a
`GtkAlertDialog` rather than a click that silently does nothing. The paged window's builder, the
page table and `help_self_check()`'s markup validation are gone with the resource.

The document identifier is the desktop file's own basename (its desktop-file id), derived in
CMakeLists from `data/org.udpscope.app.desktop.in`, so the same string is the `.desktop` name, the
GApplication id and the install directory at once. The set is installed by a new `install()` rule to
`<datadir>/help/C/org.udpscope.app/` -- where the freedesktop Help System Specification's `help:`
URI resolves `help:<id>` -- so the manual is read from a datadir by another process even though the
binary has no install step. `UDPSCOPE_HELP_NAME` and `UDPSCOPE_HELP_DIR` are compiled in from that
one place.

The 14 pages were migrated fact for fact, but restructured the Mallard way: a `<desc>` per page
(what a search result shows), `<steps>` for procedures, `<terms>` for option lists,
`<gui>`/`<key>`/`<keyseq>` for interface words and keys, `<note>` for the asides, and a topic graph
via `<link type="guide" xref="index#main"/>`. The figures are annotated screenshots produced by
`tools/make-help-shots.sh`, which drives the app headlessly against `tools/mock_udpstreamer.py` and
draws the boxes with ImageMagick; the side panel's box is measured from the app's own `side=NNNx`
dump reading, the header and status bands come from a documented table, and a crop whose standard
deviation is 0 fails the script.

`cmake --build build --target test-help` checks the set the way `test-ui` checks the `.ui` files:
`yelp-check`'s offline subcommands (links, media, orphans, ids) and a `yelp-build html` render.
`yelp-check validate` is deliberately absent -- it fetches the Mallard RelaxNG schema over the
network and fails offline for that reason, not for a fault in the pages.

The `[help]` probe reading changes with the resource it was written for. `parsed == pages` over
in-binary markup cannot exist now, so `help_self_check()` scans `UDPSCOPE_HELP_DIR` and the line
reads `topics=14 index=1 figures=3`; `topics=0 index=0` is the manual missing from the tree, which
is the finding the old count named.

Verified: clean build with the documented three warnings (the help bundle's `-Woverlength-strings`
is gone, so the baseline moves from four to three); test-ui 14/14; test-help clean (the four
subcommands and 15 pages rendered); a temp-prefix install lands 15 `.page` files and 3 figures at
`share/help/C/org.udpscope.app/`; the headless run reads `[help] topics=14 index=1 figures=3 dir=...`
with 0 Gtk-CRITICAL. Yelp's own window could not be exercised on this box -- it starts under Xvfb,
activates its portals and never maps, the same WebKit/portal limitation that stops a grab -- so its
rendering and its search index are unverified here; the content pipeline was (`yelp-build` renders
the whole set).

Docs: the manual's build/install/open story in `build-and-run.md` and README; the warning baseline
in `verification.md`/CLAUDE.md; the help bullets in `invariants-gtk-and-chrome.md`; the `[help]`
line in `probe-readings.md`.
2026-10-14 16:49:30 +02:00

94 lines
4.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<page xmlns="http://projectmallard.org/1.0/"
type="topic" style="task"
id="sessions">
<info>
<link type="guide" xref="index#output"/>
<link type="seealso" xref="source"/>
<desc>Per-source configuration files: where they live, what they persist, and how the
chooser and the Configurations dialog use them.</desc>
<credit type="author copyright">
<name>Martino Ferrari</name>
</credit>
</info>
<title>Sessions and settings</title>
<p>udpscope stores named sessions — <em>configurations</em> — per source, so reopening a
source gives you the scope you closed, and one source can hold several arrangements for
different experiments. There is no global preferences file: the session <em>is</em> the
settings.</p>
<section id="reach">
<title>How to reach it</title>
<p>Nothing to open — the file is written as you work. Its path is in the About dialog, and
the directory is <file>$XDG_CONFIG_HOME/udpscope</file>, or <file>~/.config/udpscope</file>
when that is unset. Each source has a directory <file>&lt;host&gt;_&lt;port&gt;/</file>
holding one <file>&lt;name&gt;.toml</file> per configuration and an <file>active</file>
file naming the one it is on.</p>
</section>
<section id="configs">
<title>Configurations</title>
<p><gui>Configurations…</gui> in the menu lists the running source's configurations: click
a row to open it, <gui>×</gui> to delete it, or type a name and a note and press
<gui>Save this session</gui> to keep the current arrangement under a new one. Opening a
configuration saves the current session first, so switching never loses what it switches
from.</p>
<p>The startup chooser (start with no <cmd>--server</cmd>) lists one row per configuration,
with its note and its settings, so two arrangements of one source are told apart before
they open.</p>
<p>A configuration also carries the settings that can only be decided when the buffers are
allocated: the <gui>buffer size</gui> (<cmd>--buffer-mb</cmd>), relative time, and the
packet capture's ring size. Opening a configuration from the chooser applies all three;
switching inside a running app applies the rest and says in the status line that these take
effect on the next start.</p>
<p>The chooser's form sets the first two for a new host, and its pencil button edits them
on an existing configuration — along with the name and the note. Renaming a configuration,
or editing the address it points at, moves it: the old file is removed rather than left
behind.</p>
</section>
<section id="knowing">
<title>Worth knowing</title>
<list>
<item><p>What a configuration persists: the time window, the rows and each row's slot
signals, the calibration, the trace colours, which signals were enabled, the math
channels with their graphs, the measurements pane — and the startup settings: buffer
size, relative time and the packet capture's ring size.</p></item>
<item><p>Signal identity is the <em>name</em> throughout, because a new CONFIG renumbers
the channels.</p></item>
<item><p>A file written by a run against a source whose streamer was down would name no
signals at all, so such a run does <em>not</em> write: a configured session is never
overwritten by a run that configured nothing. (The chooser hides such a file for the same
reason.)</p></item>
<item><p>The multicast group and the interface live <em>inside</em> the file, because its
name cannot carry them. A file from an older build has neither key and loads as unicast
on the default route.</p></item>
<item><p>The chooser lists only configurations that name at least one signal, which is
what keeps it the sessions you configured rather than every port you have ever tested
against.</p></item>
<item><p>Deleting a configuration is a supported way to start over; the chooser's
<gui>×</gui> and the dialog's do exactly that.</p></item>
<item><p>A session from before configurations existed is imported once as the
configuration <code>default</code>, and the old file is kept beside the directory as
<file>&lt;host&gt;_&lt;port&gt;.toml.imported</file>.</p></item>
</list>
</section>
<section id="example">
<title>Example</title>
<p>Connect to <code>127.0.0.1:8000</code>, drop three signals on row 1, set a 2 s window,
and save the session as <code>bench</code> with a note.
<file>~/.config/udpscope/127.0.0.1_8000/bench.toml</file> now holds
<code>window_s=2 comment="…"</code> with
<code>signals = ["sine", "ramp", "noise", ""]</code>, and the next run reports
<code>layout loaded from …/127.0.0.1_8000/bench.toml</code> with those signals already
acquired.</p>
</section>
</page>