Skip to content

Commit

Permalink
Don't rely on unreliable kAXUIElementDestroyedNotification to destroy…
Browse files Browse the repository at this point in the history
… windows

Should _fix #445
  • Loading branch information
nikitabobko committed Nov 1, 2024
1 parent 7d9a4a6 commit 405dec8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
13 changes: 13 additions & 0 deletions Sources/AppBundle/layout/refresh.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,23 @@ func refreshModel() {
private func gc() {
// Garbage collect terminated apps and windows before working with all windows
MacApp.garbageCollectTerminatedApps()
gcWindows()
// Garbage collect workspaces after apps, because workspaces contain apps.
Workspace.garbageCollectUnusedWorkspaces()
}

func gcWindows() {
// When lockscreen is active, all accessibility API becomes unobservable (all attributes become empty, window id
// becomes nil, etc.) which tricks AeroSpace into thinking that all windows were closed.
// The worst part is that windows don't becomes unobservable all together but window by window.
if NSWorkspace.shared.frontmostApplication?.bundleIdentifier == "com.apple.loginwindow" {
return
}
for window in MacWindow.allWindows where window.axWindow.containingWindowId() == nil {
window.garbageCollect()
}
}

func refreshObs(_ obs: AXObserver, ax: AXUIElement, notif: CFString, data: UnsafeMutableRawPointer?) {
refreshAndLayout()
}
Expand Down
7 changes: 1 addition & 6 deletions Sources/AppBundle/tree/MacWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final class MacWindow: Window, CustomStringConvertible {
)
let window = MacWindow(id, app, axWindow, parent: data.parent, adaptiveWeight: data.adaptiveWeight, index: data.index)

if window.observe(destroyedObs, kAXUIElementDestroyedNotification) &&
if window.observe(refreshObs, kAXUIElementDestroyedNotification) &&
window.observe(refreshObs, kAXWindowDeminiaturizedNotification) &&
window.observe(refreshObs, kAXWindowMiniaturizedNotification) &&
window.observe(movedObs, kAXMovedNotification) &&
Expand Down Expand Up @@ -317,11 +317,6 @@ extension UnsafeMutableRawPointer {
var window: MacWindow? { Unmanaged.fromOpaque(self).takeUnretainedValue() }
}

private func destroyedObs(_ obs: AXObserver, ax: AXUIElement, notif: CFString, data: UnsafeMutableRawPointer?) {
data?.window?.garbageCollect()
refreshAndLayout()
}

func tryOnWindowDetected(_ window: Window, startup: Bool) {
switch window.parent.cases {
case .tilingContainer, .workspace, .macosMinimizedWindowsContainer,
Expand Down

0 comments on commit 405dec8

Please sign in to comment.