Macotron

macotron.spaces

List the desktops (Spaces) on each display, find the one you are on, switch to another, and send a window to a different desktop.

macotron.keyboard.on("Next desktop", "ctrl+opt+right", () => {
  const desktops = macotron.spaces.list().filter((s) => s.type === "user");
  const i = desktops.findIndex((s) => s.current);
  const next = desktops[(i + 1) % desktops.length];
  macotron.spaces.go(next.desktop);
});

macOS has no public API for Spaces. This module uses private system functions, which a macOS update can change or remove. When they are missing, list() returns [] and the other calls return null or false.

Space objects

FieldMeaning
idThe system's id for the space.
indexIts position on its display, counting from 1.
desktopIts position across all displays, counting from 1. Full-screen apps count too.
displayThe UUID string of the display it belongs to.
currenttrue for the space showing on its display. With several displays, more than one space can be current.
type"user" for a normal desktop, "fullscreen" for a full-screen app, "other" for anything else.

Reading spaces

list(): Space[]

Every space on every display, in the order Mission Control shows them.

current(): Space | null

The current space. With several displays, it is the first current space in the list.

Switching and moving

go() and moveWindow() take the same spec:

go(spec): boolean

Switches to the space. Returns false when no space matches. A true result means the request was sent, not that the switch happened.

moveWindow(windowID: number, spec): boolean

Moves a window to the space. windowID is the id from macotron.window. Returns false when the window or the space is not found.

Recent macOS versions may refuse to move another app's window while System Integrity Protection is on. The call returns true even then, so check the window afterward if it matters.

Events

space:changed

Fires when the current space changes on any display. The payload is the new current space object, the same as current(), or {} when there is none.

macotron.on("space:changed", (space) => {
  macotron.notify.toast("Desktop", String(space.desktop));
});

See also