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)