mirror of
https://github.com/lwouis/alt-tab-macos.git
synced 2026-05-24 11:20:36 +00:00
fix: didn't show windows on same screen (closes #794)
This commit is contained in:
@@ -18,7 +18,7 @@ class DebugProfile {
|
||||
("OS version", ProcessInfo.processInfo.operatingSystemVersionString),
|
||||
("OS architecture", Sysctl.run("hw.machine")),
|
||||
("Locale", Locale.current.debugDescription),
|
||||
("Spaces", String(Spaces.allIdsAndIndexes().count)),
|
||||
("Spaces", String(Spaces.idsAndIndexes.count)),
|
||||
("Dark mode", defaults.string(forKey: "AppleInterfaceStyle") ?? "Light"),
|
||||
("\"Displays have separate Spaces\"", NSScreen.screensHaveSeparateSpaces ? "checked" : "unchecked"),
|
||||
// hardware
|
||||
|
||||
+22
-27
@@ -2,21 +2,20 @@ import Cocoa
|
||||
|
||||
class Spaces {
|
||||
static var currentSpaceId = CGSSpaceID(1)
|
||||
static var screenToVisibleSpaceMap = [ScreenUuid: CGSSpaceID]()
|
||||
static var currentSpaceIndex = SpaceIndex(1)
|
||||
static var isSingleSpace = true
|
||||
static var idsAndIndexes: [(CGSSpaceID, SpaceIndex)] = allIdsAndIndexes()
|
||||
static var visibleSpaces = [CGSSpaceID]()
|
||||
static var screenSpacesMap = [ScreenUuid: [CGSSpaceID]]()
|
||||
static var idsAndIndexes = [(CGSSpaceID, SpaceIndex)]()
|
||||
|
||||
static func observeSpaceChanges() {
|
||||
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.activeSpaceDidChangeNotification, object: nil, queue: nil, using: { _ in
|
||||
debugPrint("OS event", "activeSpaceDidChangeNotification")
|
||||
idsAndIndexes = allIdsAndIndexes()
|
||||
refreshAllIdsAndIndexes()
|
||||
updateCurrentSpace()
|
||||
refreshVisibleSpaces()
|
||||
})
|
||||
NSWorkspace.shared.notificationCenter.addObserver(forName: NSApplication.didChangeScreenParametersNotification, object: nil, queue: nil, using: { _ in
|
||||
debugPrint("OS event", "didChangeScreenParametersNotification")
|
||||
refreshVisibleSpaces()
|
||||
refreshAllIdsAndIndexes()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,19 +27,9 @@ class Spaces {
|
||||
}
|
||||
}
|
||||
|
||||
static func refreshVisibleSpaces() {
|
||||
screenToVisibleSpaceMap.removeAll()
|
||||
NSScreen.screens.forEach {
|
||||
if let uuid = $0.uuid() {
|
||||
screenToVisibleSpaceMap[uuid] = CGSManagedDisplayGetCurrentSpace(cgsMainConnectionId, uuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func initialDiscovery() {
|
||||
refreshAllIdsAndIndexes()
|
||||
updateCurrentSpace()
|
||||
refreshVisibleSpaces()
|
||||
updateIsSingleSpace()
|
||||
observeSpaceChanges()
|
||||
}
|
||||
|
||||
@@ -52,15 +41,21 @@ class Spaces {
|
||||
debugPrint("Current space", currentSpaceId)
|
||||
}
|
||||
|
||||
static func allIdsAndIndexes() -> [(CGSSpaceID, SpaceIndex)] {
|
||||
return (CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary])
|
||||
.map { (display: NSDictionary) -> [NSDictionary] in
|
||||
display["Spaces"] as! [NSDictionary]
|
||||
}
|
||||
.joined().enumerated()
|
||||
.map { (space: (offset: Int, element: NSDictionary)) -> (CGSSpaceID, SpaceIndex) in
|
||||
(space.element["id64"]! as! CGSSpaceID, space.offset + 1)
|
||||
static func refreshAllIdsAndIndexes() -> Void {
|
||||
idsAndIndexes.removeAll()
|
||||
screenSpacesMap.removeAll()
|
||||
visibleSpaces.removeAll()
|
||||
var spaceIndex = 0
|
||||
(CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary]).forEach { (screen: NSDictionary) in
|
||||
let display = screen["Display Identifier"] as! ScreenUuid
|
||||
(screen["Spaces"] as! [NSDictionary]).forEach { (space: NSDictionary) in
|
||||
let spaceId = space["id64"] as! CGSSpaceID
|
||||
idsAndIndexes.append((spaceId, spaceIndex))
|
||||
screenSpacesMap[display, default: []].append(spaceId)
|
||||
spaceIndex += 1
|
||||
}
|
||||
visibleSpaces.append((screen["Current Space"] as! NSDictionary)["id64"] as! CGSSpaceID)
|
||||
}
|
||||
}
|
||||
|
||||
static func otherSpaces() -> [CGSSpaceID] {
|
||||
@@ -73,8 +68,8 @@ class Spaces {
|
||||
return CGSCopyWindowsWithOptionsAndTags(cgsMainConnectionId, 0, spaceIds as CFArray, 2, &set_tags, &clear_tags) as! [CGWindowID]
|
||||
}
|
||||
|
||||
static func updateIsSingleSpace() {
|
||||
isSingleSpace = idsAndIndexes.count == 1
|
||||
static func isSingleSpace() -> Bool {
|
||||
return idsAndIndexes.count == 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,6 @@ class Windows {
|
||||
}
|
||||
|
||||
static func updateSpaces() {
|
||||
Spaces.updateIsSingleSpace()
|
||||
// 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()
|
||||
@@ -196,17 +195,14 @@ class Windows {
|
||||
!(!(Preferences.showFullscreenWindows[App.app.shortcutIndex] != .hide) && window.isFullscreen) &&
|
||||
!(!(Preferences.showMinimizedWindows[App.app.shortcutIndex] != .hide) && window.isMinimized) &&
|
||||
!(Preferences.spacesToShow[App.app.shortcutIndex] == .active && window.spaceId != Spaces.currentSpaceId) &&
|
||||
!(Preferences.spacesToShow[App.app.shortcutIndex] == .visible && !Spaces.screenToVisibleSpaceMap.values.contains(window.spaceId)) &&
|
||||
!(Preferences.spacesToShow[App.app.shortcutIndex] == .visible && !Spaces.visibleSpaces.contains(window.spaceId)) &&
|
||||
!(Preferences.screensToShow[App.app.shortcutIndex] == .showingAltTab && !isOnScreen(window, screen)) &&
|
||||
(Preferences.showTabsAsWindows || !window.isTabbed))
|
||||
}
|
||||
|
||||
static func isOnScreen(_ window: Window, _ screen: NSScreen) -> Bool {
|
||||
if let topLeftCorner = window.position, let size = window.size, let screenUuid = screen.uuid(), let screenSpaceId = Spaces.screenToVisibleSpaceMap[screenUuid] {
|
||||
var screenFrameInQuartzCoordinates = screen.frame
|
||||
screenFrameInQuartzCoordinates.origin.y = NSMaxY(NSScreen.screens[0].frame) - NSMaxY(screen.frame)
|
||||
let windowRect = CGRect(origin: topLeftCorner, size: size)
|
||||
return windowRect.intersects(screenFrameInQuartzCoordinates) && screenSpaceId == window.spaceId
|
||||
if let screenUuid = screen.uuid(), let screenSpaces = Spaces.screenSpacesMap[screenUuid] {
|
||||
return screenSpaces.contains { $0 == window.spaceId }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
+1
-1
@@ -244,7 +244,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
// There's no way to observe this with the AX API, other than polling. However, when Mission Control is deactivated,
|
||||
// that AXGroup gets destroyed, triggering the uiElementDestroyed notification.
|
||||
// (At that point we won't be able to see what the element was, of course.)
|
||||
Spaces.idsAndIndexes = Spaces.allIdsAndIndexes()
|
||||
Spaces.refreshAllIdsAndIndexes()
|
||||
Windows.updateSpaces()
|
||||
let screen = NSScreen.preferred()
|
||||
self.shortcutIndex = shortcutIndex
|
||||
|
||||
@@ -127,7 +127,7 @@ class ThumbnailView: NSStackView {
|
||||
assignIfDifferent(&hiddenIcon.isHidden, !element.isHidden || Preferences.hideStatusIcons)
|
||||
assignIfDifferent(&fullscreenIcon.isHidden, !element.isFullscreen || Preferences.hideStatusIcons)
|
||||
assignIfDifferent(&minimizedIcon.isHidden, !element.isMinimized || Preferences.hideStatusIcons)
|
||||
assignIfDifferent(&spaceIcon.isHidden, Spaces.isSingleSpace || Preferences.hideSpaceNumberLabels)
|
||||
assignIfDifferent(&spaceIcon.isHidden, Spaces.isSingleSpace() || Preferences.hideSpaceNumberLabels)
|
||||
if !spaceIcon.isHidden {
|
||||
if element.spaceIndex > 30 || element.isOnAllSpaces {
|
||||
spaceIcon.setStar()
|
||||
|
||||
Reference in New Issue
Block a user