feat: add trackpad haptic feedback for better navigation (closes #4763)

This commit is contained in:
lwouis committed 2025-11-24 15:42:58 +01:00
1 parent 29e1cff8f1
commit fb5dfc4399
4 files changed
+19 -1

No files matched your search

+3
View File
@@ -526,6 +526,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Titles" = "Titles"; "Titles" = "Titles";
/* No comment provided by engineer. */
"Trackpad haptic feedback" = "Trackpad haptic feedback";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Trigger shortcut" = "Trigger shortcut"; "Trigger shortcut" = "Trigger shortcut";
+2
View File
@@ -87,6 +87,7 @@ class Preferences {
"hideThumbnails": "false", "hideThumbnails": "false",
"previewFocusedWindow": "false", "previewFocusedWindow": "false",
"screenRecordingPermissionSkipped": "false", "screenRecordingPermissionSkipped": "false",
"trackpadHapticFeedbackEnabled": "true",
] ]
// system preferences // system preferences
@@ -110,6 +111,7 @@ class Preferences {
static var vimKeysEnabled: Bool { CachedUserDefaults.bool("vimKeysEnabled") } static var vimKeysEnabled: Bool { CachedUserDefaults.bool("vimKeysEnabled") }
static var mouseHoverEnabled: Bool { CachedUserDefaults.bool("mouseHoverEnabled") } static var mouseHoverEnabled: Bool { CachedUserDefaults.bool("mouseHoverEnabled") }
static var cursorFollowFocus: CursorFollowFocus { CachedUserDefaults.macroPref("cursorFollowFocus", CursorFollowFocus.allCases) } static var cursorFollowFocus: CursorFollowFocus { CachedUserDefaults.macroPref("cursorFollowFocus", CursorFollowFocus.allCases) }
static var trackpadHapticFeedbackEnabled: Bool { CachedUserDefaults.bool("trackpadHapticFeedbackEnabled") }
static var showTabsAsWindows: Bool { CachedUserDefaults.bool("showTabsAsWindows") } static var showTabsAsWindows: Bool { CachedUserDefaults.bool("showTabsAsWindows") }
static var hideColoredCircles: Bool { CachedUserDefaults.bool("hideColoredCircles") } static var hideColoredCircles: Bool { CachedUserDefaults.bool("hideColoredCircles") }
static var windowDisplayDelay: DispatchTimeInterval { DispatchTimeInterval.milliseconds(CachedUserDefaults.int("windowDisplayDelay")) } static var windowDisplayDelay: DispatchTimeInterval { DispatchTimeInterval.milliseconds(CachedUserDefaults.int("windowDisplayDelay")) }
+11 -1
View File
@@ -157,6 +157,7 @@ class TriggerSwipeDetector {
reset() reset()
DispatchQueue.main.async { DispatchQueue.main.async {
ScrollwheelEvents.toggle(true) ScrollwheelEvents.toggle(true)
performHapticFeedback()
App.app.showUiOrCycleSelection(Preferences.gestureIndex, false) App.app.showUiOrCycleSelection(Preferences.gestureIndex, false)
} }
return true return true
@@ -187,7 +188,10 @@ class NavigationSwipeDetector {
if (maxIsX ? absX : absY) > MIN_SWIPE_DISTANCE { if (maxIsX ? absX : absY) > MIN_SWIPE_DISTANCE {
maxIsX ? resetX(activeTouches) : resetY(activeTouches) maxIsX ? resetX(activeTouches) : resetY(activeTouches)
let direction: Direction = maxIsX ? (averageDistance.x < 0 ? .left : .right) : (averageDistance.y < 0 ? .down : .up) let direction: Direction = maxIsX ? (averageDistance.x < 0 ? .left : .right) : (averageDistance.y < 0 ? .down : .up)
DispatchQueue.main.async { App.app.cycleSelection(direction, allowWrap: false) } DispatchQueue.main.async {
performHapticFeedback()
App.app.cycleSelection(direction, allowWrap: false)
}
return true return true
} }
return nil return nil
@@ -209,3 +213,9 @@ class NavigationSwipeDetector {
} }
} }
} }
func performHapticFeedback() {
if Preferences.trackpadHapticFeedbackEnabled {
NSHapticFeedbackManager.defaultPerformer.perform(.generic, performanceTime: .default)
}
}
@@ -10,6 +10,8 @@ class AdditionalControlsSheet: SheetWindow {
rightViews: [LabelAndControl.makeSwitch("mouseHoverEnabled")]) rightViews: [LabelAndControl.makeSwitch("mouseHoverEnabled")])
let enableCursorFollowFocus = TableGroupView.Row(leftTitle: NSLocalizedString("Cursor follows focus", comment: ""), let enableCursorFollowFocus = TableGroupView.Row(leftTitle: NSLocalizedString("Cursor follows focus", comment: ""),
rightViews: [LabelAndControl.makeDropdown("cursorFollowFocus", CursorFollowFocus.allCases)]) rightViews: [LabelAndControl.makeDropdown("cursorFollowFocus", CursorFollowFocus.allCases)])
let enableTrackpadHapticFeedback = TableGroupView.Row(leftTitle: NSLocalizedString("Trackpad haptic feedback", comment: ""),
rightViews: [LabelAndControl.makeSwitch("trackpadHapticFeedbackEnabled")])
ControlsTab.arrowKeysCheckbox = enableArrows.rightViews[0] as? Switch ControlsTab.arrowKeysCheckbox = enableArrows.rightViews[0] as? Switch
ControlsTab.vimKeysCheckbox = enableVimKeys.rightViews[0] as? Switch ControlsTab.vimKeysCheckbox = enableVimKeys.rightViews[0] as? Switch
ControlsTab.arrowKeysEnabledCallback(ControlsTab.arrowKeysCheckbox) ControlsTab.arrowKeysEnabledCallback(ControlsTab.arrowKeysCheckbox)
@@ -22,6 +24,7 @@ class AdditionalControlsSheet: SheetWindow {
let table2 = TableGroupView(title: NSLocalizedString("Miscellaneous", comment: ""), let table2 = TableGroupView(title: NSLocalizedString("Miscellaneous", comment: ""),
width: PreferencesWindow.width) width: PreferencesWindow.width)
_ = table2.addRow(enableCursorFollowFocus) _ = table2.addRow(enableCursorFollowFocus)
_ = table2.addRow(enableTrackpadHapticFeedback)
let view = TableGroupSetView(originalViews: [table1, table2], padding: 0) let view = TableGroupSetView(originalViews: [table1, table2], padding: 0)
return view return view
} }