fix: didn't show windows on same screen (closes #794)

This commit is contained in:
Louis Pontoise authored and lwouis committed 2021-02-02 01:55:26 +09:00
1 parent 0e4987da94
commit b02e8be802
5 files changed
+28 -37

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ class DebugProfile {
("OS version", ProcessInfo.processInfo.operatingSystemVersionString), ("OS version", ProcessInfo.processInfo.operatingSystemVersionString),
("OS architecture", Sysctl.run("hw.machine")), ("OS architecture", Sysctl.run("hw.machine")),
("Locale", Locale.current.debugDescription), ("Locale", Locale.current.debugDescription),
("Spaces", String(Spaces.allIdsAndIndexes().count)), ("Spaces", String(Spaces.idsAndIndexes.count)),
("Dark mode", defaults.string(forKey: "AppleInterfaceStyle") ?? "Light"), ("Dark mode", defaults.string(forKey: "AppleInterfaceStyle") ?? "Light"),
("\"Displays have separate Spaces\"", NSScreen.screensHaveSeparateSpaces ? "checked" : "unchecked"), ("\"Displays have separate Spaces\"", NSScreen.screensHaveSeparateSpaces ? "checked" : "unchecked"),
// hardware // hardware
+22 -27
View File
@@ -2,21 +2,20 @@ import Cocoa
class Spaces { class Spaces {
static var currentSpaceId = CGSSpaceID(1) static var currentSpaceId = CGSSpaceID(1)
static var screenToVisibleSpaceMap = [ScreenUuid: CGSSpaceID]()
static var currentSpaceIndex = SpaceIndex(1) static var currentSpaceIndex = SpaceIndex(1)
static var isSingleSpace = true static var visibleSpaces = [CGSSpaceID]()
static var idsAndIndexes: [(CGSSpaceID, SpaceIndex)] = allIdsAndIndexes() static var screenSpacesMap = [ScreenUuid: [CGSSpaceID]]()
static var idsAndIndexes = [(CGSSpaceID, SpaceIndex)]()
static func observeSpaceChanges() { static func observeSpaceChanges() {
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.activeSpaceDidChangeNotification, object: nil, queue: nil, using: { _ in NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.activeSpaceDidChangeNotification, object: nil, queue: nil, using: { _ in
debugPrint("OS event", "activeSpaceDidChangeNotification") debugPrint("OS event", "activeSpaceDidChangeNotification")
idsAndIndexes = allIdsAndIndexes() refreshAllIdsAndIndexes()
updateCurrentSpace() updateCurrentSpace()
refreshVisibleSpaces()
}) })
NSWorkspace.shared.notificationCenter.addObserver(forName: NSApplication.didChangeScreenParametersNotification, object: nil, queue: nil, using: { _ in NSWorkspace.shared.notificationCenter.addObserver(forName: NSApplication.didChangeScreenParametersNotification, object: nil, queue: nil, using: { _ in
debugPrint("OS event", "didChangeScreenParametersNotification") 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() { static func initialDiscovery() {
refreshAllIdsAndIndexes()
updateCurrentSpace() updateCurrentSpace()
refreshVisibleSpaces()
updateIsSingleSpace()
observeSpaceChanges() observeSpaceChanges()
} }
@@ -52,15 +41,21 @@ class Spaces {
debugPrint("Current space", currentSpaceId) debugPrint("Current space", currentSpaceId)
} }
static func allIdsAndIndexes() -> [(CGSSpaceID, SpaceIndex)] { static func refreshAllIdsAndIndexes() -> Void {
return (CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary]) idsAndIndexes.removeAll()
.map { (display: NSDictionary) -> [NSDictionary] in screenSpacesMap.removeAll()
display["Spaces"] as! [NSDictionary] visibleSpaces.removeAll()
} var spaceIndex = 0
.joined().enumerated() (CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary]).forEach { (screen: NSDictionary) in
.map { (space: (offset: Int, element: NSDictionary)) -> (CGSSpaceID, SpaceIndex) in let display = screen["Display Identifier"] as! ScreenUuid
(space.element["id64"]! as! CGSSpaceID, space.offset + 1) (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] { static func otherSpaces() -> [CGSSpaceID] {
@@ -73,8 +68,8 @@ class Spaces {
return CGSCopyWindowsWithOptionsAndTags(cgsMainConnectionId, 0, spaceIds as CFArray, 2, &set_tags, &clear_tags) as! [CGWindowID] return CGSCopyWindowsWithOptionsAndTags(cgsMainConnectionId, 0, spaceIds as CFArray, 2, &set_tags, &clear_tags) as! [CGWindowID]
} }
static func updateIsSingleSpace() { static func isSingleSpace() -> Bool {
isSingleSpace = idsAndIndexes.count == 1 return idsAndIndexes.count == 1
} }
} }
+3 -7
View File
@@ -109,7 +109,6 @@ class Windows {
} }
static func updateSpaces() { static func updateSpaces() {
Spaces.updateIsSingleSpace()
// workaround: when Preferences > Mission Control > "Displays have separate Spaces" is unchecked, // workaround: when Preferences > Mission Control > "Displays have separate Spaces" is unchecked,
// switching between displays doesn't trigger .activeSpaceDidChangeNotification; we get the latest manually // switching between displays doesn't trigger .activeSpaceDidChangeNotification; we get the latest manually
Spaces.refreshCurrentSpaceId() Spaces.refreshCurrentSpaceId()
@@ -196,17 +195,14 @@ class Windows {
!(!(Preferences.showFullscreenWindows[App.app.shortcutIndex] != .hide) && window.isFullscreen) && !(!(Preferences.showFullscreenWindows[App.app.shortcutIndex] != .hide) && window.isFullscreen) &&
!(!(Preferences.showMinimizedWindows[App.app.shortcutIndex] != .hide) && window.isMinimized) && !(!(Preferences.showMinimizedWindows[App.app.shortcutIndex] != .hide) && window.isMinimized) &&
!(Preferences.spacesToShow[App.app.shortcutIndex] == .active && window.spaceId != Spaces.currentSpaceId) && !(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.screensToShow[App.app.shortcutIndex] == .showingAltTab && !isOnScreen(window, screen)) &&
(Preferences.showTabsAsWindows || !window.isTabbed)) (Preferences.showTabsAsWindows || !window.isTabbed))
} }
static func isOnScreen(_ window: Window, _ screen: NSScreen) -> Bool { 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] { if let screenUuid = screen.uuid(), let screenSpaces = Spaces.screenSpacesMap[screenUuid] {
var screenFrameInQuartzCoordinates = screen.frame return screenSpaces.contains { $0 == window.spaceId }
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
} }
return true return true
} }
+1 -1
View File
@@ -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, // 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. // that AXGroup gets destroyed, triggering the uiElementDestroyed notification.
// (At that point we won't be able to see what the element was, of course.) // (At that point we won't be able to see what the element was, of course.)
Spaces.idsAndIndexes = Spaces.allIdsAndIndexes() Spaces.refreshAllIdsAndIndexes()
Windows.updateSpaces() Windows.updateSpaces()
let screen = NSScreen.preferred() let screen = NSScreen.preferred()
self.shortcutIndex = shortcutIndex self.shortcutIndex = shortcutIndex
+1 -1
View File
@@ -127,7 +127,7 @@ class ThumbnailView: NSStackView {
assignIfDifferent(&hiddenIcon.isHidden, !element.isHidden || Preferences.hideStatusIcons) assignIfDifferent(&hiddenIcon.isHidden, !element.isHidden || Preferences.hideStatusIcons)
assignIfDifferent(&fullscreenIcon.isHidden, !element.isFullscreen || Preferences.hideStatusIcons) assignIfDifferent(&fullscreenIcon.isHidden, !element.isFullscreen || Preferences.hideStatusIcons)
assignIfDifferent(&minimizedIcon.isHidden, !element.isMinimized || 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 !spaceIcon.isHidden {
if element.spaceIndex > 30 || element.isOnAllSpaces { if element.spaceIndex > 30 || element.isOnAllSpaces {
spaceIcon.setStar() spaceIcon.setStar()