sindresorhus / KeyboardShortcuts

⌨️ Add user-customizable global keyboard shortcuts (hotkeys) to your macOS app in minutes
https://swiftpackageindex.com/sindresorhus/KeyboardShortcuts/documentation/keyboardshortcuts/keyboardshortcuts
MIT License
1.94k stars 181 forks source link

Fail to listen for Caps Lock #158

Open Yang-Xijie opened 9 months ago

Yang-Xijie commented 9 months ago

I create a KeyboardShortcuts.Name called my_capslock. And set KeyboardShortcuts.Shortcut KeyboardShortcuts.Shortcut(KeyboardShortcuts.Key.capsLock, modifiers: []) for it.

However, when running the app, pressing Caps Lock on the keyboard makes nothing happen...

How can I listen for the Caps Lock key event so that I can further override the default behaviour of pressing Caps Lock in macOS?

KeyboardShortcuts version: 1.16.1

Codes to reproduce:

App.swift:

import KeyboardShortcuts
import SwiftUI

@main
struct CapslockTestApp: App {
    @StateObject private var appState = AppState()

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

@MainActor
final class AppState: ObservableObject {
    init() {
        KeyboardShortcuts.setShortcut(
            KeyboardShortcuts.Shortcut(KeyboardShortcuts.Key.capsLock, modifiers: []),
            for: .my_capslock)
        KeyboardShortcuts.onKeyDown(for: .my_capslock) {
            print("capslock down")
        }
        KeyboardShortcuts.onKeyUp(for: .my_capslock) {
            print("capslock up")
        }
    }
}

extension KeyboardShortcuts.Name {
    static let my_capslock = Self("my_capslock", default: .init(KeyboardShortcuts.Key.capsLock))
}

ContentView.swift:

import KeyboardShortcuts
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
            SettingsView()
        }
        .padding()
    }
}

struct SettingsView: View {
    var body: some View {
        Form {
            KeyboardShortcuts.Recorder("My Caps Lock:", name: .my_capslock)
        }
        .padding()
    }
}
sindresorhus commented 9 months ago

Caps Lock is a modifier. You cannot listen to just a modifier. I realize now that should be better documented.

For your needs, you'll have to use CGEvent.tapCreate.