macos: forward key events to the app when no windows exist

This commit is contained in:
Mitchell Hashimoto
2024-10-05 10:02:28 -10:00
parent 6fdfa9d491
commit f9e6d6efa6
3 changed files with 54 additions and 4 deletions

View File

@ -149,6 +149,12 @@ class AppDelegate: NSObject,
// This registers the Ghostty => Services menu to exist.
NSApp.servicesMenu = menuServices
// Setup a local event monitor for app-level keyboard shortcuts. See
// localEventHandler for more info why.
_ = NSEvent.addLocalMonitorForEvents(
matching: [.keyDown],
handler: localEventHandler)
// Configure user notifications
let actions = [
UNNotificationAction(identifier: Ghostty.userNotificationActionShow, title: "Show")
@ -361,6 +367,53 @@ class AppDelegate: NSObject,
return terminalManager.focusedSurface?.surface
}
// MARK: Notifications and Events
/// This handles events from the NSEvent.addLocalEventMonitor. We use this so we can get
/// events without any terminal windows open.
private func localEventHandler(_ event: NSEvent) -> NSEvent? {
return switch event.type {
case .keyDown:
localEventKeyDown(event)
default:
event
}
}
private func localEventKeyDown(_ event: NSEvent) -> NSEvent? {
// If we have a main window then we don't process any of the keys
// because we let it capture and propagate.
guard NSApp.mainWindow == nil else { return event }
// If this event would be handled by our menu then we do nothing.
if let mainMenu = NSApp.mainMenu,
mainMenu.performKeyEquivalent(with: event) {
return nil
}
// If we reach this point then we try to process the key event
// through the Ghostty key mechanism.
// Ghostty must be loaded
guard let ghostty = self.ghostty.app else { return event }
// Build our event input and call ghostty
var key_ev = ghostty_input_key_s()
key_ev.action = GHOSTTY_ACTION_PRESS
key_ev.mods = Ghostty.ghosttyMods(event.modifierFlags)
key_ev.keycode = UInt32(event.keyCode)
key_ev.text = nil
key_ev.composing = false
if (ghostty_app_key(ghostty, key_ev)) {
// The key was used so we want to stop it from going to our Mac app
Ghostty.logger.debug("local key event handled event=\(event)")
return nil
}
return event
}
//MARK: - Restorable State
/// We support NSSecureCoding for restorable state. Required as of macOS Sonoma (14) but a good idea anyways.

View File

@ -87,7 +87,7 @@ extension Ghostty {
// Subscribe to notifications for keyboard layout change so that we can update Ghostty.
NotificationCenter.default.addObserver(
self,
selector: #selector(self.keyboardSelectionDidChange(notification:)),
selector: #selector(keyboardSelectionDidChange(notification:)),
name: NSTextInputContext.keyboardSelectionDidChangeNotification,
object: nil)
#endif

View File

@ -294,9 +294,6 @@ pub fn keyEvent(
.leaf => |leaf| leaf,
};
// We only care about global keybinds
if (!leaf.flags.global) return false;
// Perform the action
self.performAllAction(rt_app, leaf.action) catch |err| {
log.warn("error performing global keybind action action={s} err={}", .{