Repository navigation
Conversation
Adds `MouseButton.middle` and `MouseButton.middleRight` next to left/right/both, so a window can be moved or resized by pressing the middle button (e.g. the scroll wheel on a Logitech MX Master) anywhere in it and dragging, or by holding middle + right together, with or without a keyboard shortcut. `MouseButton` now describes a trigger as a set of physical buttons (`buttons`, `isChord`, `canTriggerWithoutKeyboard`) and knows the CGEvent types of each physical button. `physicalButton(of:)` maps an event back to left/right/middle and returns nil for side buttons, which share the otherMouse* event types and must pass through untouched. Mouse-only triggers are handled by one `MouseOnlyActionManager` (replacing `MouseChordActionManager`), so several mouse-only triggers can coexist even when they share a button, e.g. Move = middle and Resize = middle + right. It watches the union of the configured buttons: a single-button trigger starts once the pointer moves past the click threshold, a chord starts on the second press, a press that can no longer complete a trigger is replayed to the app, and a plain click that never became a gesture is replayed on release. The keyboard + chord path (`startTrackingWithChord`) is generalized from left + right to any two-button chord, and `MouseTracker` derives its drag mask from the trigger's buttons. Settings: the mouse picker gains a Middle option; combinations without a trigger collapse to the tapped button; mouse-only shortcuts accept the middle button or a two-button chord, and two mouse-only shortcuts only conflict when they use the same buttons. The button labels no longer wrap at narrow widths. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
|
@mew1033 is attempting to deploy a commit to the Pablo Varela's projects Team on Vercel. A member of the Team first needs to authorize it. |
This branch has not been deployed
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
Adds Middle as a mouse-button trigger for Move and Resize, plus a middle + right chord, both usable with a keyboard shortcut or on their own. The motivating setup: Move = middle button alone (the scroll wheel on a Logitech MX Master), Resize = middle + right held together, no keyboard involved. Existing left/right/both and keyboard triggers behave as before.
Related: #16 (mouse buttons as shortcuts), #69 (mouse-only chord).
How it works
MouseButtongains.middleand.middleRightand now describes a trigger as a set of physical buttons (buttons,isChord,canTriggerWithoutKeyboard), with the CGEvent types of each physical button.physicalButton(of:)maps an event back to left/right/middle and returnsnilfor side buttons, which share theotherMouse*event types and pass through untouched.MouseOnlyActionManagerreplacesMouseChordActionManagerand handles every mouse-only trigger in one state machine, so two mouse-only triggers can share a button. It watches the union of configured buttons: a single-button trigger starts once the pointer moves pastswiftShiftClickDragThreshold, a chord starts on the second press, a press that can no longer complete any trigger is replayed to the app, and a click that never became a gesture is replayed on release. A gesture ends when one of its own buttons is released.startTrackingWithChord, formerlystartTrackingWithBothMouseButtons) works for any two-button chord;MouseTrackerderives its drag mask from the trigger's buttons.Behavior note for any chord that includes the right button (true for the existing left + right chord too): a plain right-click is delivered on release rather than on press, because the app has to wait to see whether the other button follows.
No new files, no project-file changes.
Test plan
make buildandmake test(unit tests coverMouseButtonparsing, the buttons ↔ trigger round trip,canTriggerWithoutKeyboard, and event → physical-button mapping incl. side buttons)🤖 Generated with Claude Code