fix: show finder file copy windows (closes #1466)
also improve dealing with steam windows
This commit is contained in:
1 parent
0af9e0f42e
commit
c78481b5b1
2 files changed
+47
-36
No files matched your search
@@ -80,13 +80,13 @@ extension AXUIElement {
|
||||
// Minimized windows or windows of a hidden app have subrole "AXDialog"
|
||||
// Activity Monitor main window subrole is "AXDialog" for a brief moment at launch; it then becomes "AXStandardWindow"
|
||||
|
||||
// debugPrint(runningApp.bundleIdentifier, title, level, CGWindow.normalLevel, subrole, role, size)
|
||||
|
||||
// Some non-windows have cgWindowId == 0 (e.g. windows of apps starting at login with the checkbox "Hidden" checked)
|
||||
return wid != 0 &&
|
||||
size != nil && size!.width > 100 && size!.height > 100 &&
|
||||
return wid != 0 && size != nil &&
|
||||
(books(runningApp) || keynote(runningApp) || iina(runningApp) || (
|
||||
// CGWindowLevel == .normalWindow helps filter out iStats Pro and other top-level pop-overs, and floating windows
|
||||
level == CGWindow.normalLevel &&
|
||||
jetbrainApp(runningApp, title, subrole) &&
|
||||
([kAXStandardWindowSubrole, kAXDialogSubrole].contains(subrole) ||
|
||||
openBoard(runningApp) ||
|
||||
adobeAudition(runningApp, subrole) ||
|
||||
@@ -95,17 +95,24 @@ extension AXUIElement {
|
||||
battleNetBootstrapper(runningApp, role) ||
|
||||
firefoxFullscreenVideo(runningApp, role) ||
|
||||
vlcFullscreenVideo(runningApp, role) ||
|
||||
androidEmulator(runningApp, title) ||
|
||||
sanGuoShaAirWD(runningApp) ||
|
||||
dvdFab(runningApp) ||
|
||||
drBetotte(runningApp))))
|
||||
drBetotte(runningApp) ||
|
||||
androidEmulator(runningApp, title)
|
||||
) &&
|
||||
mustHaveIfJetbrainApp(runningApp, title, subrole, size!) &&
|
||||
mustHaveIfSteam(runningApp, title, role)
|
||||
))
|
||||
}
|
||||
|
||||
private static func jetbrainApp(_ runningApp: NSRunningApplication, _ title: String?, _ subrole: String?) -> Bool {
|
||||
private static func mustHaveIfJetbrainApp(_ runningApp: NSRunningApplication, _ title: String?, _ subrole: String?, _ size: NSSize) -> Bool {
|
||||
// jetbrain apps sometimes generate non-windows that pass all checks in isActualWindow
|
||||
// they have no title, so we can filter them out based on that
|
||||
return runningApp.bundleIdentifier?.range(of: "^com\\.(jetbrains\\.|google\\.android\\.studio).*?$", options: .regularExpression) == nil ||
|
||||
(subrole == kAXStandardWindowSubrole || title != nil && title != "")
|
||||
// we also hide windows too small
|
||||
return runningApp.bundleIdentifier?.range(of: "^com\\.(jetbrains\\.|google\\.android\\.studio).*?$", options: .regularExpression) == nil || (
|
||||
(subrole == kAXStandardWindowSubrole || (title != nil && title != "")) &&
|
||||
size.width > 100 && size.height > 100
|
||||
)
|
||||
}
|
||||
|
||||
private static func iina(_ runningApp: NSRunningApplication) -> Bool {
|
||||
@@ -158,7 +165,13 @@ extension AXUIElement {
|
||||
private static func steam(_ runningApp: NSRunningApplication, _ title: String?, _ role: String?) -> Bool {
|
||||
// All Steam windows have subrole == AXUnknown
|
||||
// some dropdown menus are not desirable; they have title == "", or sometimes role == nil when switching between menus quickly
|
||||
return runningApp.bundleIdentifier == "com.valvesoftware.steam" && title != "" && role != nil
|
||||
return runningApp.bundleIdentifier == "com.valvesoftware.steam" && (title != nil && title != "" && role != nil)
|
||||
}
|
||||
|
||||
private static func mustHaveIfSteam(_ runningApp: NSRunningApplication, _ title: String?, _ role: String?) -> Bool {
|
||||
// All Steam windows have subrole == AXUnknown
|
||||
// some dropdown menus are not desirable; they have title == "", or sometimes role == nil when switching between menus quickly
|
||||
return runningApp.bundleIdentifier != "com.valvesoftware.steam" || (title != nil && title != "" && role != nil)
|
||||
}
|
||||
|
||||
private static func firefoxFullscreenVideo(_ runningApp: NSRunningApplication, _ role: String?) -> Bool {
|
||||
|
||||
+25
-27
@@ -65,26 +65,27 @@ class Application: NSObject {
|
||||
guard let self = self else { return }
|
||||
if let axWindows_ = try self.axUiElement!.windows(), axWindows_.count > 0 {
|
||||
// bug in macOS: sometimes the OS returns multiple duplicate windows (e.g. Mail.app starting at login)
|
||||
let axWindows = try Array(Set(axWindows_)).compactMap {
|
||||
if let wid = try $0.cgWindowId() {
|
||||
let title = try $0.title()
|
||||
let subrole = try $0.subrole()
|
||||
let role = try $0.role()
|
||||
let size = try $0.size()
|
||||
try Array(Set(axWindows_)).forEach { axWindow in
|
||||
if let wid = try axWindow.cgWindowId() {
|
||||
let title = try axWindow.title()
|
||||
let subrole = try axWindow.subrole()
|
||||
let role = try axWindow.role()
|
||||
let size = try axWindow.size()
|
||||
let level = try wid.level()
|
||||
if AXUIElement.isActualWindow(self.runningApplication, wid, level, title, subrole, role, size) {
|
||||
return ($0, wid, title, try $0.isFullscreen(), try $0.isMinimized(), try $0.position(), size)
|
||||
let isFullscreen = try axWindow.isFullscreen()
|
||||
let isMinimized = try axWindow.isMinimized()
|
||||
let position = try axWindow.position()
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if let window = self.addWindow(axWindow, wid, title, isFullscreen, isMinimized, position, size) {
|
||||
App.app.refreshOpenUi([window])
|
||||
} else if let window = self.addWindowslessAppsIfNeeded() {
|
||||
App.app.refreshOpenUi(window)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
} as [(AXUIElement, CGWindowID, String?, Bool, Bool, CGPoint?, CGSize?)]
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
var windows = self.addWindows(axWindows)
|
||||
if let window = self.addWindowslessAppsIfNeeded() {
|
||||
windows.append(contentsOf: window)
|
||||
}
|
||||
App.app.refreshOpenUi(windows)
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@@ -135,19 +136,16 @@ class Application: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
private func addWindows(_ axWindows: [(AXUIElement, CGWindowID, String?, Bool, Bool, CGPoint?, CGSize?)]) -> [Window] {
|
||||
let windows: [Window] = axWindows.compactMap { (axUiElement, wid, axTitle, isFullscreen, isMinimized, position, size) in
|
||||
if (Windows.list.firstIndex { $0.isEqualRobust(axUiElement, wid) }) == nil {
|
||||
let window = Window(axUiElement, self, wid, axTitle, isFullscreen, isMinimized, position, size)
|
||||
Windows.appendAndUpdateFocus(window)
|
||||
return window
|
||||
private func addWindow(_ axUiElement: AXUIElement, _ wid: CGWindowID, _ axTitle: String?, _ isFullscreen: Bool, _ isMinimized: Bool, _ position: CGPoint?, _ size: CGSize?) -> Window? {
|
||||
if (Windows.list.firstIndex { $0.isEqualRobust(axUiElement, wid) }) == nil {
|
||||
let window = Window(axUiElement, self, wid, axTitle, isFullscreen, isMinimized, position, size)
|
||||
Windows.appendAndUpdateFocus(window)
|
||||
if App.app.appIsBeingUsed {
|
||||
Windows.cycleFocusedWindowIndex(1)
|
||||
}
|
||||
return nil
|
||||
return window
|
||||
}
|
||||
if App.app.appIsBeingUsed {
|
||||
Windows.cycleFocusedWindowIndex(windows.count)
|
||||
}
|
||||
return windows
|
||||
return nil
|
||||
}
|
||||
|
||||
private func observeEvents() {
|
||||
|
||||
Reference in new issue
Block a user