import Cocoa
class MyView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func becomeFirstResponder() -> Bool {
return true
}
override var acceptsFirstResponder: Bool {
return true
}
override func keyUp(with event: NSEvent) {
print("keyUp: keyCode=\(event.keyCode)")
}
// the 'CMD + q' combination will quit the app
// the 'CMD + t' combination will open a font setting window
// the 'CMD + Space' combination will toggle the spotlight search
// the 'CTRL + Space' combination will toggle the input method switching
// why this can't capture the key board event like 'CMD + Space' or 'CMD + t' or 'CMD + q'?
// or how capture those combinations regardless of the system-wide shortcuts?
override func keyDown(with event: NSEvent) {
print("keyDown: keyCode=\(event.keyCode)")
if event.modifierFlags.contains(.command) {
if event.keyCode == 49 {
print("keyDown: CMD + Space") // if the 'CMD' and 'Space' keys were pressed both, this line is not print
} else {
print("keyDown: CMD + others") // here, like 'CMD' and 'j' keys were pressed both, this line is print
}
} else if event.modifierFlags.contains(.control) {
if event.keyCode == 49 {
print("keyDown: CTRL + Space") // if the 'CTRL' and 'Space' keys were pressed both, this line is not print
} else {
print("keyDown: CTRL + others") // here, like 'CTRL' and 'j' keys were pressed both, this line is print
}
} else {
print("keyDown: CMD or CTRL is not pressed")
}
}
override func flagsChanged(with event: NSEvent) {
print(#function, event.keyCode)
}
}
class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() }
override func viewWillAppear() {
super.viewWillAppear()
let myview = MyView(frame: view.bounds)
view.addSubview(myview)
}
}
In macOS, there are some system-preserved shortcuts (key combinations). You have mentioned some good examples: CMD + q
is preserved for quitting an app, and CMD + Space
is preserved to toggle the spotlight search.
When a user inputs a shortcut of the kind, the system processes it directly; it doesn't pass the event to apps, and so your app can't capture the input.
The only thing that allows an app to detect this kind of input is Event Tap (see CGEventTapCreate), but when using the API:
- Your app needs to be added to the list of Privacy & Security > Input Monitoring.
- You still can't change how the system processes the event.
I am curious why your app needs to monitor the system-preserved shortcuts, and may have more to say if you can share more details of your use case, but most likely, you will eventually need to avoid doing that.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.