Skip to content

Tray app + Eduuh-DH docs images - #18

Merged
eduuh merged 2 commits into
mainfrom
tray-app-and-eduuh-dh-images
May 25, 2026
Merged

eduuh merged 2 commits into
mainfrom
tray-app-and-eduuh-dh-images

Conversation

@eduuh

@eduuh eduuh commented May 25, 2026

Copy link
Copy Markdown
Owner

Summary

Two intertwined changes — the runtime starts behaving like a proper system-tray daemon, and the docs finally show what each Eduuh-DH layer actually does.

  • tray app: link Release as WINDOWS subsystem with modal errors and auto-takeover — keyflow.exe no longer pops a console when launched. Fatal startup errors surface via MessageBox instead of silent exit. WindowsPlatformInit pins CWD to the exe dir so config.json resolves from any launcher (HKCU\Run, shortcuts, PowerShell). Single-instance lock now auto-terminates older instances on a second launch instead of refusing to start. Three CLI flags (--version, --validate, --list-bindings) were dropped because the MSVC CRT silently breaks std::cout under SUBSYSTEM:WINDOWS — --debug / --verbose (file logging) kept.

  • eduuh-dh: remap LeftWin→LeftAlt + screenshot pipeline for layer docs — src/config.json adds "LeftWin": "LeftAlt" (LWin acts as a second LeftAlt on laptops; Start menu still reachable via Ctrl+Esc). New designer/app/screenshot/ route + Playwright spec produce per-layer PNGs committed to docs/images/. Render rewritten with role-based color coding (modifiers amber, letters slate, punctuation teal, navigation indigo, layer outputs violet), full-word modifier labels (Shift, Ctrl, Alt, Win — no more L⇧ / L⌃), and per-keycap shadows. BASE rendering now correctly reflects noModCombos so the number row shows ? ! [ ] " { } * / ' ) ( \. Run via npm run capture-images.

Test plan

  • ./build.ps1 -Tests — all 38 unit tests pass
  • ./build.ps1 — Release builds; double-click builds/Release/bin/Release/keyflow.exe → no console, tray icon appears, right-click → Status/Exit work
  • Bad config: rename config.json next to the exe → MessageBox describes the problem
  • Launch a second instance while one is running → first instance terminates, second takes over (no error dialog)
  • LeftWin alone does not pop the Start menu; LeftWin+I produces 4 (Numpad layer); Ctrl+Esc opens the Start menu
  • cd designer && npm run capture-images regenerates the four images; PNGs are under 200 KB each
  • docs/EDUUH_DH.md renders correctly with all four images embedded

Out of scope

  • Pre-existing uncommitted designer changes (KeyPicker.tsx, Key.tsx, Keyboard.tsx, LayerTabs.tsx, layout.tsx, tailwind.config.ts, lib/keyDisplay.ts, lib/layerColors.ts) were left untouched — those belong to a different workstream.
  • The round-trip.spec.ts test fails on main and continues to fail here (unrelated — header JSON button no longer triggers a download in the current UI; the test expects the old behavior).
  • The /screenshot/ route uses an absolute /eduuh-dh-config.json fetch path that 404s on the GitHub Pages deployment (under /keyflow/). It's a local dev tool, not a production page — fixing the basePath is a separate concern.

🤖 Generated with Claude Code

eduuh and others added 2 commits May 25, 2026 20:16
…o-takeover

Release builds now link with /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup so
keyflow.exe no longer pops a console when launched. Process lives in the
existing system tray. Debug builds keep CONSOLE subsystem for developer
output.

Three follow-on changes were required to keep the app usable as a true
tray daemon:

- showFatalError() on IPlatformInit surfaces startup failures (bad config,
  missing Interception driver, instance-lock contention) via MessageBox so
  Explorer-launched users actually see why the process exited. stderr still
  fires in parallel for shell launches.

- WindowsPlatformInit's constructor calls SetCurrentDirectoryW(exe_dir) so
  config.json, keyboard-icon.ico, and keyflow_debug.log resolve next to the
  exe regardless of how Windows hands off CWD (HKCU\Run, shortcuts, etc.).

- WindowsSingleInstanceLock auto-takeover: a second launch enumerates
  processes by exe basename, terminates any siblings, sleeps 200 ms for the
  OS to release the mutex, and retries. The MessageBox only fires when
  takeover itself failed (permission denied / runaway mutex).

Also drops the --version, --validate, --list-bindings CLI flags and their
printer functions: under SUBSYSTEM:WINDOWS the MSVC CRT doesn't bind stdout
to inherited handles, so those flags were silently broken from PowerShell.
Better to delete than maintain dead code; --debug and --verbose (which
writes to a log file) stay.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
src/config.json: add "LeftWin": "LeftAlt" so the left Windows key acts as
a second LeftAlt (laptop ergonomics fix). Inherits LAlt's role as the
Numpad layer trigger; Start menu still reachable via Ctrl+Esc.

docs/EDUUH_DH.md: new row in the Modifier remaps table, design note
explaining the Start-menu trade-off, and four embedded layer images at
the hero, base, numpad, and arrows sections so readers can see the
layout instead of parsing prose tables.

Designer screenshot pipeline:

- designer/components/Export/ExportKeyboard.tsx (new): extracted from the
  inline component in CategoryExport.tsx and given two props — `scale`
  for high-DPI export and `layerFilter` ("all" | "base" | layer index)
  for per-layer rendering. Visuals rewritten: each keycap shows its
  FINAL output (what pressing it produces) at full clarity with a
  role-based color (modifiers amber, letters slate, punctuation teal,
  navigation indigo, layer outputs violet, special neutral). Drop
  shadow + top highlight for depth. Long modifier names ("Shift",
  "Ctrl", "Alt", "Win") replace the cryptic L⇧/L⌃/L⌥/L⊞ glyphs.

- designer/app/screenshot/page.tsx (new): client-only route that reads
  ?layer= from window.location.search and renders just the keyboard
  in a mounting-plate frame. Loads the bundled config via fetch from
  /eduuh-dh-config.json (synced into public/ by predev/prebuild).

- designer/scripts/copy-config.mjs (new): predev/prebuild hook that
  copies src/config.json → designer/public/eduuh-dh-config.json.
  Required because Turbopack refuses cross-root imports.

- designer/tests/capture-images.spec.ts (new): Playwright spec that
  iterates over [all, base, 0, 1] and snapshots #screenshot-root to
  docs/images/eduuh-dh-{name}.png. Run via `npm run capture-images`.

- designer/playwright.config.ts: split into chromium (testIgnore the
  capture spec) and capture projects. Capture uses deviceScaleFactor=2,
  1400×600 viewport. Dev server moved to port 3100 to dodge Windows'
  invisibly-reserved port 3000 (WSL/Hyper-V reservation).

- designer/package.json: copy-config, predev, prebuild, capture-images
  scripts.

BASE rendering now includes noModCombos via a US-QWERTY shift map so
the number row correctly shows ? ! [ ] " { } * / ' ) ( \ — the
characters actually produced, not the raw digits.

CategoryExport dialog inherits the new visuals automatically since it
shares ExportKeyboard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@eduuh
eduuh merged commit 10cf560 into main May 25, 2026
2 checks passed
@eduuh
eduuh deleted the tray-app-and-eduuh-dh-images branch May 25, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant