mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-24 05:40:15 +00:00
macOS: Re-enable global keybinds after event tap disable events (#12714)
While testing https://github.com/ghostty-org/ghostty/pull/9857, I encountered the behavior mentioned below. It's pretty frustrating to encounter, so I've been actually compiling this fix into my test builds for last month or so, and the issue has not come back. I exclusively use the QuickTerminal, so my workflow depends on global keybinds working reliably. Issue: https://github.com/ghostty-org/ghostty/issues/12294 The solution includes listening to two events that are fired when a tap is disabled: - tapDisabledByTimeout - tapDisabledByUserInput When these are fired, we re-enable the tap. Apple's Docs: https://developer.apple.com/documentation/coregraphics/cgeventtype?language=swift Related Discussions: - https://github.com/ghostty-org/ghostty/discussions/11819 - https://github.com/ghostty-org/ghostty/discussions/12091
This commit is contained in:
@@ -16,7 +16,7 @@ class GlobalEventTap {
|
||||
|
||||
// The event tap used for global event listening. This is non-nil if it is
|
||||
// created.
|
||||
private var eventTap: CFMachPort?
|
||||
fileprivate var eventTap: CFMachPort?
|
||||
|
||||
// This is the timer used to retry enabling the global event tap if we
|
||||
// don't have permissions.
|
||||
@@ -125,6 +125,17 @@ private func cgEventFlagsChangedHandler(
|
||||
) -> Unmanaged<CGEvent>? {
|
||||
let result = Unmanaged.passUnretained(cgEvent)
|
||||
|
||||
// macOS disables the event tap if the callback is too slow or for other
|
||||
// internal reasons. When that happens it sends this event type. We need
|
||||
// to re-enable the tap or it stays dead forever.
|
||||
if type == .tapDisabledByTimeout || type == .tapDisabledByUserInput {
|
||||
GlobalEventTap.logger.warning("global event tap was disabled by the system, re-enabling")
|
||||
if let machPort = GlobalEventTap.shared.eventTap {
|
||||
CGEvent.tapEnable(tap: machPort, enable: true)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// We only care about keydown events
|
||||
guard type == .keyDown else { return result }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user