fix: would not correctly show windows/tabs from other spaces
This commit is contained in:
1 parent
6681a85111
commit
873f98525e
5 files changed
+26
-11
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
Reference in new issue
Block a user