Skip to content

Commit

Permalink
fix: don't display tabbed windows (closes #258)
Browse files Browse the repository at this point in the history
  • Loading branch information
lwouis committed May 6, 2020
1 parent b8eb0b4 commit 8419ad9
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 30 deletions.
5 changes: 3 additions & 2 deletions src/api-wrappers/AXUIElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ extension AXUIElement {
return attribute(kAXTitleAttribute, String.self)
}

func windows() -> [AXUIElement]? {
return attribute(kAXWindowsAttribute, [AXUIElement].self)
func windows(_ bundleIdentifier: String?) -> [AXUIElement]? {
return attribute(kAXWindowsAttribute, [AXUIElement].self)?
.filter { $0.isActualWindow(bundleIdentifier) }
}

func isMinimized() -> Bool {
Expand Down
8 changes: 3 additions & 5 deletions src/logic/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Application: NSObject {

static let notifications = [
kAXApplicationActivatedNotification,
kAXFocusedWindowChangedNotification,
kAXMainWindowChangedNotification,
kAXWindowCreatedNotification,
kAXApplicationHiddenNotification,
kAXApplicationShownNotification,
Expand Down Expand Up @@ -51,10 +51,8 @@ class Application: NSObject {
}

func observeNewWindows() {
if let windows = axUiElement!.windows() {
let actualWindows = windows.filter {
$0.isActualWindow(runningApplication.bundleIdentifier) && Windows.list.firstIndexThatMatches($0) == nil
}
if let windows = axUiElement!.windows(runningApplication.bundleIdentifier) {
let actualWindows = windows.filter { Windows.list.firstIndexThatMatches($0) == nil }
if actualWindows.count > 0 {
addWindows(actualWindows)
}
Expand Down
9 changes: 8 additions & 1 deletion src/logic/Windows.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ class Windows {
!(!Preferences.showHiddenWindows && window.isHidden) &&
!(Preferences.appsToShow == .active && window.application.runningApplication != NSWorkspace.shared.frontmostApplication) &&
!(Preferences.spacesToShow == .active && window.spaceId != Spaces.currentSpaceId) &&
!(Preferences.screensToShow == .showingAltTab && !isOnScreen(window, screen))
!(Preferences.screensToShow == .showingAltTab && !isOnScreen(window, screen)) &&
!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
}

static func isOnScreen(_ window: Window, _ screen: NSScreen) -> Bool {
Expand Down
27 changes: 16 additions & 11 deletions src/logic/events/AccessibilityEvents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ func axObserverCallback(observer: AXObserver, element: AXUIElement, notification
case kAXApplicationHiddenNotification,
kAXApplicationShownNotification: applicationHiddenOrShown(element, type)
case kAXWindowCreatedNotification: windowCreated(element, applicationPointer)
case kAXFocusedWindowChangedNotification: focusedWindowChanged(element)
case kAXMainWindowChangedNotification: focusedWindowChanged(element, applicationPointer)
case kAXUIElementDestroyedNotification: windowDestroyed(element)
case kAXWindowMiniaturizedNotification,
kAXWindowDeminiaturizedNotification: windowMiniaturizedOrDeminiaturized(element, type)
Expand All @@ -19,11 +19,10 @@ func axObserverCallback(observer: AXObserver, element: AXUIElement, notification
}

private func applicationActivated(_ element: AXUIElement) {
guard !App.app.appIsBeingUsed,
let appFocusedWindow = element.focusedWindow(),
guard let appFocusedWindow = element.focusedWindow(),
let existingIndex = Windows.list.firstIndexThatMatches(appFocusedWindow) else { return }
Windows.list.insert(Windows.list.remove(at: existingIndex), at: 0)
App.app.refreshOpenUi([Windows.list[0], Windows.list[existingIndex]], true)
App.app.refreshOpenUi([Windows.list[0], Windows.list[existingIndex]])
}

private func applicationHiddenOrShown(_ element: AXUIElement, _ type: String) {
Expand All @@ -32,7 +31,7 @@ private func applicationHiddenOrShown(_ element: AXUIElement, _ type: String) {
$0.application.axUiElement!.pid() == element.pid()
}
windows.forEach { $0.isHidden = type == kAXApplicationHiddenNotification }
App.app.refreshOpenUi(windows, true)
App.app.refreshOpenUi(windows)
}

private func windowCreated(_ element: AXUIElement, _ applicationPointer: UnsafeMutableRawPointer?) {
Expand All @@ -46,11 +45,17 @@ private func windowCreated(_ element: AXUIElement, _ applicationPointer: UnsafeM
App.app.refreshOpenUi([window])
}

private func focusedWindowChanged(_ element: AXUIElement) {
guard !App.app.appIsBeingUsed,
let existingIndex = Windows.list.firstIndexThatMatches(element) else { return }
Windows.list.insert(Windows.list.remove(at: existingIndex), at: 0)
App.app.refreshOpenUi([Windows.list[0], Windows.list[existingIndex]])
private func focusedWindowChanged(_ element: AXUIElement, _ applicationPointer: UnsafeMutableRawPointer?) {
if let existingIndex = Windows.list.firstIndexThatMatches(element) {
Windows.list.insert(Windows.list.remove(at: existingIndex), at: 0)
App.app.refreshOpenUi([Windows.list[0], Windows.list[existingIndex]])
} else {
let application = Unmanaged<Application>.fromOpaque(applicationPointer!).takeUnretainedValue()
if element.isActualWindow(application.runningApplication.bundleIdentifier) {
Windows.list.insert(Window(element, application), at: 0)
App.app.refreshOpenUi([Windows.list[0]])
}
}
}

private func windowDestroyed(_ element: AXUIElement) {
Expand All @@ -65,7 +70,7 @@ private func windowMiniaturizedOrDeminiaturized(_ element: AXUIElement, _ type:
guard let index = Windows.list.firstIndexThatMatches(element) else { return }
let window = Windows.list[index]
window.isMinimized = type == kAXWindowMiniaturizedNotification
App.app.refreshOpenUi([window], true)
App.app.refreshOpenUi([window])
}

private func windowTitleChanged(_ element: AXUIElement) {
Expand Down
20 changes: 9 additions & 11 deletions src/ui/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ class App: NSApplication, NSApplicationDelegate {
rebuildUi()
}

func refreshOpenUi(_ windowsToUpdate: [Window]? = nil, _ updateWindowsInfo: Bool = false) {
func refreshOpenUi(_ windowsToUpdate: [Window]? = nil) {
guard appIsBeingUsed else { return }
let currentScreen = Screen.preferred() // fix screen between steps since it could change (e.g. mouse moved to another screen)
// workaround: when Preferences > Mission Control > "Displays have separate Spaces" is unchecked,
// switching between displays doesn't trigger .activeSpaceDidChangeNotification; we get the latest manually
Spaces.refreshCurrentSpaceId()
refreshSpecificWindows(windowsToUpdate, updateWindowsInfo, currentScreen)
refreshSpecificWindows(windowsToUpdate, currentScreen)
guard appIsBeingUsed else { return }
thumbnailsPanel.thumbnailsView.updateItems(currentScreen)
guard appIsBeingUsed else { return }
Expand All @@ -169,18 +169,16 @@ class App: NSApplication, NSApplicationDelegate {
Screen.repositionPanel(thumbnailsPanel, currentScreen, .appleCentered)
}

private func refreshSpecificWindows(_ windowsToUpdate: [Window]?, _ updateWindowsInfo: Bool, _ currentScreen: NSScreen) -> ()? {
private func refreshSpecificWindows(_ windowsToUpdate: [Window]?, _ currentScreen: NSScreen) -> ()? {
windowsToUpdate?.forEach { (window: Window) in
guard appIsBeingUsed else { return }
window.refreshThumbnail()
if updateWindowsInfo {
Windows.refreshIfWindowShouldBeShownToTheUser(window, currentScreen)
if !window.shouldShowTheUser && window.cgWindowId == Windows.focusedWindow()!.cgWindowId {
let stepWithClosestWindow = Windows.windowIndexAfterCycling(-1) > Windows.focusedWindowIndex ? 1 : -1
Windows.cycleFocusedWindowIndex(stepWithClosestWindow)
} else {
Windows.updatesWindowSpace(window)
}
Windows.refreshIfWindowShouldBeShownToTheUser(window, currentScreen)
if !window.shouldShowTheUser && window.cgWindowId == Windows.focusedWindow()!.cgWindowId {
let stepWithClosestWindow = Windows.windowIndexAfterCycling(-1) > Windows.focusedWindowIndex ? 1 : -1
Windows.cycleFocusedWindowIndex(stepWithClosestWindow)
} else {
Windows.updatesWindowSpace(window)
}
}
}
Expand Down

0 comments on commit 8419ad9

Please sign in to comment.