CWindow Data Structure: How Hyprland Represents Windows

The CWindow class serves as the central data structure for representing windows in Hyprland, encapsulating all state for both Wayland and X11 surfaces while providing the primary interface for layout, rendering, and input handling.

In the Hyprland compositor, every top-level surface—from standard XDG toplevels to legacy X11 windows—requires a unified representation. The data structure for representing windows in Hyprland is the CWindow class, defined in src/desktop/view/Window.hpp. This design abstracts underlying protocol differences into a first-class object that the compositor can query, animate, and move between workspaces.

CWindow Architecture and Inheritance

The CWindow class implements multiple interfaces to support Hyprland's feature set. According to the source code in src/desktop/view/Window.hpp (lines 16–27), it inherits from:

  • IView – the core view interface for surface handling
  • CGeometricMovableAnimated – for geometric animations and position interpolation
  • IAlphaModifiable – for per-window opacity control

This inheritance allows CWindow to function as both a data container and an active participant in the compositor's animation and rendering systems.

Core Window State and Member Variables

CWindow aggregates all per-window state needed for the compositor's operation. Key member variables declared in src/desktop/view/Window.hpp (lines 45–89) include:

  • m_xdgSurface and m_xwaylandSurface – weak pointers to the underlying Wayland or X11 protocol resources
  • m_target – a strong pointer to the window's layout target (CWindowTarget)
  • m_self – a self-referential handle used throughout the compositor for safe callback registration
  • m_group – group membership data for window grouping features
  • m_windowDecorations – collection of active decorations (borders, shadows, etc.)
  • m_title and m_class – application metadata strings
  • m_isFloating – boolean state for floating vs. tiled layout

Window Creation and Lifecycle

Windows are instantiated through static factory methods rather than direct construction. The CWindow class provides two primary creation paths in src/desktop/view/Window.hpp:

// Create from a Wayland XDG surface
static PHLWINDOW create(SP<CXDGSurfaceResource> resource);

// Create from an XWayland surface
static PHLWINDOW create(SP<CXWaylandSurface> resource);

These methods return a PHLWINDOW, which is a type alias for SP<CWindow> (strong pointer). This handle type appears throughout the codebase whenever the compositor references windows.

Interacting with CWindow Objects

Once created, CWindow provides the public API for window manipulation. As implemented in src/desktop/view/Window.hpp (lines 133–180), key methods include moveToWorkspace, activate, getPID, and geometry helpers like layoutBox() and getFullWindowBoundingBox().

Basic Property Access

// Create a window from a Wayland XDG surface
PHLWINDOW myWin = Desktop::View::CWindow::create(xdgSurface);

// Query basic properties
std::string title    = myWin->m_title;          // window title
std::string appClass = myWin->m_class;          // application class
bool        floating = myWin->m_isFloating;     // floating state

Workspace and Focus Operations

// Move the window to workspace 3
myWin->moveToWorkspace(workspaceByID(3));

// Activate (focus) the window
myWin->activate(/*force=*/false);

// Change the window's alpha for the "active" state
myWin->alpha(Desktop::View::eWindowAlpha::WINDOW_ALPHA_ACTIVE) = 0.85f;

Iterating All Windows

The global window controller maintains a registry of all windows. In src/desktop/state/GlobalWindowController.hpp, windows are stored in g_pGlobalState->m_vWindows:

// Iterate all mapped windows using the global controller
for (const auto& winRef : g_pGlobalState->m_vWindows) {
    if (!Desktop::View::validMapped(winRef))
        continue;
    const auto& win = winRef.lock();
    std::cout << "Window [" << win->m_title << "] on monitor "
              << win->monitorID() << "\n";
}

Key Source Files for Window Management

Understanding the window data structure requires familiarity with several interconnected files:

Summary

  • CWindow is the primary data structure for representing windows in Hyprland, defined in src/desktop/view/Window.hpp.
  • It implements IView, CGeometricMovableAnimated, and IAlphaModifiable to support rendering, animation, and opacity control.
  • Windows are created via static factories CWindow::create() returning PHLWINDOW handles, supporting both XDG and XWayland surfaces.
  • The class stores weak pointers to protocol resources (m_xdgSurface, m_xwaylandSurface) and a strong pointer to layout targets (m_target).
  • All windows are tracked globally in g_pGlobalState->m_vWindows via the GlobalWindowController.

Frequently Asked Questions

What is the primary window data structure in Hyprland?

The primary data structure is the CWindow class declared in src/desktop/view/Window.hpp. It encapsulates all window state including geometry, decorations, group membership, and surface references, serving as the unified representation for both Wayland and X11 windows.

How does Hyprland handle both Wayland and X11 windows in the same structure?

CWindow stores weak pointers to both m_xdgSurface (Wayland) and m_xwaylandSurface (X11) but exposes a common interface through the IView inheritance. The static factory methods create(SP<CXDGSurfaceResource>) and create(SP<CXWaylandSurface>) return the same PHLWINDOW type, allowing the compositor to treat both protocols identically after creation.

Where are windows stored and managed in the codebase?

All windows are stored in the GlobalWindowController, accessible via g_pGlobalState->m_vWindows as defined in src/desktop/state/GlobalWindowController.hpp. This registry maintains strong references to all window objects and provides iteration and lookup capabilities used by layouts and input handlers.

How can I access window properties programmatically in Hyprland?

Window properties are accessible through public member variables of CWindow such as m_title, m_class, and m_isFloating, or through methods like getPID(), monitorID(), and layoutBox(). For iteration, use the global window list with validMapped() checks to ensure the window is still active and mapped.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →