or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-ewmh

Python implementation of Extended Window Manager Hints for querying and controlling EWMH-compliant window managers

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/ewmh@0.1.x

To install, run

npx @tessl/cli install tessl/pypi-ewmh@0.1.0

index.mddocs/

EWMH

A Python implementation of Extended Window Manager Hints (EWMH) specification for querying and controlling EWMH-compliant window managers on Linux/Unix systems. Built on top of python-xlib, it enables programmatic interaction with modern window managers to retrieve window information, manipulate window properties, manage desktops and workspaces, and perform window management operations.

Package Information

  • Package Name: ewmh
  • Package Type: pypi
  • Language: Python
  • Installation: pip install ewmh
  • Dependencies: python-xlib

Core Imports

from ewmh import EWMH

Alternative import pattern:

import ewmh
ewmh_instance = ewmh.EWMH()

Basic Usage

from ewmh import EWMH

# Initialize EWMH connection (uses default display and root window)
ewmh = EWMH()

# Get current active window
active_window = ewmh.getActiveWindow()
if active_window:
    print(f"Active window: {ewmh.getWmName(active_window)}")

# Get list of all managed windows
windows = ewmh.getClientList()
print(f"Total windows: {len(windows)}")

# Get desktop information
num_desktops = ewmh.getNumberOfDesktops()
current_desktop = ewmh.getCurrentDesktop()
print(f"Desktop {current_desktop + 1} of {num_desktops}")

# Set a window as active
if windows:
    ewmh.setActiveWindow(windows[0])
    ewmh.display.flush()  # Important: flush to send the request

# Clean up
ewmh.display.close()

Architecture

EWMH provides a comprehensive interface to the Extended Window Manager Hints specification through a single EWMH class. The architecture is organized around five main capability areas:

  • Desktop/Workspace Management: Query and control virtual desktops, geometry, viewports, and workspace properties
  • Window Discovery: Enumerate managed windows, get stacking order, and find active windows
  • Window Properties: Access window metadata like names, types, states, process IDs, and allowed actions
  • Window Control: Perform window operations including activation, movement, resizing, state changes, and closure
  • Generic Access: Use string-based property names for dynamic access to any EWMH property

The implementation builds on python-xlib for low-level X11 communication and provides both specific methods (e.g., getActiveWindow()) and generic property access (e.g., getProperty('_NET_ACTIVE_WINDOW')) for maximum flexibility. All operations require explicit display flushing to ensure commands are sent to the window manager.

Capabilities

EWMH Class

Main class providing access to all EWMH window manager functionality through getter and setter methods.

class EWMH:
    """
    Implementation of Extended Window Manager Hints specification.
    
    Args:
        _display: X11 display connection (optional, defaults to Xlib.display.Display())
        root: Root window object (optional, defaults to display.screen().root)
    """
    def __init__(self, _display=None, root=None): ...

Desktop and Workspace Information

Methods for querying and controlling desktop/workspace properties.

def getClientList(self):
    """
    Get list of windows maintained by the window manager.
    
    Returns:
        list: List of Window objects
    """

def getClientListStacking(self):
    """
    Get list of windows in bottom-to-top stacking order.
    
    Returns:
        list: List of Window objects in stacking order
    """

def getNumberOfDesktops(self):
    """
    Get number of virtual desktops.
    
    Returns:
        int: Number of desktops
    """

def getDesktopGeometry(self):
    """
    Get desktop geometry as width and height.
    
    Returns:
        list: [width, height] in pixels
    """

def getDesktopViewPort(self):
    """
    Get viewport positions for each desktop.
    
    Returns:
        list: List of [x, y] coordinates for each desktop viewport
    """

def getCurrentDesktop(self):
    """
    Get current desktop number (0-indexed).
    
    Returns:
        int: Current desktop index
    """

def getActiveWindow(self):
    """
    Get currently active window.
    
    Returns:
        Window or None: Active window object or None if no active window
    """

def getWorkArea(self):
    """
    Get work area geometry for each desktop.
    
    Returns:
        list: List of [x, y, width, height] for each desktop work area
    """

def getShowingDesktop(self):
    """
    Get desktop showing mode status.
    
    Returns:
        int: 1 if showing desktop mode active, 0 otherwise
    """

Desktop and Workspace Control

Methods for controlling desktop/workspace properties and state.

def setNumberOfDesktops(self, nb):
    """
    Set number of virtual desktops.
    
    Args:
        nb (int): Desired number of desktops
    """

def setDesktopGeometry(self, w, h):
    """
    Set desktop geometry.
    
    Args:
        w (int): Desktop width in pixels
        h (int): Desktop height in pixels
    """

def setDesktopViewport(self, w, h):
    """
    Set desktop viewport size.
    
    Args:
        w (int): Viewport width in pixels
        h (int): Viewport height in pixels
    """

def setCurrentDesktop(self, i):
    """
    Switch to specified desktop.
    
    Args:
        i (int): Desktop index (0-indexed)
    """

def setActiveWindow(self, win):
    """
    Set specified window as active.
    
    Args:
        win (Window): Window object to activate
    """

def setShowingDesktop(self, show):
    """
    Enable or disable desktop showing mode.
    
    Args:
        show (int): 1 to show desktop, 0 to hide
    """

Window Information

Methods for querying individual window properties.

def getWmName(self, win):
    """
    Get window name/title.
    
    Args:
        win (Window): Window object
        
    Returns:
        str: Window name
    """

def getWmVisibleName(self, win):
    """
    Get window visible name (may differ from WM_NAME).
    
    Args:
        win (Window): Window object
        
    Returns:
        str: Window visible name
    """

def getWmDesktop(self, win):
    """
    Get desktop number that window belongs to.
    
    Args:
        win (Window): Window object
        
    Returns:
        int: Desktop index (0-indexed)
    """

def getWmWindowType(self, win, str=False):
    """
    Get window type(s).
    
    Args:
        win (Window): Window object
        str (bool): If True, return string names instead of atom IDs
        
    Returns:
        list: List of window type atoms (int) or names (str)
    """

def getWmState(self, win, str=False):
    """
    Get window state(s).
    
    Args:
        win (Window): Window object
        str (bool): If True, return string names instead of atom IDs
        
    Returns:
        list: List of window state atoms (int) or names (str)
    """

def getWmAllowedActions(self, win, str=False):
    """
    Get allowed actions for window.
    
    Args:
        win (Window): Window object
        str (bool): If True, return string names instead of atom IDs
        
    Returns:
        list: List of allowed action atoms (int) or names (str)
    """

def getWmPid(self, win):
    """
    Get process ID of window's application.
    
    Args:
        win (Window): Window object
        
    Returns:
        int: Process ID
    """

Window Control

Methods for controlling individual window properties and actions.

def setCloseWindow(self, win):
    """
    Request window closure.
    
    Args:
        win (Window): Window object to close
    """

def setWmName(self, win, name):
    """
    Set window name/title.
    
    Args:
        win (Window): Window object
        name (str): New window name
    """

def setWmVisibleName(self, win, name):
    """
    Set window visible name.
    
    Args:
        win (Window): Window object
        name (str): New visible name
    """

def setWmDesktop(self, win, i):
    """
    Move window to specified desktop.
    
    Args:
        win (Window): Window object
        i (int): Target desktop index (0-indexed)
    """

def setMoveResizeWindow(self, win, gravity=0, x=None, y=None, w=None, h=None):
    """
    Move and/or resize window.
    
    Args:
        win (Window): Window object
        gravity (int): Gravity hint (Xlib.X.*Gravity constant or 0)
        x (int, optional): New X coordinate
        y (int, optional): New Y coordinate
        w (int, optional): New width
        h (int, optional): New height
    """

def setWmState(self, win, action, state, state2=0):
    """
    Set or unset window state(s).
    
    Args:
        win (Window): Window object
        action (int): 0=remove, 1=add, 2=toggle
        state (int or str): Window state atom ID or name
        state2 (int or str, optional): Second state atom ID or name
    """

Generic Property Access

Methods for accessing EWMH properties by name using generic interfaces.

def getReadableProperties(self):
    """
    Get list of all readable EWMH property names.
    
    Returns:
        list: Property names that can be used with getProperty()
    """

def getProperty(self, prop, *args, **kwargs):
    """
    Get EWMH property value by name.
    
    Args:
        prop (str): Property name (e.g., '_NET_ACTIVE_WINDOW')
        *args: Arguments passed to specific getter method
        **kwargs: Keyword arguments passed to specific getter method
        
    Returns:
        Property value (type depends on property)
        
    Raises:
        KeyError: If property name is not recognized
    """

def getWritableProperties(self):
    """
    Get list of all writable EWMH property names.
    
    Returns:
        list: Property names that can be used with setProperty()
    """

def setProperty(self, prop, *args, **kwargs):
    """
    Set EWMH property value by name.
    
    Args:
        prop (str): Property name (e.g., '_NET_ACTIVE_WINDOW')
        *args: Arguments passed to specific setter method  
        **kwargs: Keyword arguments passed to specific setter method
        
    Raises:
        KeyError: If property name is not recognized
    """

Constants

Window Types

NET_WM_WINDOW_TYPES = (
    '_NET_WM_WINDOW_TYPE_DESKTOP',
    '_NET_WM_WINDOW_TYPE_DOCK', 
    '_NET_WM_WINDOW_TYPE_TOOLBAR',
    '_NET_WM_WINDOW_TYPE_MENU',
    '_NET_WM_WINDOW_TYPE_UTILITY',
    '_NET_WM_WINDOW_TYPE_SPLASH',
    '_NET_WM_WINDOW_TYPE_DIALOG',
    '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU',
    '_NET_WM_WINDOW_TYPE_POPUP_MENU',
    '_NET_WM_WINDOW_TYPE_NOTIFICATION',
    '_NET_WM_WINDOW_TYPE_COMBO',
    '_NET_WM_WINDOW_TYPE_DND',
    '_NET_WM_WINDOW_TYPE_NORMAL'
)

Window Actions

NET_WM_ACTIONS = (
    '_NET_WM_ACTION_MOVE',
    '_NET_WM_ACTION_RESIZE',
    '_NET_WM_ACTION_MINIMIZE',
    '_NET_WM_ACTION_SHADE',
    '_NET_WM_ACTION_STICK',
    '_NET_WM_ACTION_MAXIMIZE_HORZ',
    '_NET_WM_ACTION_MAXIMIZE_VERT',
    '_NET_WM_ACTION_FULLSCREEN',
    '_NET_WM_ACTION_CHANGE_DESKTOP',
    '_NET_WM_ACTION_CLOSE',
    '_NET_WM_ACTION_ABOVE',
    '_NET_WM_ACTION_BELOW'
)

Window States

NET_WM_STATES = (
    '_NET_WM_STATE_MODAL',
    '_NET_WM_STATE_STICKY',
    '_NET_WM_STATE_MAXIMIZED_VERT',
    '_NET_WM_STATE_MAXIMIZED_HORZ',
    '_NET_WM_STATE_SHADED',
    '_NET_WM_STATE_SKIP_TASKBAR',
    '_NET_WM_STATE_SKIP_PAGER',
    '_NET_WM_STATE_HIDDEN',
    '_NET_WM_STATE_FULLSCREEN',
    '_NET_WM_STATE_ABOVE',
    '_NET_WM_STATE_BELOW',
    '_NET_WM_STATE_DEMANDS_ATTENTION'
)

Types

# Xlib types used by EWMH methods
from Xlib.display import Display
from Xlib import Window

Window = Window  # X11 window object from python-xlib
Display = Display  # X11 display connection object from python-xlib

Usage Notes

Flushing Changes

After calling setter methods, you must flush the display connection to ensure changes are sent to the window manager:

ewmh = EWMH()
ewmh.setActiveWindow(some_window)
ewmh.display.flush()  # Required to send the request

Error Handling

Methods may raise exceptions from the underlying Xlib operations. Common patterns:

  • Window objects may become invalid if windows are closed
  • Property access may return None for non-existent properties
  • Generic property methods raise KeyError for unknown property names

Display Management

Remember to close the display connection when done:

ewmh = EWMH()
# ... use ewmh methods ...
ewmh.display.close()

Or use context management patterns for automatic cleanup.