fix: would not correctly show windows/tabs from other spaces

This commit is contained in:
Louis Pontoise authored and lwouis committed 2020-05-07 14:11:22 +09:00
1 parent 6681a85111
commit 873f98525e
5 files changed
+26 -11

No files matched your search

+6 -3
View File
@@ -43,9 +43,12 @@ extension AXUIElement {
return attribute(kAXTitleAttribute, String.self)
}
func windows(_ bundleIdentifier: String?) -> [AXUIElement]? {
return attribute(kAXWindowsAttribute, [AXUIElement].self)?
.filter { $0.isActualWindow(bundleIdentifier) }
func windows() -> [AXUIElement]? {
return attribute(kAXWindowsAttribute, [AXUIElement].self)
}
func isTabbed(_ window: AXUIElement) -> Bool {
return windows()?.first(where: { $0 == window }) == nil
}
func isMinimized() -> Bool {
+3 -1
View File
@@ -12,6 +12,7 @@ class Application: NSObject {
kAXWindowCreatedNotification,
kAXApplicationHiddenNotification,
kAXApplicationShownNotification,
kAXFocusedUIElementChangedNotification,
]
// some apps never finish their subscription retry loop; they should be stopped to avoid infinite loop
@@ -51,7 +52,8 @@ class Application: NSObject {
}
func observeNewWindows() {
if let windows = axUiElement!.windows(runningApplication.bundleIdentifier) {
if let windows = (axUiElement!.windows()?
.filter { $0.isActualWindow(runningApplication.bundleIdentifier) }) {
let actualWindows = windows.filter { Windows.list.firstIndexThatMatches($0) == nil }
if actualWindows.count > 0 {
addWindows(actualWindows)
+2
View File
@@ -6,6 +6,7 @@ class Window {
var thumbnail: NSImage?
var icon: NSImage?
var shouldShowTheUser = true
var isTabbed: Bool
var isHidden: Bool
var isMinimized: Bool
var isOnAllSpaces: Bool
@@ -36,6 +37,7 @@ class Window {
self.application = application
self.cgWindowId = axUiElement.cgWindowId()
self.icon = application.runningApplication.icon
self.isTabbed = application.axUiElement!.isTabbed(axUiElement)
self.isHidden = application.runningApplication.isHidden
self.isMinimized = axUiElement.isMinimized()
self.spaceId = Spaces.currentSpaceId
+3 -7
View File
@@ -51,6 +51,8 @@ class Windows {
}
static func updatesWindowSpace(_ window: Window) {
// macOS bug: if you tab a window, then move the tab group to another space, other tabs from the tab group will stay on the current space
// you can use the Dock to focus one of the other tabs and it will teleport that tab in the current space, proving that it's a macOS bug
let spaceIds = window.cgWindowId.spaces()
if spaceIds.count == 1 {
window.spaceId = spaceIds.first!
@@ -104,13 +106,7 @@ class Windows {
!(Preferences.appsToShow == .active && window.application.runningApplication != NSWorkspace.shared.frontmostApplication) &&
!(Preferences.spacesToShow == .active && window.spaceId != Spaces.currentSpaceId) &&
!(Preferences.screensToShow == .showingAltTab && !isOnScreen(window, screen)) &&
(Preferences.showTabsAsWindows || !isTabbed(window))
}
static func isTabbed(_ window: Window) -> Bool {
let app = window.application
let windows = app.axUiElement?.windows(app.runningApplication.bundleIdentifier)
return windows?.first(where: { $0 == window.axUiElement }) == nil
(Preferences.showTabsAsWindows || !window.isTabbed)
}
static func isOnScreen(_ window: Window, _ screen: NSScreen) -> Bool {
@@ -14,10 +14,22 @@ func axObserverCallback(observer: AXObserver, element: AXUIElement, notification
kAXWindowDeminiaturizedNotification: windowMiniaturizedOrDeminiaturized(element, type)
case kAXTitleChangedNotification: windowTitleChanged(element)
case kAXWindowResizedNotification: windowResized(element)
case kAXFocusedUIElementChangedNotification: focusedUiElementChanged(element, applicationPointer)
default: return
}
}
private func focusedUiElementChanged(_ element: AXUIElement, _ applicationPointer: UnsafeMutableRawPointer?) {
// this event is the only opportunity we have to check if a window became a tab, or a tab became a window
// we can only detect tabs for windows on the current space, as AXUIElement.windows() only reports current space windows
let application = Unmanaged<Application>.fromOpaque(applicationPointer!).takeUnretainedValue()
Windows.list.forEach {
if $0.spaceId == Spaces.currentSpaceId && $0.application == application {
$0.isTabbed = application.axUiElement!.isTabbed($0.axUiElement)
}
}
}
private func applicationActivated(_ element: AXUIElement) {
guard let appFocusedWindow = element.focusedWindow(),
let existingIndex = Windows.list.firstIndexThatMatches(appFocusedWindow) else { return }