Repository navigation
Tray app + Eduuh-DH docs images - #18
Merged
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.exeno longer pops a console when launched. Fatal startup errors surface viaMessageBoxinstead of silent exit.WindowsPlatformInitpins CWD to the exe dir soconfig.jsonresolves 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 breaksstd::coutunderSUBSYSTEM:WINDOWS—--debug/--verbose(file logging) kept.eduuh-dh: remap LeftWin→LeftAlt + screenshot pipeline for layer docs—src/config.jsonadds"LeftWin": "LeftAlt"(LWin acts as a second LeftAlt on laptops; Start menu still reachable via Ctrl+Esc). Newdesigner/app/screenshot/route + Playwright spec produce per-layer PNGs committed todocs/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 moreL⇧/L⌃), and per-keycap shadows. BASE rendering now correctly reflectsnoModCombosso the number row shows? ! [ ] " { } * / ' ) ( \. Run vianpm run capture-images.Test plan
./build.ps1 -Tests— all 38 unit tests pass./build.ps1— Release builds; double-clickbuilds/Release/bin/Release/keyflow.exe→ no console, tray icon appears, right-click → Status/Exit workconfig.jsonnext to the exe →MessageBoxdescribes the problemLeftWinalone does not pop the Start menu;LeftWin+Iproduces4(Numpad layer);Ctrl+Escopens the Start menucd designer && npm run capture-imagesregenerates the four images; PNGs are under 200 KB eachdocs/EDUUH_DH.mdrenders correctly with all four images embeddedOut of scope
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.round-trip.spec.tstest fails onmainand continues to fail here (unrelated — headerJSONbutton no longer triggers a download in the current UI; the test expects the old behavior)./screenshot/route uses an absolute/eduuh-dh-config.jsonfetch 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