penrose

repository·develop·Indexed 23 days ago

https://github.com/sminez/penrose

A modular Rust library for building custom X11 tiling window managers, inspired by dwm and xmonad. It separates pure state management from X server rendering and provides a core event loop. The ecosystem includes companion crates such as penrose_keysyms for type-safe X11 keysyms, penrose_ui for minimal GUI elements and status bars, and penrose_menu for user input interfaces.

Tokens
27.6K
Snippets
49
Records
155
Agent score
80%

What's inside penrose

  1. Overview of Penrose UI

    develop

    The penrose_ui crate provides minimal GUI elements designed specifically for the Penrose window manager library. It acts as a thin wrapper over xlib and fontconfig to support text-based user interfaces.

    Note: While it may be possible to use this crate for standalone UIs, its primary and supported use case is direct integration within the Penrose window manager ecosystem.

  2. Use X11 Keysyms with Penrose via penrose_keysyms

    develop
    The penrose_keysyms crate provides an enum representing X11 keysyms specifically designed for use within the penrose tiling window manager library. This allows developers to use type-safe, named constants for key bindings instead of raw integer values when configuring window manager behaviors.
  3. Control layouts using Messages

    develop

    You can modify the behavior of active layouts by sending Messages. Built-in messages for the standard layouts include:

    Layout Modification Messages

    • IncMain, ExpandMain, and ShrinkMain: Used with MainAndStack (and similar layouts) to adjust the size or number of windows in the primary area.
    • Rotate: Used with CenteredMain or layouts with rotational symmetry to switch the position of secondary areas (e.g., from sides to top/bottom).
    • Mirror: Used to reflect the layout's symmetry.
    • UnwrapTransformer: A message tied to the LayoutTransformer trait used to remove a specific transformer from the underlying layout.
  4. What are Actions in Penrose

    develop
    In Penrose, an action is custom code executed in response to a key binding. Actions allow you to extend the window manager's behavior, such as focusing windows, changing layouts, spawning programs (like terminals), or executing arbitrary logic. Actions are implemented as KeyEventHandlers.
  5. Understand the StackSet data structure

    develop

    The StackSet is the top-level container that manages the entire state of the window manager. It is conceptually a "Stack of Stacks" using a zipper-like pattern to manage visibility and focus.

    It manages four main components:

    1. Windows: Managed via Stacks.
    2. Workspaces: Assigned to screens or kept hidden.
    3. Screens: The visible areas, managed via a Stack<Screen>.
    4. Hidden Workspaces: Workspaces not currently assigned to a screen, stored in a LinkedList<Workspace>.

    The StackSet maintains the currently focused screen (where X input focus lies) and allows you to manipulate groups of windows based on their workspace or move workspaces between screens.

    struct StackSet {
        screens: Stack<Screen>,
        hidden: LinkedList<Workspace>,
        // and other book-keeping fields...
    }
  6. Use Refresh Hooks to respond to state changes

    develop

    Refresh hooks are implementations of the StateHook trait that execute at the end of the modify_and_refresh method in the XConnExt trait. They run every time the window manager's internal state is refreshed and rendered to the X server.

    This is a general-purpose hook used to run code whenever something changes in the window manager's state. A common use case is updating a status bar by logging the internal state (similar to Xmonad's "Log Hook").

  7. Extend Penrose functionality using Hooks and State Extensions

    develop

    Penrose provides two primary ways to add custom functionality to your window manager:

    1. Traits and Helper Functions: For common use cases, Penrose provides high-level traits and helpers (documented in the builtin section). These are designed to handle most standard window manager tasks with minimal boilerplate.
    2. Lower-level APIs: For highly custom behavior that doesn't fit standard patterns, you should use the Hook and State Extension APIs. These allow you to intercept window manager events or augment the internal state of the manager.
  8. Understand the core architecture of Penrose

    develop

    Penrose is designed as a modular library for building custom X11 window managers in Rust. The core functionality focuses on two primary responsibilities:

    1. State Management: Handling the internal representation of windows, workspaces, and layouts.
    2. X Server Interaction: Managing the low-level communication with the X11 server.

    While the library provides a minimal amount of out-of-the-box functionality, it is intended to be extended using various types and traits provided by the library to implement custom window management behavior.

  9. Understand the Screen and Rect data structures

    develop

    A Screen represents a physical display area. It pairs a Workspace with an ID and a Rect to define its dimensions and position.

    • Screens: Workspaces can be moved between screens, and clients can be moved between workspaces.
    • Rect (Rectangles): Both screens and windows are described using Rect. A Rect consists of (x, y) coordinates for the top-left corner, plus width and height. Use the Rect struct methods for slicing, dicing, positioning, and comparing areas when writing custom Layout algorithms.
  10. Apply LayoutTransformers to windows

    develop

    Penrose uses LayoutTransformers to modify how a layout positions windows, allowing for visual adjustments like spacing or reserving screen real estate. Common built-in transformers include:

    • ReflectHorizontal and ReflectVertical: Mirror the layout horizontally or vertically.
    • ReserveTop: Reserves space at the top of the screen, typically used to prevent windows from overlapping a status bar.
    • Gaps: Adds space between windows to prevent them from touching.
  11. What are ManageHooks and how to use them

    develop

    The ManageHook trait allows you to modify how a window is initially handled when it is first added to the window manager state. This is useful for automating window placement, such as moving a client to a specific workspace, positioning it in a stack, or marking it as floating at a specific screen position.

    Because the hook is called after the window has been added to the internal state, you have access to the full Penrose API to perform these modifications.

  12. Verify Penrose backend support

    develop
    Penrose currently supports X11 as a backend. It does not support Wayland. The internal APIs are designed around managing window positioning and workspaces within the X11 ecosystem. While Wayland support is a potential future interest, it is not currently a priority or supported.