Skip to content

Architecture Overview

This document provides a high-level overview of Pyprland's architecture, data flow, and design patterns.

TIP

For a practical guide to writing plugins, see the Development document.

Executive Summary

Pyprland is a plugin-based companion application for tiling window managers (Hyprland, Niri). It operates as a daemon that extends the window manager's capabilities through a modular plugin system, communicating via Unix domain sockets (IPC).

AttributeValue
LanguagePython 3.11+
LicenseMIT
ArchitectureDaemon/Client, Plugin-based
Async Frameworkasyncio

High-Level Architecture

Data Flow

Event Processing

When the window manager emits an event (window opened, workspace changed, etc.):

Command Processing

When the user runs pypr <command>:

Directory Structure

All source files are in the pyprland/ directory:

pyprland/
├── command.py           # CLI entry point, argument parsing
├── pypr_daemon.py       # Daemon startup logic
├── manager.py           # Core Pyprland class (orchestrator)
├── client.py            # Client mode implementation
├── ipc.py               # Socket communication with WM
├── config.py            # Configuration wrapper
├── validation.py        # Config validation framework
├── common.py            # Shared utilities, SharedState, logging
├── constants.py         # Global constants
├── models.py            # TypedDict definitions
├── version.py           # Version string
├── aioops.py            # Async file ops, DebouncedTask
├── completions.py       # Shell completion generators
├── help.py              # Help system
├── ansi.py              # Terminal colors/styling
├── debug.py             # Debug utilities

├── adapters/            # Window manager abstraction
│   ├── backend.py       # Abstract EnvironmentBackend
│   ├── hyprland.py      # Hyprland implementation
│   ├── niri.py          # Niri implementation
│   ├── menus.py         # Menu engine abstraction (rofi, wofi, etc.)
│   └── units.py         # Unit conversion utilities

└── plugins/             # Plugin implementations
    ├── interface.py     # Plugin base class
    ├── protocols.py     # Event handler protocols

    ├── pyprland/        # Core internal plugin
    ├── scratchpads/     # Scratchpad plugin (complex, multi-file)
    ├── monitors/        # Monitor management
    ├── wallpapers/      # Wallpaper management

    └── *.py             # Simple single-file plugins

Design Patterns

PatternUsage
Plugin ArchitectureExtensibility via Plugin base class
Adapter PatternEnvironmentBackend abstracts WM differences
Strategy PatternMenu engines in menus.py (rofi, wofi, tofi, etc.)
Observer PatternEvent handlers subscribe to WM events
Async Task QueuesPer-plugin isolation, prevents blocking
Decorator Pattern@retry_on_reset in ipc.py, @remove_duplicate in manager.py
Template MethodPlugin lifecycle hooks (init, on_reload, exit)