← All repositories

listless

A simple list app for Apple platforms

git clone https://code.inqk.net/listless.git


Listless/Helpers/KeyboardNavigationModifier.swift (1603B)

1import SwiftUI
2
3struct ShortcutKey: Hashable {
4    let key: KeyEquivalent
5    let modifiers: EventModifiers
6
7    init(key: KeyEquivalent, modifiers: EventModifiers = []) {
8        self.key = key
9        self.modifiers = modifiers
10    }
11
12    static func == (lhs: ShortcutKey, rhs: ShortcutKey) -> Bool {
13        lhs.key == rhs.key && lhs.modifiers == rhs.modifiers
14    }
15
16    func hash(into hasher: inout Hasher) {
17        hasher.combine(key)
18        hasher.combine(modifiers.rawValue)
19    }
20}
21
22extension View {
23    func keyboardNavigation(_ bindings: [ShortcutKey: () -> KeyPress.Result]) -> some View {
24        self.onKeyPress { press in
25            let key = normalizeKey(press)
26            let modifiers = normalizeModifiers(press.modifiers)
27            let shortcut = ShortcutKey(key: key, modifiers: modifiers)
28
29            if let action = bindings[shortcut] {
30                return action()
31            }
32            return .ignored
33        }
34    }
35
36    private func normalizeKey(_ press: KeyPress) -> KeyEquivalent {
37        // Normalize backspace/delete key
38        if press.characters == "\u{7F}" {
39            return .delete
40        }
41        return press.key
42    }
43
44    private func normalizeModifiers(_ modifiers: EventModifiers) -> EventModifiers {
45        // Mask to only meaningful shortcut modifiers, excluding system artifacts
46        // like .function (deprecated), .numericPad, .capsLock, etc.
47        let shortcutModifierMask: EventModifiers = [.command, .shift, .option, .control]
48        return EventModifiers(rawValue: modifiers.rawValue & shortcutModifierMask.rawValue)
49    }
50}