Reputation: 41
I'm trying to move windows around from other spaces to the current window and have wasted many hours not understanding why nothing is being moved..
I've tried various applications (hardcoding some screens now to test). I ensure window level is 0 and various other things, but the key thing is that the private API is not migrating the window. Common libs on the market today are using these calls on this Mac release, but I'm worried there is an additional step in the flow I'm missing.
Demo repo: https://github.com/Schachte/mac-os-graphics
I've tried thread sleeps between windows, etc. The main snippet is this:
static func addInitialRunningApplicationsWindows() {
let cgsMainConnectionId = CGSMainConnectionID()
let otherSpaces = [UInt64(213)]
print("Other spaces found: \(otherSpaces)")
guard otherSpaces.count > 0 else {
print("No other spaces found")
return
}
let windowsOnCurrentSpace = getWindowsInSpace([currentSpaceId])
print("Windows on current space: \(windowsOnCurrentSpace)")
let windowsOnOtherSpaces = getWindowsInSpace(otherSpaces)
print("Windows on other spaces: \(windowsOnOtherSpaces)")
let windowsOnlyOnOtherSpaces = Array(Set(windowsOnOtherSpaces).subtracting(windowsOnCurrentSpace))
print("Windows to move: \(windowsOnlyOnOtherSpaces)")
guard windowsOnlyOnOtherSpaces.count > 0 else {
print("No windows to move")
return
}
// Split windows into chunks to avoid overwhelming the API
let chunkSize = 5
let windowChunks = stride(from: 0, to: windowsOnlyOnOtherSpaces.count, by: chunkSize).map {
Array(windowsOnlyOnOtherSpaces[$0..<min($0 + chunkSize, windowsOnlyOnOtherSpaces.count)])
}
for chunk in windowChunks {
print("Processing chunk of \(chunk.count) windows")
// First add windows to the current space
CGSAddWindowsToSpaces(cgsMainConnectionId,
chunk as NSArray,
[currentSpaceId] as NSArray)
// Give the system a moment to process
Thread.sleep(forTimeInterval: 0.1)
// Then remove from other spaces
for spaceId in otherSpaces {
CGSRemoveWindowsFromSpaces(cgsMainConnectionId,
chunk as NSArray,
[spaceId] as NSArray)
// Give the system a moment to process
Thread.sleep(forTimeInterval: 0.1)
}
// Verify the move for this chunk
let windowsStillOnOtherSpaces = getWindowsInSpace(otherSpaces)
let unmovedInChunk = chunk.filter { windowsStillOnOtherSpaces.contains($0) }
if unmovedInChunk.count > 0 {
print("Warning: Failed to move \(unmovedInChunk.count) windows in current chunk")
// Try alternative method for unmoved windows
for windowId in unmovedInChunk {
if canMoveWindow(windowId) {
print("Attempting alternative move for window \(windowId)")
CGSMoveWindowsToManagedSpace(cgsMainConnectionId,
[windowId] as NSArray,
currentSpaceId)
Thread.sleep(forTimeInterval: 0.1)
}
}
}
}
5
Other spaces found: [213]
Windows on current space: [115, 99, 98, 94, 26, 100, 25, 27, 24, 22, 38, 12159, 10, 116, 942, 12493, 12557, 13406]
Windows on other spaces: [13749, 16723, 13747, 116, 13328]
Windows to move: [16723, 13749, 13747, 13328]
Processing chunk of 4 windows
Warning: Failed to move 4 windows in current chunk
Attempting alternative move for window 16723
Warning: Total failed moves: 4 windows
Unmoved window IDs: [16723, 13749, 13747, 13328]
5
Using inspiration from https://github.com/lwouis/alt-tab-macos
Thread sleeps, different windows, running as root, disabling SIP
Upvotes: 2
Views: 56