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:
-
Socket creation – The constructor
CEventManager::CEventManager()creates a Unix domain socket usingsocket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)and binds it tog_pCompositor->m_instancePath + "/.socket2.sock". -
Accepting clients – When a client connects, the
onServerEventcallback triggers, instantiating a newSCliententry and attaching a writable event source to the main Wayland event loop. -
Formatting events – The
formatEventmethod constructs lines following the pattern<event-name>>payload\n, replacing internal newlines with spaces and truncating payloads to 1024 bytes. -
Posting events – Subsystems call
g_pEventManager->postEvent(event), which creates a sharedstd::stringof the formatted line and pushes it onto each client's event queue, attempting an immediate write viaflushClient. -
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.
-
Client cleanup – Connection errors, hangs, or explicit socket closures trigger removal from the
m_clientscontainer.
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
CEventManagerclass insrc/managers/EventManager.cpp. - The system uses a Unix domain socket at
.socket2.sockwith a fire-and-forget event model. - Events follow the format
eventname>>payload\nwith a 1024-byte payload limit. - Client queues are capped at 64 entries to prevent resource exhaustion.
- The global
g_pEventManagerpointer allows any subsystem to broadcast events viapostEvent().
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →