Skip to content

Commit

Permalink
Monitor application launch completion (#1446)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianyh authored Mar 4, 2023
1 parent be01c12 commit ba49823
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
15 changes: 10 additions & 5 deletions Amethyst/Categories/NSRunningApplication+Manageable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
import AppKit
import Foundation

enum Manageable {
case manageable
case unmanageable
case undetermined
}

private let ignoredBundleIDs = Set([
"com.apple.dashboard",
"com.apple.loginwindow",
Expand All @@ -34,11 +40,6 @@ protocol BundleIdentifiable {
var bundleIdentifier: String? { get }
}

enum Manageable {
case manageable
case unmanageable
case undetermined
}
extension NSRunningApplication: BundleIdentifiable {}

extension NSRunningApplication {
Expand All @@ -47,6 +48,10 @@ extension NSRunningApplication {
return .unmanageable
}

guard isFinishedLaunching else {
return .undetermined
}

guard case .regular = activationPolicy else {
return .undetermined
}
Expand Down
40 changes: 34 additions & 6 deletions Amethyst/Managers/WindowManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ final class WindowManager<Application: ApplicationType>: NSObject, Codable {
typealias Window = Application.Window
typealias Screen = Window.Screen

private struct UndeterminedApplication {
let application: NSRunningApplication
let activationPolicyObservation: NSKeyValueObservation?
let isFinishedLaunchingObservation: NSKeyValueObservation?

func invalidate() {
activationPolicyObservation?.invalidate()
isFinishedLaunchingObservation?.invalidate()
}
}

enum CodingKeys: String, CodingKey {
case screens
}
Expand All @@ -36,7 +47,7 @@ final class WindowManager<Application: ApplicationType>: NSObject, Codable {
let focusTransitionCoordinator: FocusTransitionCoordinator<WindowManager<Application>>

private var applications: [pid_t: AnyApplication<Application>] = [:]
private var applicationObservations: [pid_t: (NSRunningApplication, NSKeyValueObservation)] = [:]
private var applicationObservations: [pid_t: UndeterminedApplication] = [:]
private let screens: Screens
private let windows = Windows()
private var lastReflowTime = Date()
Expand Down Expand Up @@ -323,23 +334,40 @@ extension WindowManager {
func monitorUndeterminedApplication(_ runningApplication: NSRunningApplication) {
let pid = runningApplication.processIdentifier

if let (_, previousObservation) = applicationObservations[pid] {
previousObservation.invalidate()
if let previousApplication = applicationObservations[pid] {
previousApplication.invalidate()
applicationObservations.removeValue(forKey: pid)
}

let observation = runningApplication.observe(\.activationPolicy) { [weak self] runningApplication, change in
let activationPolicyObservation = runningApplication.observe(\.activationPolicy) { [weak self] runningApplication, change in
guard case .setting = change.kind else {
return
}

if runningApplication.activationPolicy == .regular {
self?.applicationObservations[runningApplication.processIdentifier]?.invalidate()
self?.applicationObservations.removeValue(forKey: runningApplication.processIdentifier)
self?.add(runningApplication: runningApplication)
self?.applicationObservations[runningApplication.processIdentifier]?.1.invalidate()
}
}

let isFinishedLaunchingObservation = runningApplication.observe(\.isFinishedLaunching) { [weak self] runningApplication, change in
guard case .setting = change.kind else {
return
}

if runningApplication.isFinishedLaunching {
self?.applicationObservations[runningApplication.processIdentifier]?.invalidate()
self?.applicationObservations.removeValue(forKey: runningApplication.processIdentifier)
self?.add(runningApplication: runningApplication)
}
}
applicationObservations[pid] = (runningApplication, observation)

applicationObservations[pid] = UndeterminedApplication(
application: runningApplication,
activationPolicyObservation: activationPolicyObservation,
isFinishedLaunchingObservation: isFinishedLaunchingObservation
)
}

func reevaluateWindows() {
Expand Down

0 comments on commit ba49823

Please sign in to comment.