ion.wm

This module exposes live compositor state through five collections: desktops, outputs, workspaces, frames, and windows. It is only accessible inside callbacks (keybinding handlers, hook callbacks, operator exec functions).

Entity hierarchy

As a simplified mental model: Desktop -> Workspace -> Frame -> Window. The fuller picture is two layers per desktop. The tiling layer (desktop.items_tiling) holds workspaces, each assigned to all outputs or to a single output; a workspace owns a split tree of frames and a frame holds one or more tabbed windows. The floating layer (desktop.items_floating) holds free-positioned frames and whole-workspace overlays, interleaved in one z-order.

Entities link both ways: workspace.frames lists the frames in a workspace, while window.workspace returns the workspace a window belongs to. Scoped sub-collections (frame.windows, workspace.frames, desktop.items_tiling) filter to one parent; top-level collections (ion.wm.windows) span all parents.

Tiled vs floating

Tiled windows live inside the split tree. Floating windows live in the desktop’s floating layer and have no workspace - window.workspace returns None. Whole workspaces can also float as overlays.

Focus chain

Each collection has an active property. Walking from the active desktop down to the active window passes through entry wrappers, not directly through the entities: desktops.active -> desktop.items_tiling.active (a DesktopItemTilingWorkspace, so take its .workspace) -> workspace.frames.active -> frame.windows.active. When focus is on the floating layer, desktop.items_floating.active is the mutually exclusive alternative; it returns a DesktopItemFloatingFrame or DesktopItemFloatingWorkspace entry.

Split tree

The tiling structure is a binary tree accessible from workspace.split_root. Each node is either a container (with children and a split axis) or a leaf holding a single frame.

Context

ion.wm.context is the action context accessor - for example, which tab is under the pointer when a tab-bar binding fires. Use this when the target differs from the focused item.

Cursor stack

The compositor maintains a stack of CSS cursor icons; the top of the stack is what the user sees. Push and pop entries via the cursor functions in this module. The stack clears when all generators exit.

Overlays

ion.wm.overlay_root is the root of the overlay tree. Append Overlay children to draw custom geometry on the compositor surface.

Output and workspaces

Outputs do not directly reference their workspace. Workspace-to-output assignments are managed through the desktop.

Collections

Collections generally provide sequence-style access - len(), iteration, and indexing - and most expose an active property for the currently focused item plus find_by_* methods for reverse lookups. Membership testing with in is available on most collections but not all. Check the generated class for each collection for its exact protocol support.

Proxy objects

Values returned by collections are lightweight proxies identified by a unique id (or index for desktops). A proxy stays valid as long as the underlying object exists; accessing a stale proxy raises ReferenceError. Use is_valid to check. This most often bites when a proxy is held across callbacks or generator yields, since the underlying window, frame, or workspace may be removed before it is reused.

Window manager state access with proxy objects.

Querying Runtime State

The ion.wm module exposes live collections for windows, workspaces, outputs, frames, and desktops. Each collection supports iteration, indexing, len(), and an active property.

These queries are typically used inside hook callbacks or operator exec functions.


import ion


@ion.app.hooks.window_new_post.append
def on_window_new(window: ion.types.Window) -> None:
    print("New window:", window.title, window.app_id)
    print("Total windows:", len(ion.wm.windows))

    # Show which output received the window.
    for output in ion.wm.outputs:
        r = output.rect
        print(" ", output.name, r.min, r.size)

    # List workspaces on the active desktop.
    desktop = ion.wm.desktops.active
    for item in desktop.items_tiling:
        if isinstance(item, ion.types.DesktopItemTilingWorkspace):
            ws = item.workspace
            print("  Workspace:", ws.name, "frames:", len(ws.frames))

Functions

ion.wm.cursor_pop(token)

Pop a cursor stack entry and all entries pushed after it.

If the token has already been popped, this is a no-op.

Parameters:

token (CursorToken) – Token returned by cursor_push().

Return type:

None

ion.wm.cursor_push(name)

Push a cursor icon onto the cursor stack.

The top of the stack determines the displayed cursor. When all generators exit, the entire cursor stack is cleared.

Parameters:

name (str) – CSS cursor name (e.g. "grabbing", "col-resize").

Returns:

Opaque token for cursor_pop().

Return type:

CursorToken

Data

ion.wm.context

Accessor object exposed as ion.wm.context.

Exposes the elements the current keymap or menu action targets. Each attribute is a lookup of the current focus - so a keyboard binding and a menu opened on the focused frame see the same thing - unless the action’s region overrode it for the click (e.g. the root menu’s pointer output, or the divider’s split). Attributes are None only when nothing of that kind is in use.

Type:

ion.types.ContextAccessor

ion.wm.desktops

Collection accessor for desktops (ion.wm.desktops).

Type:

ion.types.DesktopCollection

ion.wm.frames

Collection accessor for frames.

Type:

ion.types.FrameCollection

ion.wm.outputs

Collection accessor for outputs.

Type:

ion.types.OutputCollection

ion.wm.overlay_root
class ion.wm.OverlayGroup(Overlay)

A grouping overlay that applies a position and scale transform to its children. When alpha is 1.0, children render individually (fast path). When alpha is less than 1.0 and use_alpha_merged is true (default), children are composited to an offscreen texture first, then the texture is drawn with the group’s alpha, treating the group as a single visual unit. When use_alpha_merged is false, the alpha is applied to each child element individually (no FBO overhead, but overlapping children show through each other).

__init__(self)
Return type:

None

Type:

ion.types.OverlayGroup

ion.wm.windows

Collection accessor for windows.

Type:

ion.types.WindowCollection

ion.wm.workspaces

Collection accessor for workspaces.

Type:

ion.types.WorkspaceCollection