diff --git a/src/api-wrappers/PrivateApis.swift b/src/api-wrappers/PrivateApis.swift index c68ba092..f822a6d1 100644 --- a/src/api-wrappers/PrivateApis.swift +++ b/src/api-wrappers/PrivateApis.swift @@ -112,10 +112,10 @@ func CGSCopyManagedDisplaySpaces(_ cid: CGSConnectionID) -> CFArray struct CGSCopyWindowsOptions: OptionSet { let rawValue: Int - static let minimizedAndTabbed = CGSCopyWindowsOptions(rawValue: 1 << 0) + static let invisible1 = CGSCopyWindowsOptions(rawValue: 1 << 0) // retrieves windows when their app is assigned to All Spaces, and windows at ScreenSaver level 1000 static let screenSaverLevel1000 = CGSCopyWindowsOptions(rawValue: 1 << 1) - static let minimized2 = CGSCopyWindowsOptions(rawValue: 1 << 2) + static let invisible2 = CGSCopyWindowsOptions(rawValue: 1 << 2) static let unknown1 = CGSCopyWindowsOptions(rawValue: 1 << 3) static let unknown2 = CGSCopyWindowsOptions(rawValue: 1 << 4) static let desktopIconWindowLevel2147483603 = CGSCopyWindowsOptions(rawValue: 1 << 5) diff --git a/src/logic/Spaces.swift b/src/logic/Spaces.swift index 22ad9c39..1908f3e3 100644 --- a/src/logic/Spaces.swift +++ b/src/logic/Spaces.swift @@ -69,11 +69,14 @@ class Spaces { return idsAndIndexes.filter { $0.0 != currentSpaceId }.map { $0.0 } } - static func windowsInSpaces(_ spaceIds: [CGSSpaceID]) -> [CGWindowID] { + static func windowsInSpaces(_ spaceIds: [CGSSpaceID], _ includeInvisible: Bool = true) -> [CGWindowID] { var set_tags = ([] as CGSCopyWindowsTags).rawValue var clear_tags = ([] as CGSCopyWindowsTags).rawValue - let options = ([.minimizedAndTabbed, .screenSaverLevel1000] as CGSCopyWindowsOptions).rawValue - return CGSCopyWindowsWithOptionsAndTags(cgsMainConnectionId, 0, spaceIds as CFArray, options, &set_tags, &clear_tags) as! [CGWindowID] + var options = [.screenSaverLevel1000] as CGSCopyWindowsOptions + if includeInvisible { + options = [options, .invisible1, .invisible2] + } + return CGSCopyWindowsWithOptionsAndTags(cgsMainConnectionId, 0, spaceIds as CFArray, options.rawValue, &set_tags, &clear_tags) as! [CGWindowID] } static func isSingleSpace() -> Bool { diff --git a/src/logic/Windows.swift b/src/logic/Windows.swift index d3a948a6..169a95e8 100644 --- a/src/logic/Windows.swift +++ b/src/logic/Windows.swift @@ -228,10 +228,21 @@ class Windows { /// tabs detection is a flaky work-around the lack of public API to observe OS tabs /// see: https://github.com/lwouis/alt-tab-macos/issues/1540 static func detectTabbedWindows() { - let cgsWindowIds = Spaces.windowsInSpaces(Spaces.idsAndIndexes.map { $0.0 }) + lazy var cgsWindowIds = Spaces.windowsInSpaces(Spaces.idsAndIndexes.map { $0.0 }) + lazy var visibleCgsWindowIds = Spaces.windowsInSpaces(Spaces.idsAndIndexes.map { $0.0 }, false) list.forEach { if let cgWindowId = $0.cgWindowId { - $0.isTabbed = !cgsWindowIds.contains(cgWindowId) + if $0.isMinimized || $0.isHidden { + if #available(macOS 13, *) { + // not exact after window merging + $0.isTabbed = !cgsWindowIds.contains(cgWindowId) + } else { + // not known + $0.isTabbed = false + } + } else { + $0.isTabbed = !visibleCgsWindowIds.contains(cgWindowId) + } } } }