diff --git a/src/logic/Applications.swift b/src/logic/Applications.swift index 42a193fe..cbea511c 100644 --- a/src/logic/Applications.swift +++ b/src/logic/Applications.swift @@ -11,7 +11,7 @@ class Applications { } static func addInitialRunningApplications() { - addRunningApplications(NSWorkspace.shared.runningApplications) + addRunningApplications(NSWorkspace.shared.runningApplications, false) } static func manuallyRefreshAllWindows() { @@ -54,7 +54,7 @@ class Applications { } } - static func addRunningApplications(_ runningApps: [NSRunningApplication]) { + static func addRunningApplications(_ runningApps: [NSRunningApplication], _ needToVerifyFrontmostPid: Bool) { runningApps.forEach { let bundleIdentifier = $0.bundleIdentifier let processIdentifier = $0.processIdentifier @@ -63,7 +63,7 @@ class Applications { } // com.apple.universalcontrol always fails subscribeToNotification. We blacklist it to save resources on everyone's machines if bundleIdentifier != "com.apple.universalcontrol" { - findOrCreate(processIdentifier) + findOrCreate(processIdentifier, needToVerifyFrontmostPid) } } } @@ -103,7 +103,7 @@ class Applications { static func refreshBadges_(_ items: [(URL?, String?)]) { Windows.list.enumerated().forEach { (i, window) in let view = TilesView.recycledViews[i] - if let app = findOrCreate(window.application.pid) { + if let app = findOrCreate(window.application.pid, false) { if app.runningApplication.activationPolicy == .regular, let matchingItem = (items.first { $0.0 == app.bundleURL }), let label = matchingItem.1 { @@ -118,7 +118,7 @@ class Applications { } @discardableResult - static func findOrCreate(_ pid: pid_t) -> Application? { + static func findOrCreate(_ pid: pid_t, _ needToVerifyFrontmostPid: Bool) -> Application? { if let app = (list.first { $0.pid == pid }) { return app } @@ -126,6 +126,8 @@ class Applications { guard ApplicationDiscriminator.isActualApplication(pid, runningApp.bundleIdentifier) else { return nil } let app = Application(runningApp) list.append(app) + // apps don't always create kAXApplicationActivatedNotification upon launch. We need to update frontmostPid in case it has changed + frontmostPid = NSWorkspace.shared.frontmostApplication?.processIdentifier return app } diff --git a/src/logic/Windows.swift b/src/logic/Windows.swift index 7829b0c3..efc9002c 100644 --- a/src/logic/Windows.swift +++ b/src/logic/Windows.swift @@ -228,7 +228,7 @@ class Windows { TilesView.highlight(oldIndex) } if let frontmostPid = Applications.frontmostPid, - let frontmostApp = Applications.findOrCreate(frontmostPid), + let frontmostApp = Applications.findOrCreate(frontmostPid, false), (frontmostApp.focusedWindow == nil || Preferences.windowOrder[App.app.shortcutIndex] != .recentlyFocused), let lastFocusedOrderWindowIndex = getLastFocusedOrderWindowIndex() { updateSelectedAndHoveredWindowIndex(lastFocusedOrderWindowIndex) diff --git a/src/logic/events/AccessibilityEvents.swift b/src/logic/events/AccessibilityEvents.swift index 015fe093..8d364657 100644 --- a/src/logic/events/AccessibilityEvents.swift +++ b/src/logic/events/AccessibilityEvents.swift @@ -30,7 +30,7 @@ class AccessibilityEvents { let appFocusedWindow = try element.attributes([kAXFocusedWindowAttribute]).focusedWindow let wid = try appFocusedWindow?.cgWindowId() DispatchQueue.main.async { - guard let app = Applications.findOrCreate(pid) else { return } + guard let app = Applications.findOrCreate(pid, false) else { return } Logger.info { "\(type) app:\(app.debugId)" } if type == kAXApplicationActivatedNotification { applicationActivated(app, pid, type, appFocusedWindow, wid) @@ -79,7 +79,7 @@ class AccessibilityEvents { let level = wid.level() let a = try element.attributes([kAXTitleAttribute, kAXSubroleAttribute, kAXRoleAttribute, kAXSizeAttribute, kAXPositionAttribute, kAXFullscreenAttribute, kAXMinimizedAttribute]) DispatchQueue.main.async { - guard let app = Applications.findOrCreate(pid) else { return } + guard let app = Applications.findOrCreate(pid, false) else { return } Logger.info { "\(type) wid:\(wid) app:\(app.debugId)" } if type == kAXUIElementDestroyedNotification { windowDestroyed(element, pid, wid) diff --git a/src/logic/events/RunningApplicationsEvents.swift b/src/logic/events/RunningApplicationsEvents.swift index 817f0b74..a4956946 100644 --- a/src/logic/events/RunningApplicationsEvents.swift +++ b/src/logic/events/RunningApplicationsEvents.swift @@ -14,7 +14,7 @@ class RunningApplicationsEvents { let quit = change.oldValue if let launched { Logger.debug { "launched:\(launched.map { $0.debugId() })" } - Applications.addRunningApplications(launched) + Applications.addRunningApplications(launched, true) } if let quit { Logger.debug { "quit:\(quit.map { $0.debugId() })" } diff --git a/src/logic/events/SpacesEvents.swift b/src/logic/events/SpacesEvents.swift index a6a0ef14..4fe7cf7b 100644 --- a/src/logic/events/SpacesEvents.swift +++ b/src/logic/events/SpacesEvents.swift @@ -14,7 +14,7 @@ class SpacesEvents { // for such cases, we refresh isFullscreen on Space change Windows.updateIsFullscreenOnCurrentSpace() if let frontmostPid = Applications.frontmostPid, - let frontmostApp = Applications.findOrCreate(frontmostPid), + let frontmostApp = Applications.findOrCreate(frontmostPid, false), let focusedWindow = frontmostApp.focusedWindow { App.app.checkIfShortcutsShouldBeDisabled(focusedWindow, nil) }