|
Item 200. Another program that knows which message it cares about has no way
to say so: qtmaildir accepts no arguments beyond --version and --help.
Three decisions from the user shape it. A second launch STEERS the running
window over a QLocalServer rather than opening a second one, which is what the
note's own framing needs, since a caller will usually find the client already
running, and it fixes the two-notmuch-handles problem that exists today as a
side effect. The selectors are --account, --thread and --message; --query was
dropped as the most general and the one with no caller, the query bar already
serving the only party who would type one. A selector matching nothing opens
the window normally and names the miss in the status bar, rather than showing
an empty result that makes a stale link look like a broken client.
The design shrank on one side and grew on the other. recoverStaleThread()
already runs thread:<id>, holds its target across the two queued round trips a
load takes, expands when the row arrives and selects the message when the
replies land; item 91's double-click reuses it and a CLI selector is a third
caller, so the selectors are the small half. The socket is the real work:
connect-first ordering, which is also how a stale socket file is detected,
stale-socket recovery, and a degrade path that starts the window anyway when no
socket is possible. It adds Qt6::Network to a component list that is currently
Widgets, Svg and WebEngineWidgets.
Quoting is the security-relevant part and is called out. Existing code
interpolates ids unquoted because they came from notmuch itself; an id from
argv did not, so every one goes through SearchTerm::quote(). notmuch parses
garbage happily and matches zero, so this cannot be checked by asking it.
Raising the window under a Wayland compositor is handed to the user to look at
rather than tested: it is compositor policy and the offscreen platform reports
the same result whatever the code does.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P3HQXLauwQgzxR4YfJBB3x
|