fix: ui would sometimes stay open (closes #588)
This commit is contained in:
1 parent
3019dd58d7
commit
8912c70bcd
5 files changed
+37
-23
No files matched your search
@@ -25,11 +25,6 @@ class ATShortcut {
|
||||
state = state == .down ? .up : .down
|
||||
if state == .up {
|
||||
KeyRepeatTimer.timer?.invalidate()
|
||||
} else {
|
||||
// macOS bug: the app doesn't receive either local or global modifierChanged events during Space transition
|
||||
// we force holdShortcut to be .down if nextWindowShortcut trigger during a transition, since we know it has to be down at that point
|
||||
let suffix = shortcutId == "nextWindowShortcut" ? "" : "2"
|
||||
ControlsTab.shortcuts["holdShortcut" + suffix]!.state = .down
|
||||
}
|
||||
if (triggerPhase == .down && shortcutState == .down) || (triggerPhase == .up && shortcutState == .up) {
|
||||
return true
|
||||
|
||||
@@ -11,8 +11,6 @@ class Spaces {
|
||||
debugPrint("OS event", "activeSpaceDidChangeNotification")
|
||||
idsAndIndexes = allIdsAndIndexes()
|
||||
updateCurrentSpace()
|
||||
guard App.app.appIsBeingUsed else { return }
|
||||
App.app.reopenUi()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ class KeyboardEvents {
|
||||
"holdShortcut2": 3,
|
||||
]
|
||||
static var eventHotKeyRefs = [String: EventHotKeyRef?]()
|
||||
static var hotModifierEventHandler: EventHandlerRef?
|
||||
static var hotKeyPressedEventHandler: EventHandlerRef?
|
||||
static var hotKeyReleasedEventHandler: EventHandlerRef?
|
||||
static var localMonitor: Any!
|
||||
@@ -70,22 +69,33 @@ class KeyboardEvents {
|
||||
}
|
||||
}
|
||||
|
||||
static func addLocalEventHandler() {
|
||||
localMonitor = NSEvent.addLocalMonitorForEvents(matching: [.keyDown, .keyUp, .flagsChanged]) { event in
|
||||
static func addEventHandlers() {
|
||||
addLocalMonitorForKeyDownAndKeyUp()
|
||||
addCgEventTapForModifierFlags()
|
||||
}
|
||||
|
||||
private static func addLocalMonitorForKeyDownAndKeyUp() {
|
||||
localMonitor = NSEvent.addLocalMonitorForEvents(matching: [.keyDown, .keyUp]) { event in
|
||||
return handleEvent(nil, nil, event.type == .keyDown ? UInt32(event.keyCode) : nil, cocoaToCarbonFlags(event.modifierFlags), event.type == .keyDown ? event.isARepeat : false) ? nil : event
|
||||
}
|
||||
}
|
||||
|
||||
private static func addCgEventTapForModifierFlags() {
|
||||
let eventMask = [CGEventType.flagsChanged].reduce(CGEventMask(0), { $0 | (1 << $1.rawValue) })
|
||||
// CGEvent.tapCreate returns null if ensureAccessibilityCheckboxIsChecked() didn't pass
|
||||
// CGEvent.tapCreate is unaffected by SecureInput for .flagsChanged
|
||||
eventTap = CGEvent.tapCreate(
|
||||
tap: .cgSessionEventTap,
|
||||
place: .headInsertEventTap,
|
||||
options: .defaultTap,
|
||||
eventsOfInterest: eventMask,
|
||||
callback: cgEventFlagsChangedHandler,
|
||||
userInfo: nil)
|
||||
let runLoopSource = CFMachPortCreateRunLoopSource(nil, eventTap, 0)
|
||||
CFRunLoopAddSource(CFRunLoopGetMain(), runLoopSource, .commonModes)
|
||||
}
|
||||
|
||||
private static func addGlobalHandlerIfNeeded(_ shortcut: Shortcut) {
|
||||
if shortcut.keyCode == .none && hotModifierEventHandler == nil {
|
||||
var eventTypes = [EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: OSType(kEventRawKeyModifiersChanged))]
|
||||
InstallEventHandler(GetEventMonitorTarget(), { (_: EventHandlerCallRef?, event: EventRef?, _: UnsafeMutableRawPointer?) -> OSStatus in
|
||||
var modifiers = UInt32(0)
|
||||
GetEventParameter(event, EventParamName(kEventParamKeyModifiers), EventParamType(typeUInt32), nil, MemoryLayout<UInt32>.size, nil, &modifiers)
|
||||
handleEvent(nil, nil, nil, modifiers, false)
|
||||
return noErr
|
||||
}, eventTypes.count, &eventTypes, nil, &hotModifierEventHandler)
|
||||
}
|
||||
if shortcut.keyCode != .none && hotKeyPressedEventHandler == nil {
|
||||
var eventTypes = [EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: OSType(kEventHotKeyPressed))]
|
||||
InstallEventHandler(shortcutEventTarget, { (_: EventHandlerCallRef?, event: EventRef?, _: UnsafeMutableRawPointer?) -> OSStatus in
|
||||
@@ -114,9 +124,6 @@ class KeyboardEvents {
|
||||
hotKeyPressedEventHandler = nil
|
||||
RemoveEventHandler(hotKeyReleasedEventHandler_)
|
||||
hotKeyReleasedEventHandler = nil
|
||||
} else if let hotModifierEventHandler_ = hotModifierEventHandler, (globalShortcuts.allSatisfy { $0.shortcut.keyCode != .none }) {
|
||||
RemoveEventHandler(hotModifierEventHandler_)
|
||||
hotModifierEventHandler = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,3 +139,15 @@ fileprivate func handleEvent(_ id: EventHotKeyID?, _ shortcutState: ShortcutStat
|
||||
}
|
||||
return someShortcutTriggered
|
||||
}
|
||||
|
||||
fileprivate func cgEventFlagsChangedHandler(proxy: CGEventTapProxy, type: CGEventType, cgEvent: CGEvent, userInfo: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {
|
||||
if type == .flagsChanged {
|
||||
let modifiers = cocoaToCarbonFlags(NSEvent.ModifierFlags(rawValue: UInt(cgEvent.flags.rawValue)))
|
||||
if handleEvent(nil, nil, nil, modifiers, false) {
|
||||
return nil // focused app won't receive the event
|
||||
}
|
||||
} else if (type == .tapDisabledByUserInput || type == .tapDisabledByTimeout) {
|
||||
CGEvent.tapEnable(tap: eventTap!, enable: true)
|
||||
}
|
||||
return Unmanaged.passUnretained(cgEvent) // focused app will receive the event
|
||||
}
|
||||
+1
-1
@@ -60,7 +60,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
Applications.initialDiscovery()
|
||||
self.preferencesWindow = PreferencesWindow()
|
||||
self.feedbackWindow = FeedbackWindow()
|
||||
KeyboardEvents.addLocalEventHandler()
|
||||
KeyboardEvents.addEventHandlers()
|
||||
MouseEvents.observe()
|
||||
// TODO: undeterministic; events in the queue may still be processing; good enough for now
|
||||
DispatchQueue.main.async { () -> () in Windows.sortByLevel() }
|
||||
|
||||
@@ -15,6 +15,8 @@ class ThumbnailsPanel: NSPanel {
|
||||
contentView!.addSubview(thumbnailsView)
|
||||
preservesContentDuringLiveResize = false
|
||||
disableSnapshotRestoration()
|
||||
// triggering AltTab before or during Space transition animation brings the window on the Space post-transition
|
||||
collectionBehavior = .canJoinAllSpaces
|
||||
// 2nd highest level possible; this allows the app to go on top of context menus
|
||||
// highest level is .screenSaver but makes drag and drop on top the main window impossible
|
||||
level = .popUpMenu
|
||||
|
||||
Reference in new issue
Block a user