SpaceAPI legacy format¶
This page documents the legacy notification names and delimiter-based payloads that remain available for existing clients. It is a compatibility reference, not a recommendation for new integrations. For new integrations, use the structured SpaceAPI protocol.
The legacy command getAllSpaces is not the structured JSON-RPC method with the same name. The legacy command returns newline-delimited text; JSON-RPC getAllSpaces returns an array of typed space objects.
SpaceAPI uses DistributedNotificationCenter. The notification prefix is:
dev.mqiu.DesktopRenamer
Request and response notifications¶
| Request | Response | Purpose |
|---|---|---|
GetActiveSpace |
ReturnActiveSpace |
Read the currently tracked active space. |
GetSpaceList |
ReturnSpaceList |
Read the known spaces and names. |
GetAPIVersion |
ReturnAPIVersion |
Read the external API contract version. |
PerformCommand |
CommandResult |
Execute a named legacy command and receive its result. |
| — | ReturnAPIState |
Receive API enabled/disabled changes. |
New clients should use the prefix dev.mqiu.DesktopRenamer, which matches the current app bundle identifier. DesktopRenamer accepts and emits the com.michaelqiu.DesktopRenamer prefix only for compatibility with existing integrations. Requests should be posted only after response observers have been registered. Legacy request notifications do not use the structured payload key.
Active-space payload¶
ReturnActiveSpace includes:
apiVersion: String
spaceUUID: String
spaceName: String
spaceNumber: NSNumber
This payload contains one spaceUUID; it is not a per-display array. Use structured getCurrentSpaceID or AppleScript get current space id when a client needs all currently visible space IDs.
Space-list payload¶
ReturnSpaceList includes an apiVersion value and a spaces array. Each entry contains:
spaceUUID: String
spaceName: String
spaceNumber: NSNumber
displayID: String
The app broadcasts updates when the active space or stored names change. A client should request an initial snapshot after subscribing, then reconcile subsequent broadcasts by identifier.
The delimiter formats are not escaped. A space name, display name, path, owner name, or title containing ~, |, or a newline can make positional parsing ambiguous; use the structured protocol when those values must round-trip exactly.
Legacy command channel¶
Post PerformCommand with a userInfo dictionary containing a command name and, when needed, string arguments:
import Foundation
let center = DistributedNotificationCenter.default()
let requestID = UUID().uuidString
let arguments = try JSONSerialization.data(
withJSONObject: ["spaceID": "SPACE-ID", "name": "Research"]
)
let argumentsJSON = String(decoding: arguments, as: UTF8.self)
center.post(
name: Notification.Name("dev.mqiu.DesktopRenamer.PerformCommand"),
object: nil,
userInfo: [
"requestID": requestID,
"command": "renameSpace",
"argumentsJSON": argumentsJSON
],
deliverImmediately: true
)
argumentsJSON must be a JSON object whose values are strings. The app also accepts an arguments dictionary containing only String values. The request ID is optional; when it is missing or empty, DesktopRenamer generates one for the response.
The command channel accepts the legacy command names supported by the app, including getAPIVersion, getSpaceSnapshot, getCurrentSpaceName, getCurrentSpaceID, getAllSpaces, switchToSpace, renameCurrentSpace, renameSpace, rearrangeSpace, moveWindowNext, moveWindowPrevious, moveWindowToSpace, reloadSpaceLabels, the six toggle... commands, getWindows, focusWindow, executeWindowAction, and moveSpecificWindow. getAPIInfo is only a structured-protocol method and is not implemented by PerformCommand.
Successful result strings use these legacy shapes:
getSpaceSnapshotreturns JSON withapiVersion,currentSpaceIDs,currentSpaceName,movedWindowsCount, andspaces. It has no structuredrevisionortimestamp; its space records containid,name,displayID,displayName,number,isFullscreen,isLocked, and an optionalappPath. Theid,currentSpaceID, andcurrentSpaceIDsvalues are macOS ManagedSpaceIDs in this legacy response; use the structured protocol for DesktopRenamer-owned IDs. These fields are additive for clients that already parse the legacy JSON snapshot.getAllSpacesreturns newline-delimitedManagedSpaceID~Name~DisplayName~Number~IsFullscreen~AppPathrecords, andgetWindowsreturns the delimiter format described in AppleScript window automation. These legacy IDs are macOS ManagedSpaceIDs, not persistent DesktopRenamer IDs.getCurrentSpaceIDreturns comma-separated macOS ManagedSpaceIDs.getAPIVersionandgetCurrentSpaceNamereturn text.- Mutating commands return an empty string. The six toggle commands return the new Boolean state as the string
trueorfalse.
CommandResult always includes requestID, apiVersion, and success. Successful results also include a string result (which may be empty); failures include an error string instead:
requestID: String
apiVersion: String
success: Bool
result: String # success only
error: String # failure only
The legacy command channel uses the same string command arguments as the structured method names: for example, direction is up or down, window IDs and process IDs are positive integer strings, and action is one of close, minimize, hide, enterFullScreen, exitFullScreen, quit, or restore. When SpaceAPI is disabled, legacy request listeners are not active and no legacy response is sent.
Payload reference¶
| Notification | userInfo |
Notes |
|---|---|---|
ReturnActiveSpace |
apiVersion, spaceUUID, spaceName, spaceNumber |
spaceNumber is 0 for the synthetic FULLSCREEN value. |
ReturnSpaceList |
apiVersion, spaces |
spaces is an array of dictionaries using the four space fields above, including displayID. |
ReturnAPIVersion |
apiVersion |
Sent in response to GetAPIVersion. |
CommandResult |
requestID, apiVersion, success, and either result or error |
Sent in response to PerformCommand; result is a string and may be empty. |
ReturnAPIState |
isEnabled |
A Boolean indicating whether the listener is active. |
Snapshot and version requests have no request ID or error response. If one of those responses is missing, check API state and request a fresh snapshot after subscribing. PerformCommand reports validation and execution failures through CommandResult when the legacy listener is active.
Swift example¶
let center = DistributedNotificationCenter.default()
let name = Notification.Name("dev.mqiu.DesktopRenamer.ReturnActiveSpace")
center.addObserver(forName: name, object: nil, queue: .main) { notification in
let spaceID = notification.userInfo?["spaceUUID"] as? String
let spaceName = notification.userInfo?["spaceName"] as? String
print(spaceID ?? "", spaceName ?? "")
}
center.post(name: Notification.Name("dev.mqiu.DesktopRenamer.GetActiveSpace"), object: nil)