diff --git a/src/api-wrappers/AXUIElement.swift b/src/api-wrappers/AXUIElement.swift index 91a688ed..a85b62e2 100644 --- a/src/api-wrappers/AXUIElement.swift +++ b/src/api-wrappers/AXUIElement.swift @@ -89,7 +89,8 @@ extension AXUIElement { keynote(runningApp) || iina(runningApp) || openFlStudio(runningApp, title) || - crossoverWindow(runningApp, role, subrole, level) + crossoverWindow(runningApp, role, subrole, level) || + isAlwaysOnTopScrcpy(runningApp, level, role, subrole) ) || ( // CGWindowLevel == .normalWindow helps filter out iStats Pro and other top-level pop-overs, and floating windows level == CGWindow.normalLevel && ( @@ -218,6 +219,12 @@ extension AXUIElement { && (runningApp.localizedName == "wine64-preloader" || runningApp.executableURL?.absoluteString.contains("/winetemp-") ?? false) } + private static func isAlwaysOnTopScrcpy(_ runningApp: NSRunningApplication, _ level: CGWindowLevel, _ role: String?, _ subrole: String?) -> Bool { + // scrcpy presents as a floating window when "Always on top" is enabled, so it doesn't get picked up normally. + // It also doesn't have a bundle ID, so we need to match using the localized name, which should always be the same. + return runningApp.localizedName == "scrcpy" && level == CGWindow.floatingWindow && role == kAXWindowRole && subrole == kAXStandardWindowSubrole + } + func position() throws -> CGPoint? { return try value(kAXPositionAttribute, CGPoint.zero, .cgPoint) } diff --git a/src/api-wrappers/CGWindow.swift b/src/api-wrappers/CGWindow.swift index 1f1f997f..79def969 100644 --- a/src/api-wrappers/CGWindow.swift +++ b/src/api-wrappers/CGWindow.swift @@ -5,6 +5,7 @@ typealias CGWindow = [CFString: Any] extension CGWindow { static let normalLevel = CGWindowLevelForKey(.normalWindow) static let baseLevel = CGWindowLevelForKey(.baseWindow) + static let floatingWindow = CGWindowLevelForKey(.floatingWindow) static func windows(_ option: CGWindowListOption) -> [CGWindow] { return CGWindowListCopyWindowInfo([.excludeDesktopElements, option], kCGNullWindowID) as! [CGWindow]