28 thumb bug - #29
Merged
Merged
Conversation
- Add ModifierKeyType enum with shift/control/option/command - Add exclusion zone preferences (enabled, size) - Add modifier key preferences (requireKey, keyType) - Add contact size filter preferences (enabled, maxSize) - Update GestureConfiguration with palm rejection fields - Update UserPreferences.gestureConfig to include new options
- Add UserDefaults keys for exclusion zone settings - Add UserDefaults keys for modifier key settings - Add UserDefaults keys for contact size filter settings - Register defaults for all new preferences - Update loadPreferences() to load new settings - Update savePreferences() to persist new settings
- Add modifier key check at start of processTouches() - Filter touches in exclusion zone (bottom of trackpad) - Filter touches exceeding max contact size threshold - Add getModifierFlags() helper using CGEventSource - Cancel active gesture if modifier key released
- Add createPalmRejectionMenu() with three sections - Add exclusion zone toggle and size options (10-25%) - Add modifier key toggle and key type selector - Add contact size filter toggle and threshold options - Add action methods for all new preferences - Dynamically show/hide options based on toggle state
Closed
Copilot started reviewing on behalf of
NullPointerDepressiveDisorder
December 19, 2025 20:03
View session
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds palm rejection functionality to prevent accidental activation of gestures by thumbs/palms resting on the trackpad. The implementation provides three configurable palm rejection methods to improve gesture recognition accuracy.
Key Changes:
- Added exclusion zone filtering to ignore touches in the bottom portion of the trackpad where palms typically rest
- Added modifier key requirement option to require holding a key (Shift/Control/Option/Command) for gesture activation
- Added contact size filtering to reject large touch contacts that are likely palms rather than intentional finger touches
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| MiddleDrag/Utilities/PreferencesManager.swift | Added persistence layer for six new palm rejection preferences (exclusion zone, modifier key, and contact size filter settings) |
| MiddleDrag/UI/MenuBarController.swift | Added comprehensive UI controls in the Advanced menu for configuring all three palm rejection methods with dynamic sub-options |
| MiddleDrag/Models/GestureModels.swift | Added ModifierKeyType enum and six new fields to GestureConfiguration and UserPreferences for palm rejection settings |
| MiddleDrag/Core/GestureRecognizer.swift | Implemented palm rejection logic: modifier key checking, exclusion zone filtering, and contact size filtering in touch processing |
…for reliable state.
- Add tests for GestureConfiguration palm rejection defaults - Add tests for UserPreferences palm rejection defaults - Add test for UserPreferences -> GestureConfiguration mapping - Add tests for ModifierKeyType display names and raw values - Add test for ModifierKeyType CaseIterable conformance
- Add new test file GestureRecognizerTests.swift with 12 tests - Add tests for modifier key requirement (all 4 types) - Add tests for exclusion zone filtering - Add tests for contact size filtering - Add combined filter test - Add GestureRecognizer.swift to test target Includes MockGestureRecognizerDelegate for testing callbacks.
Copilot started reviewing on behalf of
NullPointerDepressiveDisorder
December 19, 2025 20:24
View session
The comment claimed modifier flags were captured on the main thread, but deviceMonitor callback actually runs on a framework-managed background thread. CGEventSource.flagsState is thread-safe per Apple docs, so this is fine, but the comment was inaccurate.
Add 4 new tests for scenarios where some touches are filtered while others pass palm rejection filters: - testExclusionZone_PartialFiltering_FiveTouchesThreePass - testContactSizeFilter_PartialFiltering_FiveTouchesThreePass - testCombinedFilters_PartialFiltering_SixTouchesThreePass - testPartialFiltering_InsufficientRemainingTouches These verify gestures activate when exactly 3 valid touches remain after filtering, regardless of total touch count.
middledrag-releaser Bot
pushed a commit
that referenced
this pull request
Dec 20, 2025
* feat: add ModifierKeyType enum and palm rejection preferences - Add ModifierKeyType enum with shift/control/option/command - Add exclusion zone preferences (enabled, size) - Add modifier key preferences (requireKey, keyType) - Add contact size filter preferences (enabled, maxSize) - Update GestureConfiguration with palm rejection fields - Update UserPreferences.gestureConfig to include new options * feat: add persistence for palm rejection preferences - Add UserDefaults keys for exclusion zone settings - Add UserDefaults keys for modifier key settings - Add UserDefaults keys for contact size filter settings - Register defaults for all new preferences - Update loadPreferences() to load new settings - Update savePreferences() to persist new settings * feat: implement palm rejection touch filtering - Add modifier key check at start of processTouches() - Filter touches in exclusion zone (bottom of trackpad) - Filter touches exceeding max contact size threshold - Add getModifierFlags() helper using CGEventSource - Cancel active gesture if modifier key released * feat: add Palm Rejection submenu to Advanced menu - Add createPalmRejectionMenu() with three sections - Add exclusion zone toggle and size options (10-25%) - Add modifier key toggle and key type selector - Add contact size filter toggle and threshold options - Add action methods for all new preferences - Dynamically show/hide options based on toggle state * refactor: Pass modifier flags to gesture recognizer from main thread for reliable state. * test: add palm rejection configuration and ModifierKeyType tests - Add tests for GestureConfiguration palm rejection defaults - Add tests for UserPreferences palm rejection defaults - Add test for UserPreferences -> GestureConfiguration mapping - Add tests for ModifierKeyType display names and raw values - Add test for ModifierKeyType CaseIterable conformance * test: add GestureRecognizerTests for palm rejection filters - Add new test file GestureRecognizerTests.swift with 12 tests - Add tests for modifier key requirement (all 4 types) - Add tests for exclusion zone filtering - Add tests for contact size filtering - Add combined filter test - Add GestureRecognizer.swift to test target Includes MockGestureRecognizerDelegate for testing callbacks. * docs: fix misleading comment about thread context The comment claimed modifier flags were captured on the main thread, but deviceMonitor callback actually runs on a framework-managed background thread. CGEventSource.flagsState is thread-safe per Apple docs, so this is fine, but the comment was inaccurate. * test: add partial filter tests for palm rejection Add 4 new tests for scenarios where some touches are filtered while others pass palm rejection filters: - testExclusionZone_PartialFiltering_FiveTouchesThreePass - testContactSizeFilter_PartialFiltering_FiveTouchesThreePass - testCombinedFilters_PartialFiltering_SixTouchesThreePass - testPartialFiltering_InsufficientRemainingTouches These verify gestures activate when exactly 3 valid touches remain after filtering, regardless of total touch count.
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.
This pull request adds comprehensive palm rejection features to MiddleDrag, improving gesture reliability and reducing accidental activations caused by palms or unintended touches. It introduces three configurable palm rejection methods—exclusion zone, modifier key requirement, and contact size filtering—along with a new menu section for user configuration. Preferences are persisted, and the gesture recognizer logic is updated to enforce these new filters.
Palm Rejection Features:
User Preferences and Configuration:
UserPreferencesandGestureConfigurationto support new palm rejection options, including their default values and conversion logic. [1] [2] [3]PreferencesManagerto persist new palm rejection settings and ensure correct loading/saving fromUserDefaults. [1] [2]Menu Bar UI Enhancements:
Gesture Recognition Logic:
General Code Improvements:
These changes provide users with robust control over palm rejection, reducing false positives and improving the overall experience when using MiddleDrag.