Qol improvements - #8
Conversation
…w report processing and comprehensive logging, and refine button mapping logic.
|
Hey @JoshGatto — wow, this is a seriously impressive contribution! The Hypershift implementation is really well thought out, the media key support fills a big gap, and the UI redesign looks clean. A lot of care went into this and it shows. I went through the changes carefully and have some feedback I'd love to work through together before we merge. Nothing here is a dealbreaker — I think we can clean this up collaboratively and get it into great shape. Things to fix before merging
Nice-to-haves (we can tackle together in follow-up commits)
What's great
|
- Remove .DS_Store and add dist/ to .gitignore - Fix finishLearning() cooldown with dedicated isCoolingDown flag - Guard nil binding save on learn timeout - Replace unreliable shell commands with CGEvent HID for missionControl - Remove appExpose, appsGrid, controlCenter (no reliable macOS API) - Fix hypershift stuck-on with explicit hold/toggle modes - Auto-save on setHypershiftAction and setBothActions atomic write
…ng-hold escape - showDesktop: replace osascript shell call with CGEvent(virtualKey: 103) consistent with missionControl approach; no subprocess, no sandbox friction - hypershift toggle: long-hold release (>0.5s) force-deactivates Hypershift giving users an intuitive escape hatch without changing tap-to-toggle UX
|
Hey @DParent10 glad you like the updates! Sorry have been a bit busy but have pushed through some fixes for that feedback you gave, awesome work on the project happy to be helping out! |
|
@DParent10 Good for review? |
|
Hey @JoshGatto — went through all of this carefully and you got every single point from my review. Really nice work. Quick rundown on the must-fixes: Nice-to-haves are all in there too — dead code removed, defaults cleaned up, One thing I want to dig into before merging — the
The Hypershift toggle escape looks right in the code too, I just want to feel it out on hardware before we ship. I've been away from home without my Mac, so I can't do the final |
…isting - Replace hardcoded Razer Naga checks with a generalized whitelisting architecture (isWhitelistedMouse) - Store optional vendorID and productID in HardwareBinding when learning - Restrict keyboard-page (0x07) mappings at runtime to matching device VIDs to prevent keyboard shadowing - Remove unknown 0x2442 VID whitelist entry
|
@DParent10 Thanks, I think I've attempted refactoring the code to better support the hardware learning like you suggested so its not razer specific, althought have kept the whitelisted id's. Let me know your thoughts |
|
Hey @DParent10 haven't heard from you, what are your thoughts on this? |
…ismiss
Two bugs in the hardware learning path:
1. `return` inside a `queue.sync` closure exits only the closure, not the
enclosing function. In `handle(value:)` and `triggerVirtualButton`,
execution fell through to the button-index lookup, so learning a
non-keyboard button both trained the binding and fired the action
already bound to it. Applies the same `if isLearning { return }` shape
the keyboard path already used.
2. `ActionEditorViewController.viewWillDisappear` restarted the event tap
without clearing the learning callbacks. Those live on singletons, so
dismissing mid-learn left the tap returning nil for every keyDown and
flagsChanged system-wide — swallowing keystrokes, and permanently if
the view controller had been deallocated.
Not compiled or tested; authored on Windows against a macOS-only target.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Hey @JoshGatto — sorry for the slow reply, and thanks for sticking with this. Went through the whole diff. The cleanup is much appreciated (dropping the I found two bugs and pushed fixes to your branch. Fair warning that I'm working off my Windows machine at the moment, so none of this is built or tested — it's all from reading the diff. 1. In queue.sync {
if let callback = learningCallback {
callback(usagePage, usage, cookie, activeVal, vendor, productID)
return // exits the closure only
}
}Execution fell through to the One judgment call I'd like your read on: I put the guard outside the 2. Cancelling learn mode could leave the keyboard blocked
Repro: click "Learn Hardware Trigger…", then Cancel or Esc without pressing a mouse button. With remapping on, the callback stays armed and the next keystroke is swallowed. If the VC has been deallocated, A question rather than a change: // TEMP: Match EVERYTHING to find the missing Naga interfaces
let matches: [[String: Any]] = [[:]]I was going to ask you to restore the vendor matching, then realised the Minor, non-blocking:
If I get to my Mac this week I'll test properly and either follow up here or just go ahead and merge. If you get to it before I do, let me know how my two commits behave — and push back on any of the above if I've misread something. |
What does this PR do?
Screenshots