Where Is the Hyprland IPC Code? A Deep Dive into the EventManager Implementation

Hyprland's IPC implementation lives in src/managers/EventManager.cpp and src/managers/EventManager.hpp, where the CEventManager class creates a Unix domain socket (.socket2.sock) and broadcasts formatted events to connected clients.

The Hyprland IPC (Inter-Process Communication) system allows external tools, scripts, and plugins to react to compositor events in real-time. Unlike traditional request-response protocols, Hyprland uses a fire-and-forget event stream where the compositor pushes formatted strings to any client listening on its private Unix socket.

Core IPC Components

Hyprland's IPC architecture centers around three primary constructs defined in the EventManager headers.

SHyprIPCEvent

The SHyprIPCEvent struct is a simple data holder defined in src/managers/EventManager.hpp. It stores an event name and payload string that will be serialized and transmitted to all connected clients.

CEventManager

The CEventManager class handles the actual socket lifecycle. According to the Hyprland source code, this class manages Unix socket creation, accepts incoming client connections, maintains event queues, and flushes data to listeners. The implementation uses non-blocking I/O and integrates with the Wayland event loop.

g_pEventManager

A global shared pointer g_pEventManager provides singleton access to the event manager throughout the codebase. Window managers, monitor handlers, and workspace logic all invoke g_pEventManager->postEvent() to broadcast state changes.

How the Hyprland IPC Socket Works

The IPC mechanism follows a six-stage pipeline implemented in src/managers/EventManager.cpp:

  1. Socket creation – The constructor CEventManager::CEventManager() creates a Unix domain socket using socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) and binds it to g_pCompositor->m_instancePath + "/.socket2.sock".

  2. Accepting clients – When a client connects, the onServerEvent callback triggers, instantiating a new SClient entry and attaching a writable event source to the main Wayland event loop.

  3. Formatting events – The formatEvent method constructs lines following the pattern <event-name>>payload\n, replacing internal newlines with spaces and truncating payloads to 1024 bytes.

  4. Posting events – Subsystems call g_pEventManager->postEvent(event), which creates a shared std::string of the formatted line and pushes it onto each client's event queue, attempting an immediate write via flushClient.

  5. Queue handling – Each connected client maintains a limited queue of 64 entries. If the queue overflows, the client is disconnected to prevent memory pressure on the compositor.

  6. Client cleanup – Connection errors, hangs, or explicit socket closures trigger removal from the m_clients container.

IPC Event Format and Examples

Hyprland emits events as plain text lines with a specific delimiter structure. The standard format separates the event type from its payload using the >> sequence.

Common event types emitted by the compositor include:

  • workspace – Emitted when the active workspace changes (e.g., workspace>>2)
  • workspacev2 – Extended workspace event with name data (e.g., workspacev2>>2,2nd-Workspace)
  • openwindow – Fired when a new window opens (e.g., openwindow>>0x5600ab123456,2,Alacritty,Terminal)
  • activelayout – Keyboard layout changes (e.g., activelayout>>keyboard1,default)
  • screencast – Screen sharing status updates (e.g., screencast>>1,0)

These strings originate from calls such as:

g_pEventManager->postEvent(SHyprIPCEvent{
    .event = "workspace",
    .data  = PNEWWORKSPACE->m_name
});

Connecting to the Hyprland IPC Socket

You can interact with the IPC system from Bash scripts, the official hyprctl utility, or C++ plugins.

Reading Events from Bash

Use socat to connect to the Unix socket and parse events line-by-line:

#!/usr/bin/env bash
SOCK="$HOME/.hyprland/.socket2.sock"

while IFS= read -r line; do
    event=${line%%>>*}
    payload=${line#*>>}
    echo "Event: $event   Payload: $payload"
done < <(socat - UNIX-CONNECT:"$SOCK")

This script listens indefinitely, splitting each line on the >> delimiter to separate event types from data payloads.

Using hyprctl for Queries

The official client utility provides a higher-level interface:


# List all workspaces

hyprctl workspaces

# Get active window as JSON

hyprctl activewindow -j

Internally, hyprctl opens the same .socket2.sock and sends request strings, handling the response parsing automatically. The request logic resides in src/hyprctl/src/main.cpp within the requestIPC function.

Emitting Events from C++ Plugins

Plugin developers can inject custom events using the global manager:

#include "EventManager.hpp"

void sendMyEvent(const std::string& msg) {
    SHyprIPCEvent ev;
    ev.event = "custom";
    ev.data  = msg;  // Remember: 1024 byte limit
    g_pEventManager->postEvent(ev);
}

Any listening client receives custom>><msg> immediately after the call completes.

Key Source Files for Hyprland IPC

File Role
src/managers/EventManager.hpp Declares SHyprIPCEvent, CEventManager, and the global g_pEventManager pointer
src/managers/EventManager.cpp Implements socket setup, client lifecycle, and event broadcasting
src/desktop/view/Window.cpp Emits window-related events (openwindow, closewindow, activewindow)
src/output/Monitor.cpp Broadcasts monitor and workspace events (monitoradded, workspace)
src/hyprctl/src/main.cpp Client-side implementation for sending requests and parsing replies

Summary

  • Hyprland IPC is implemented through the CEventManager class in src/managers/EventManager.cpp.
  • The system uses a Unix domain socket at .socket2.sock with a fire-and-forget event model.
  • Events follow the format eventname>>payload\n with a 1024-byte payload limit.
  • Client queues are capped at 64 entries to prevent resource exhaustion.
  • The global g_pEventManager pointer allows any subsystem to broadcast events via postEvent().

Frequently Asked Questions

Where is the Hyprland IPC socket located?

The socket file is created at runtime within the compositor's instance directory, specifically at $HYPR_INSTANCE_PATH/.socket2.sock or typically ~/.hyprland/.socket2.sock. This path is generated dynamically in CEventManager::CEventManager() to support multiple concurrent compositor instances.

What is the maximum payload size for Hyprland IPC events?

The compositor truncates all event payloads to 1024 bytes in the formatEvent function. Newline characters within the payload are replaced with spaces before transmission, ensuring single-line event delivery.

How does Hyprland handle slow or unresponsive IPC clients?

Each client connection maintains a queue of 64 events. If a client's buffer overflows because it cannot read fast enough, CEventManager disconnects the client automatically to protect the compositor's performance.

Can I send commands to Hyprland through the IPC socket?

While the .socket2.sock socket is read-only for event streaming, the hyprctl utility communicates with a separate command socket (typically .socket.sock) to send instructions to the compositor. The command handling logic resides in src/hyprctl/src/main.cpp, distinct from the event broadcasting system in EventManager.cpp.

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 →