docs: the app icon, AdwAboutDialog and the desktop entry
Records the app icons: assertion and why it stops short of claiming the icon renders -- no runtime GTK call can tell a malformed SVG from a good one, which is why the manifest validates through xmllint at build time instead. Scopes the 'filled paths only' authoring rule to symbolic icons, since the colour icon strokes its sine and is never recoloured. Revises the windows invariant to one GtkWindow and two AdwDialogs, and documents the desktop-entry target with the build-path caveat it comes with. Two findings from the regression run are recorded as well. The icons' generated GResource crossed C99's 4095-byte string-literal limit when the app icons joined the action ones, so the build's warning baseline is five, not four. And the app icons: line's has_icon() half is satisfied by an installed theme copy, so on a machine that has run --target desktop-entry it reads ok even with the resource path broken; toolbar icons: is the sensitive line for that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
f2978fe742
commit
e2be597698
2 files changed
+167
-15
No files matched your search
@@ -252,6 +252,80 @@ The same reason the window control is a fixed-width label in the header bar
|
||||
not expand: a header-bar child that expands is measured into the title's centre
|
||||
box, so the control stretched to the title and every window resize moved it.
|
||||
|
||||
## The icon, the About dialog and the desktop entry
|
||||
|
||||
**The icon is the instrument face**: a dark panel carrying one bold green trace. That is the
|
||||
clearest metaphor available for this program -- it is what the thing being imitated looks like --
|
||||
and it is the kind of physical object the GNOME HIG's top-and-front depth language was written
|
||||
for, so the guidelines apply as written rather than by analogy. Its silhouette is also what makes
|
||||
it survive being scaled down, which is why two alternatives were dropped: a bare waveform (no
|
||||
silhouette at all, so nothing is left of it in a dock) and a colour version of the trigger glyph
|
||||
the toolbar already carries (a *control*, not the application, and it would mean two icons that
|
||||
have to stay in step).
|
||||
|
||||
It is built to the HIG's own numbers. A 128px canvas the artwork does not fill (it spans
|
||||
x 12..116, y 22..106), every feature on the 2px grid, and **one** depth treatment: a 4px front
|
||||
profile along the bottom, clipped to the chassis silhouette so it does not protrude past the
|
||||
rounded corners. The rest is flat colour -- no gradients, no shadows -- because every surface
|
||||
here is straight, and the palette is GNOME's (Dark 3 chassis, Dark 2 profile, Dark 4 screen,
|
||||
Green 1 trace).
|
||||
|
||||
**Two things were deliberately left out.** There is no graticule: the grid lines a real scope
|
||||
face carries cannot survive 32px, and the trace carries the metaphor without them. And the trace
|
||||
is one cycle -- a single crest, a single trough -- because at 32px the screen is about 22x16 px
|
||||
and anything busier reads as a smudge.
|
||||
|
||||
The two forms are authored differently on purpose. The colour icon **strokes** its sine, which is
|
||||
the sane way to draw a smooth curve; the 16px symbolic one cannot, because GTK's symbolic
|
||||
recolour wraps the file in a stylesheet that reaches `fill` on `path`, `rect` and `circle` only,
|
||||
so a stroked line keeps the colour written in the file and stays dark on a dark theme. Its wave is
|
||||
therefore a closed 2px band -- a sine along the top edge and the same sine 2px lower along the
|
||||
bottom. Do not "fix" one to match the other.
|
||||
|
||||
Both are compiled into the binary as a `GResource` under `scalable/apps/`, for the same reason
|
||||
the four action icons are: udpscope is run straight out of its build tree and has no install step.
|
||||
The one consequence worth knowing is that a **malformed** SVG cannot be caught at runtime -- the
|
||||
icon *name* still resolves, so GTK reports the icon as present and draws nothing -- which is why
|
||||
every `<file>` in the manifest carries `preprocess="xml-stripblanks"` and the build fails with a
|
||||
file, line and column instead.
|
||||
|
||||
**The About dialog is an `AdwAboutDialog`** rather than a `GtkAboutDialog`, and that migration is
|
||||
what the app has an icon *for*: the dialog shows it in its own header, which `GtkAboutDialog`
|
||||
would too but only after being handed one, and nothing else in the program had asked for a
|
||||
128px rendering. Two further gains came with it. The debug information is a **Troubleshooting
|
||||
page with a copy button**, where `system_information` on the old dialog was inert text a user
|
||||
reporting a problem had to retype. And the string it shows is a `std::string`, which removed a
|
||||
`char[1024]` that truncated a long settings path in silence -- the one failure mode of a fixed
|
||||
buffer that no one notices until the path matters.
|
||||
|
||||
What it cost: an `AdwAboutDialog` is an `AdwDialog` and **not** a `GtkWindow`, so its close path
|
||||
differs from the help window sitting beside it -- `adw_dialog_close()` and `::closed`, rather than
|
||||
`gtk_window_close()` and `::close-request`. That is the same trap the shortcut overview already
|
||||
had, and the two now share one `::closed` handler keyed by the pointer it must null. What was
|
||||
deliberately left out: credits (one author, already named), release notes (there are no releases)
|
||||
and an issue-tracker URL (the website link reaches the repository, which carries the tracker).
|
||||
|
||||
**The desktop entry is opt-in.** `cmake --build build` never touches `$XDG_DATA_HOME`; asking for
|
||||
it does:
|
||||
|
||||
```sh
|
||||
cmake --build build --target desktop-entry
|
||||
```
|
||||
|
||||
That writes `org.udpscope.app.desktop` and both app icons under `$XDG_DATA_HOME` (default
|
||||
`~/.local/share`), validates the entry with `desktop-file-validate` as a hard failure, refreshes
|
||||
`update-desktop-database` and `gtk4-update-icon-cache` if they are on `PATH`, and prints the three
|
||||
paths it wrote. Those three lines **are** the uninstall instructions: there is no uninstall
|
||||
target, because three `rm`s the build already told you about are less to maintain than a target
|
||||
that has to guess what a previous version installed.
|
||||
|
||||
The caveat is the entry's `Exec`, which is the built binary's **absolute path in the build tree**:
|
||||
moving or deleting `build/` breaks the launcher. That is the price of having no install step, and
|
||||
it is the right trade here -- the entry then always launches exactly the binary that was last
|
||||
built, which for a program under development is what you want. No `StartupWMClass` is needed:
|
||||
GTK takes the WM class from the application ID, and the desktop file's basename is that same
|
||||
string, which is what associates a running window with the entry.
|
||||
|
||||
## How the spec maps onto the code
|
||||
|
||||
**One buffer of `N+1` slices, plus frozen event snapshots.** `ScopeModel`
|
||||
|
||||
Reference in new issue
Block a user