Selkies
Developer Referencedisplay_utils_xrandr

MultiMonitorWindowManager

Restarts X11 window management once a session has two displays, where the manager running needs it.

A window manager that reads the monitor set only as it starts tiles a maximized window across the whole framebuffer rather than the per-display regions an extended layout defines; restarted, it reads the set the layout published. None of this applies where the displays are outputs of their own (has_pluggable_outputs): a second output arriving is a hotplug, which every manager follows. Which managers need that is measured (RESTART_TO_READ_MONITORS), not configured, and the one running is restarted with the command line it was started with plus --replace, so it keeps the configuration chain its session gave it, less the options that would run the session's autostart again (restart_command). Both transports share this state: once per session, since a second restart would take window management away from whoever is using it. Wayland sessions manage their own windows and never restart.

Functions

constructor__init__() -> None
Source Code
def __init__(self) -> None:
    self._done = False

Returns

None
funcensure_for(display_count, is_wayland) -> None

Restart the running window manager if it is one that needs it and this session has not yet.

The replacement is started detached, so it outlives this process's session.

Source Code
async def ensure_for(self, display_count: int, is_wayland: bool) -> None:
    """Restart the running window manager if it is one that needs it and
    this session has not yet.

    The replacement is started detached, so it outlives this process's
    session.
    """
    if is_wayland or self._done or display_count <= 1:
        return
    self._done = True
    if await has_pluggable_outputs():
        logger_app_resize.info(
            "Multi-monitor setup: the displays are outputs of their own, which "
            "every window manager follows live; no restart.")
        return
    running = await current_wm_name()
    needing = next((wm for wm in RESTART_TO_READ_MONITORS
                    if wm_name_matches(wm, running)), None)
    if needing is None:
        logger_app_resize.info(
            f"Multi-monitor setup: {running or 'no window manager'} keeps its "
            "monitor set current; no restart.")
        return
    replacing = await current_wm_pid()
    command = restart_command(wm_command(replacing)) or [needing]
    if "--replace" not in command:
        command.append("--replace")
    logger_app_resize.info(
        f"Multi-monitor setup: restarting {needing} to read the monitor set.")
    try:
        await asyncio.create_subprocess_exec(
            *command,
            stdout=asyncio.subprocess.DEVNULL,
            stderr=asyncio.subprocess.DEVNULL,
            start_new_session=True,
        )
    except Exception as e:
        logger_app_resize.error(f"Failed to restart {needing}: {e}")
        return
    # Before the layout applies: a WM snapshotting the monitor set mid-swap
    # re-tiles maximized windows across the whole framebuffer.
    if not await wait_for_wm(needing, replacing):
        logger_app_resize.warning(
            f"{needing} restart not confirmed; applying layout anyway.")
paramdisplay_countint
paramis_waylandbool

Returns

None

On this page

Edit on GitHub