diff --git a/alt-tab-macos/api-wrappers/AXUIElement.swift b/alt-tab-macos/api-wrappers/AXUIElement.swift index 8ae93458..e27bc07c 100644 --- a/alt-tab-macos/api-wrappers/AXUIElement.swift +++ b/alt-tab-macos/api-wrappers/AXUIElement.swift @@ -15,13 +15,15 @@ extension AXUIElement { } func isActualWindow(_ isAppHidden: Bool = false) -> Bool { - // TODO: should we displays windows that disappear when invoking Expose? (e.g. Outlook meeting reminder window) (see https://stackoverflow.com/a/49723037/2249756) // TODO: TotalFinder and XtraFinder double-window hacks (see #84) - // TODO: should we display menubar windows? (e.g. iStats Pro dropdown menu) // Some non-windows have subrole: nil (e.g. some OS elements), "AXUnknown" (e.g. Bartender), "AXSystemDialog" (e.g. Intellij tooltips) // Some non-windows have title: nil (e.g. some OS elements) // Minimized windows or windows of a hidden app have subrole "AXDialog" - return title() != nil && (subrole() == "AXStandardWindow" || isMinimized() || isAppHidden) + return title() != nil && (subrole() == "AXStandardWindow" || isMinimized() || isAppHidden) && isOnNormalLevel() + } + + func isOnNormalLevel() -> Bool { + return cgWindowId().level() == CGWindowLevelForKey(.normalWindow) } func title() -> String? { diff --git a/alt-tab-macos/api-wrappers/CGWindowID.swift b/alt-tab-macos/api-wrappers/CGWindowID.swift index e416363d..0775978a 100644 --- a/alt-tab-macos/api-wrappers/CGWindowID.swift +++ b/alt-tab-macos/api-wrappers/CGWindowID.swift @@ -6,6 +6,16 @@ extension CGWindowID { return cgProperty("kCGSWindowTitle", String.self) } + func level() -> CGWindowLevel { + var level = CGWindowLevel(0) + CGSGetWindowLevel(cgsMainConnectionId, self, &level) + return level + } + + func spaces() -> [CGSSpaceID] { + return CGSCopySpacesForWindows(cgsMainConnectionId, CGSSpaceMask.all.rawValue, [self] as CFArray) as! [CGSSpaceID] + } + func screenshot() -> CGImage? { // CGSHWCaptureWindowList var windowId_ = self diff --git a/alt-tab-macos/api-wrappers/PrivateApis.swift b/alt-tab-macos/api-wrappers/PrivateApis.swift index 79da6de5..858c788b 100644 --- a/alt-tab-macos/api-wrappers/PrivateApis.swift +++ b/alt-tab-macos/api-wrappers/PrivateApis.swift @@ -123,6 +123,11 @@ enum CGSSpaceMask: Int { @_silgen_name("CGSCopySpacesForWindows") func CGSCopySpacesForWindows(_ cid: CGSConnectionID, _ mask: CGSSpaceMask.RawValue, _ wids: CFArray) -> CFArray +// returns window level (see definition in CGWindowLevel.h) of provided window +// * macOS 10.10+ +@_silgen_name("CGSGetWindowLevel") @discardableResult +func CGSGetWindowLevel(_ cid: CGSConnectionID, _ wid: CGWindowID, _ level: inout CGWindowLevel) -> CGError + // ------------------------------------------------------------ @@ -151,11 +156,6 @@ func CGSCopySpacesForWindows(_ cid: CGSConnectionID, _ mask: CGSSpaceMask.RawVal //@_silgen_name("CGSGetWindowType") @discardableResult //func CGSGetWindowType(_ wid: CGWindowID, _ type: inout UInt32) -> CGError // -//// seems to always return 0, for windows in the same space, other space, minimized, etc -//// * macOS 10.10+ -//@_silgen_name("CGSGetWindowLevel") @discardableResult -//func CGSGetWindowLevel(_ cid: CGSConnectionID, _ wid: CGWindowID, _ level: inout UInt32) -> CGError -// //// * macOS 10.12+ //@_silgen_name("CGSProcessAssignToSpace") @discardableResult //func CGSProcessAssignToSpace(_ cid: CGSConnectionID, _ pid: pid_t, _ sid: CGSSpaceID) -> CGError diff --git a/alt-tab-macos/logic/Application.swift b/alt-tab-macos/logic/Application.swift index 5e7924cf..06e108d5 100644 --- a/alt-tab-macos/logic/Application.swift +++ b/alt-tab-macos/logic/Application.swift @@ -115,7 +115,6 @@ private func eventWindowCreated(_ app: App, _ element: AXUIElement, _ applicatio private func eventFocusedWindowChanged(_ app: App, _ element: AXUIElement) { guard !app.appIsBeingUsed, - element.isActualWindow(), let existingIndex = Windows.list.firstIndexThatMatches(element) else { return } Windows.list.insert(Windows.list.remove(at: existingIndex), at: 0) } \ No newline at end of file diff --git a/alt-tab-macos/logic/Window.swift b/alt-tab-macos/logic/Window.swift index edf53422..da97e1d6 100644 --- a/alt-tab-macos/logic/Window.swift +++ b/alt-tab-macos/logic/Window.swift @@ -129,8 +129,7 @@ private func eventWindowMiniaturizedOrDeminiaturized(_ app: App, _ element: AXUI } private func eventWindowTitleChanged(_ app: App, _ element: AXUIElement) { - guard element.isActualWindow(), - let window = Windows.list.firstWindowThatMatches(element), + guard let window = Windows.list.firstWindowThatMatches(element), let newTitle = window.axUiElement.title(), newTitle != window.title else { return } window.title = newTitle diff --git a/alt-tab-macos/logic/Windows.swift b/alt-tab-macos/logic/Windows.swift index 7ed1b99a..ab56832f 100644 --- a/alt-tab-macos/logic/Windows.swift +++ b/alt-tab-macos/logic/Windows.swift @@ -28,7 +28,7 @@ class Windows { static func updateSpaces() { let spacesMap = Spaces.allIdsAndIndexes() for window in list { - let spaceIds = CGSCopySpacesForWindows(cgsMainConnectionId, CGSSpaceMask.all.rawValue, [window.cgWindowId] as CFArray) as! [CGSSpaceID] + let spaceIds = window.cgWindowId.spaces() guard spaceIds.count > 0 else { continue } if spaceIds.count > 1 { window.spaceId = Spaces.currentSpaceId