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

This commit is contained in:
Louis Pontoise
2021-02-02 01:55:26 +09:00
committed by lwouis
parent 0e4987da94
commit b02e8be802
5 changed files with 28 additions and 37 deletions
+1 -1
View File
@@ -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
View File
@@ -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
}
}
+3 -7
View File
@@ -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
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,
// 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
+1 -1
View File
@@ -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()