Skip to content

Commit

Permalink
fix: handle on-all-spaces windows better
Browse files Browse the repository at this point in the history
  • Loading branch information
louis.pontoise authored and lwouis committed Mar 10, 2020
1 parent 4a8bdeb commit 4abe9f3
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 16 deletions.
8 changes: 7 additions & 1 deletion alt-tab-macos/logic/Applications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ class Applications {
NSWorkspace.shared.addObserver(Applications.appsObserver, forKeyPath: "runningApplications", options: [.old, .new], context: nil)
}

static func reviewRunningApplicationsWindows() {
static func addInitialRunningApplicationsWindows() {
let windows = Spaces.windowsInSpaces(Spaces.otherSpaces()).filter { window in
return Windows.list.first(where: { $0.cgWindowId == window }) == nil
}
CGSAddWindowsToSpaces(cgsMainConnectionId, windows as NSArray, [Spaces.currentSpaceId])
for app in list {
guard app.runningApplication.isFinishedLaunching else { continue }
app.observeNewWindows()
}
Windows.sortByLevel()
CGSRemoveWindowsFromSpaces(cgsMainConnectionId, windows as NSArray, [Spaces.currentSpaceId])
}

static func addRunningApplications(_ runningApps: [NSRunningApplication]) {
Expand Down
13 changes: 4 additions & 9 deletions alt-tab-macos/logic/Spaces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ class Spaces {
static func observeSpaceChanges() {
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.activeSpaceDidChangeNotification, object: nil, queue: nil, using: { _ in
updateCurrentSpace()
guard visitedSpaces[Spaces.currentSpaceId] == nil else { return }
visitedSpaces[Spaces.currentSpaceId] = true
// when visiting a space for the first time, we review windows that we could not gather before the visit, from the other space
Applications.reviewRunningApplicationsWindows()
})
}

Expand All @@ -23,17 +19,16 @@ class Spaces {
debugPrint("current space", Spaces.currentSpaceId)
}

static func updateInitialSpace() {
updateCurrentSpace()
visitedSpaces[Spaces.currentSpaceId] = true
}

static func allIdsAndIndexes() -> [(CGSSpaceID, SpaceIndex)] {
return (CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary])
.map { return $0["Spaces"] }.joined().enumerated()
.map { (($0.element as! NSDictionary)["id64"]! as! CGSSpaceID, $0.offset + 1) }
}

static func otherSpaces() -> [CGSSpaceID] {
return allIdsAndIndexes().filter { $0.0 != Spaces.currentSpaceId }.map { $0.0 }
}

static func windowsInSpaces(_ spaceIds: [CGSSpaceID]) -> [CGWindowID] {
var set_tags = UInt64(0)
var clear_tags = UInt64(0)
Expand Down
2 changes: 2 additions & 0 deletions alt-tab-macos/logic/Window.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Window {
var icon: NSImage?
var isHidden: Bool
var isMinimized: Bool
var isOnAllSpaces: Bool
var spaceId: CGSSpaceID?
var spaceIndex: SpaceIndex?
var axUiElement: AXUIElement
Expand All @@ -24,6 +25,7 @@ class Window {
self.isMinimized = axUiElement.isMinimized()
self.spaceId = Spaces.currentSpaceId
self.spaceIndex = Spaces.currentSpaceIndex
self.isOnAllSpaces = false
self.title = Window.bestEffortTitle(axUiElement, cgWindowId, application)
debugPrint("Adding window: " + title, application.runningApplication.bundleIdentifier, Spaces.currentSpaceId, Spaces.currentSpaceIndex)
observeEvents()
Expand Down
13 changes: 10 additions & 3 deletions alt-tab-macos/logic/Windows.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ class Windows {
static func updateSpaces() {
let spacesMap = Spaces.allIdsAndIndexes()
for window in list {
guard let spaceId = (CGSCopySpacesForWindows(cgsMainConnectionId, CGSSpaceMask.all.rawValue, [window.cgWindowId] as CFArray) as! [CGSSpaceID]).first else { continue }
window.spaceId = spaceId
window.spaceIndex = spacesMap.first { $0.0 == spaceId }!.1
let spaceIds = CGSCopySpacesForWindows(cgsMainConnectionId, CGSSpaceMask.all.rawValue, [window.cgWindowId] as CFArray) as! [CGSSpaceID]
guard spaceIds.count > 0 else { continue }
if spaceIds.count > 1 {
window.spaceId = Spaces.currentSpaceId
window.spaceIndex = Spaces.currentSpaceIndex
window.isOnAllSpaces = true
continue
}
window.spaceId = spaceIds.first!
window.spaceIndex = spacesMap.first { $0.0 == spaceIds.first! }!.1
}
}

Expand Down
5 changes: 3 additions & 2 deletions alt-tab-macos/ui/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ class App: NSApplication, NSApplicationDelegate, NSWindowDelegate {
Preferences.loadFromDiskAndUpdateValues()
statusItem = StatusItem.make(self)
initPreferencesDependentComponents()
Spaces.updateInitialSpace()
Spaces.updateCurrentSpace()
Spaces.updateIsSingleSpace()
Applications.addInitialRunningApplications()
Applications.observeRunningApplications()
Spaces.observeSpaceChanges()
Windows.sortByLevel()
Applications.addInitialRunningApplicationsWindows()
Keyboard.listenToGlobalEvents(self)
}

Expand Down
6 changes: 5 additions & 1 deletion alt-tab-macos/ui/Cell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ class Cell: NSCollectionViewItem {
minimizedIcon.isHidden = !window!.isMinimized
spaceIcon.isHidden = element.spaceIndex == nil || Spaces.isSingleSpace || Preferences.hideSpaceNumberLabels
if !spaceIcon.isHidden {
spaceIcon.setNumber(UInt32(element.spaceIndex!))
if element.isOnAllSpaces {
spaceIcon.setStar()
} else {
spaceIcon.setNumber(UInt32(element.spaceIndex!))
}
}
let fontIconWidth = CGFloat([minimizedIcon, hiddenIcon, spaceIcon].filter { !$0.isHidden }.count) * (Preferences.fontIconSize + Preferences.interItemPadding)
label.textContainer!.size.width = thumbnail.frame.width - Preferences.iconSize! - Preferences.interItemPadding - fontIconWidth
Expand Down
5 changes: 5 additions & 0 deletions alt-tab-macos/ui/FontIcon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class FontIcon: CellTitle {
static let sfSymbolCircledDotSign = "􀍷"
static let sfSymbolCircledNumber0 = "􀀸"
static let sfSymbolCircledNumber10 = "􀓵"
static let sfSymbolCircledStart = "􀕬"

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
Expand All @@ -28,6 +29,10 @@ class FontIcon: CellTitle {
string = String(UnicodeScalar(baseCharacter.unicodeScalars.first!.value + offset)!)
}

func setStar() {
string = FontIcon.sfSymbolCircledStart
}

private func baseCharacterAndOffset(_ number: UInt32) -> (String, UInt32) {
if number <= 9 {
// numbers alternate between empty and full circles; we skip the full circles
Expand Down

0 comments on commit 4abe9f3

Please sign in to comment.