Repository navigation
Held-key check reads HID state and names a key it waits on - #1335
Conversation
Startup refused Caps activation with physicalKeysHeld three times on the mini on 2026-10-20. Combined session state reported Space held while HID state and every keyboard had released it, and the wake recovery loop waited on it silently for hours. The check now reads HID state, which was clear throughout. Because a posted press can still hold HID state, the wake recovery loop names the held key after 5 seconds and asks for it to be pressed and released. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Review of PR 1335: no blocking issues. Three things worth checking:
Minor: the docs say posted presses can still reach HID state and the root cause is unestablished. The fix therefore narrows the failure rather than removing it, and the 5s warning is the only mitigation for that case. That seems acceptable, but it's worth keeping the bug doc open or linked to a follow-up. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5ebf3ef0e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if Date().timeIntervalSince(since) >= 5, !held.isEmpty, held != namedHeldKeys { | ||
| namedHeldKeys = held | ||
| AppLogger.shared.warn("[SessionRuntime] Wake recovery waiting on held key codes \(held)") | ||
| onWarning?(Self.heldKeysWarning(held)) |
There was a problem hiding this comment.
Publish the named held-key warning
When a key remains held for five seconds, this updates lastWarning through onWarning but never calls onStateChanged. The UI is event-driven—StatePublisherService emits a new snapshot only when notifyStateChanged() is called—and the lifecycle warning callback in RuntimeCoordinator only assigns the value. Consequently, during the indefinite held-key wait the user continues seeing the generic warning, and a successful resume clears the named warning before the next state publication. Trigger onStateChanged after replacing the warning so the new actionable message is actually shown.
Useful? React with 👍 / 👎.
Problem
On the mini on 2026-10-20, KeyPath started without its engine three times (11:01, 14:09, 14:18). Each start refused Caps activation with
physicalKeysHeld, and the wake recovery loop loggedheld-keysonce and then waited silently for hours. All you could see was "Remapping will resume when your keyboard session is ready."requirePhysicalAllUp()read.combinedSessionState, which reported Space (keycode 49) held..hidSystemStatedid not. No keyboard was holding Space: pressing it on the cl80 and unplugging the fixture and the X2A changed nothing. One posted Space key-up at the session tap cleared it.Change
requirePhysicalAllUpreads.hidSystemState, which was clear throughout the incident. The check exists so a Caps Lock hidutil mapping never changes mid-press, and hidutil acts on HID events. The key-state reader is injectable for tests.held-keys, the wake recovery loop now logs the key codes and warns: "Remapping is waiting because macOS reports the “space” key as held down. Press and release it to resume."docs/bugs/stale-synthetic-key-blocks-startup.mdrecords the incident, what is and isn't established, and how to clear it by hand.Verification
SessionCapsRuntimeSupportTests,SessionFailureRecoveryMessageTests,ServiceLifecycleCoordinatorTests: 52 passed (run-tests-safe.sh).[49]vs hid[]during the incident, and the posted-event behaviour of both records.Review gate
./Scripts/review-gate.shcould not run locally (the Claude login expired), so the remote review gate is selected. Do not merge until GitHubclaude-reviewpasses.🤖 Generated with Claude Code