diff --git a/src/api-wrappers/PrivateApis.swift b/src/api-wrappers/PrivateApis.swift index 2b95ff65..c7edbed1 100644 --- a/src/api-wrappers/PrivateApis.swift +++ b/src/api-wrappers/PrivateApis.swift @@ -52,8 +52,61 @@ func CGSGetWindowOwner(_ cid: CGSConnectionID, _ wid: CGWindowID, _ windowCid: i func CGSGetConnectionPSN(_ cid: CGSConnectionID, _ psn: inout ProcessSerialNumber) -> CGError // returns an array of displays (as NSDictionary) -> each having an array of spaces (as NSDictionary) at the "Spaces" key; each having a space ID (as UInt64) at the "id64" key -// /!\ only returns correct values if the user has checked the checkbox in Preferences > Mission Control > "Displays have separate Spaces" // * macOS 10.10+ +// /!\ only returns correct values if the user has checked the checkbox in Preferences > Mission Control > "Displays have separate Spaces" +// See this example with 2 monitors (1 laptop internal + 1 external): +// * Output with "Displays have separate Spaces" checked: +// [{ +// "Current Space" = { +// ManagedSpaceID = 4; +// id64 = 4; +// type = 0; +// uuid = "6622AC87-2FD2-48E8-934D-F6EB303AC9BA"; +// }; +// "Display Identifier" = "6FBB92D9-84CE-8D20-C114-3B1052DD9529"; +// Spaces = ( +// { +// ManagedSpaceID = 4; +// id64 = 4; +// type = 0; +// uuid = "6622AC87-2FD2-48E8-934D-F6EB303AC9BA"; +// } +// ); +// }, { +// "Current Space" = { +// ManagedSpaceID = 5; +// id64 = 5; +// type = 0; +// uuid = "BE05AFA2-B253-4199-B39E-A8E77CD4851B"; +// }; +// "Display Identifier" = "BB2327F9-3D4F-FD8F-A0EA-B9745A0B818F"; +// Spaces = ( +// { +// ManagedSpaceID = 5; +// id64 = 5; +// type = 0; +// uuid = "BE05AFA2-B253-4199-B39E-A8E77CD4851B"; +// } +// ); +// }] +// * Output with "Displays have separate Spaces" unchecked: +// [{ +// "Current Space" = { +// ManagedSpaceID = 4; +// id64 = 4; +// type = 0; +// uuid = "6622AC87-2FD2-48E8-934D-F6EB303AC9BA"; +// }; +// "Display Identifier" = Main; +// Spaces = ( +// { +// ManagedSpaceID = 4; +// id64 = 4; +// type = 0; +// uuid = "6622AC87-2FD2-48E8-934D-F6EB303AC9BA"; +// } +// ); +// }] @_silgen_name("CGSCopyManagedDisplaySpaces") func CGSCopyManagedDisplaySpaces(_ cid: CGSConnectionID) -> CFArray diff --git a/src/logic/Spaces.swift b/src/logic/Spaces.swift index ce0d92e5..9b616d85 100644 --- a/src/logic/Spaces.swift +++ b/src/logic/Spaces.swift @@ -49,7 +49,10 @@ class Spaces { visibleSpaces.removeAll() var spaceIndex = SpaceIndex(1) (CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary]).forEach { (screen: NSDictionary) in - let display = screen["Display Identifier"] as! ScreenUuid + var display = screen["Display Identifier"] as! ScreenUuid + if display as String == "Main", let mainUuid = NSScreen.main?.uuid() { + display = mainUuid + } (screen["Spaces"] as! [NSDictionary]).forEach { (space: NSDictionary) in let spaceId = space["id64"] as! CGSSpaceID idsAndIndexes.append((spaceId, spaceIndex)) diff --git a/src/logic/Window.swift b/src/logic/Window.swift index eec378e2..4ad81bc8 100644 --- a/src/logic/Window.swift +++ b/src/logic/Window.swift @@ -218,8 +218,17 @@ class Window { } func isOnScreen(_ screen: NSScreen) -> Bool { - if let screenUuid = screen.uuid(), let screenSpaces = Spaces.screenSpacesMap[screenUuid] { - return screenSpaces.contains { $0 == spaceId } + if NSScreen.screensHaveSeparateSpaces { + if let screenUuid = screen.uuid(), let screenSpaces = Spaces.screenSpacesMap[screenUuid] { + return screenSpaces.contains { $0 == spaceId } + } + } else { + if let topLeftCorner = position, let size = size { + 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) && Spaces.visibleSpaces.contains(spaceId) + } } return true }