Skip to content

fix(linux): correct mid-transcript submits, and unify releases across macOS and Linux - #23

Merged
itisrmk merged 2 commits into
mainfrom
t3code/optimize-app-memory
Aug 30, 2026
Merged

itisrmk merged 2 commits into
mainfrom
t3code/optimize-app-memory

Conversation

@itisrmk

@itisrmk itisrmk commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Two things, both about shipping Linux properly.

1. Text injection could submit a half-typed transcript

Dictating more than ~100 characters into a chat box dropped characters and then
submitted the field partway through. Root cause is wtype -: its stdin mode
types in 100-character batches and re-uploads a growing keymap between them,
so any character first seen after the 100th arrives while the client still
holds the previous keymap. It carries no keysym and is dropped — and the one
that lands on wire keycode 28 (KEY_ENTER) is read as a bare Return by clients
that map hardware codes directly, which submits the field.

Reproduced exactly on Hyprland with an Electron chat box: a 260-character
dictation lost every letter it had not already used (do → o, Linux →
inu, because → ecause) and submitted at the apostrophe of it's — the
28th distinct character.

Fixed by passing the transcript in argv after --, which takes wtype's other
path: it resolves every keysym up front and uploads the keymap once, before the
first keystroke. Multi-line transcripts now go through the clipboard instead,
since wtype types a newline as Return where both macOS strategies insert it as
text. Verified working on a real desktop.

2. Releases now ship both platforms from one tag

The previous workflow attached Linux artifacts to a tag the macOS job had
already published, so a Linux failure would leave a release with half its
artifacts. Restructured to params → (macos ‖ linux) → publish: both builds
run in parallel from the same commit, and the appcast commit, version bump, tag
and release all happen after both pass.

  • One version number, one owner: linux/packaging/set-version.sh stamps the
    Cargo manifest, lockfile and both PKGBUILDs; the Linux job asserts the built
    binary reports it; the AUR checksum is computed from the tag tarball.
  • Release notes composed once (scripts/compose_release_notes.sh) and reused
    by the GitHub Release and the Sparkle appcast.
  • CI runs both platforms on every PR (macos-ci.yml → ci.yml).
  • docs/RELEASE.md replaces the DMG-only guide; README leads with both
    platforms.

Labelled skip-release — the release will be dispatched manually with an
explicit version and notes.

itisrmk and others added 2 commits August 30, 2026 16:06
`wtype -` types stdin in 100-character batches. It assigns keycodes to
characters as it first meets them, so between batches it uploads a new,
larger keymap and immediately resumes sending key events. Clients apply a
keymap asynchronously, so every character first seen after the 100th
arrived while the client still held the previous keymap: with no keysym it
was silently dropped, and the character that landed on wire keycode 28 —
KEY_ENTER — was read as a bare Return by clients that map hardware codes
directly, submitting the field halfway through the transcript.

Observed on Hyprland with an Electron chat box: a 260-character dictation
lost every letter it had not already used ("do" -> "o", "Linux" -> "inu",
"because" -> "ecause") and submitted at the apostrophe of "it's", the 28th
distinct character.

Pass the transcript in argv after `--` instead. That takes wtype's other
path, which resolves every keysym up front and uploads the keymap once,
before the first keystroke. Command::arg goes to execve verbatim, so the
quoting concern behind the stdin call site never applied.

Also route multi-line transcripts to the clipboard: wtype types a newline
as Return, which submits a chat box rather than inserting a line break,
where both macOS strategies insert it as text.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Linux port shipped in b3ac2c7 but nothing tagged since, so the DMG was
still the whole of a release in practice. The workflow that was meant to fix
that attached Linux artifacts to a tag the macOS job had already created and
published, which is unification in name only: the tag exists before the Linux
build runs, so a Linux failure leaves a released version with half its
artifacts, and the Linux binary carried whatever version linux/Cargo.toml
happened to hold.

Restructure it as params -> (macos || linux) -> publish. The version, channel
and changelog range are resolved once, the two builds run in parallel from the
same commit, and every push — the appcast commit, the version bump, the tag,
the release — happens in publish, after both have passed. A failure on either
platform now leaves nothing behind to clean up.

Version becomes a single number with one owner: linux/packaging/set-version.sh
stamps the Cargo manifest, the lockfile and both PKGBUILDs, the Linux job
asserts the built binary reports it, and publish commits the same stamp
alongside the appcast. The AUR checksum is computed from the tag tarball once
the tag exists, which was the last manual step.

Release notes are composed once by scripts/compose_release_notes.sh and reused
by the GitHub Release and the Sparkle appcast, with a download table naming
both platforms' artifacts and their install commands.

Also: CI now runs both platforms on every PR (macos-ci.yml -> ci.yml), so a
green PR means both halves of a release can be cut from it; docs/RELEASE.md
replaces the DMG-only guide; the README leads with both platforms rather than
treating Linux as an appendix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@itisrmk itisrmk added the skip-release Merged PR does not trigger an automatic release label Aug 30, 2026
@itisrmk
itisrmk merged commit fb42326 into main Aug 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-release Merged PR does not trigger an automatic release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant