fix: handle on-all-spaces windows better
This commit is contained in:
1 parent
4a8bdebacc
commit
4abe9f31ec
7 files changed
+36
-16
No files matched your search
@@ -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]) {
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user