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

> Discover where Hyprland's IPC code resides! Explore the EventManager implementation in EventManager cpp and hpp files, and understand how it manages client communication via Unix domain sockets.

- Repository: [Hypr Development/Hyprland](https://github.com/hyprwm/Hyprland)
- Tags: deep-dive
- Published: 2026-07-23

---

**Hyprland's IPC implementation lives in [`src/managers/EventManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/EventManager.cpp) and [`src/managers/EventManager.hpp`](https://github.com/hyprwm/Hyprland/blob/main/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`](https://github.com/hyprwm/Hyprland/blob/main/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`](https://github.com/hyprwm/Hyprland/blob/main/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:

```cpp
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:

```bash
#!/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:

```bash

# 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`](https://github.com/hyprwm/Hyprland/blob/main/src/hyprctl/src/main.cpp) within the `requestIPC` function.

### Emitting Events from C++ Plugins

Plugin developers can inject custom events using the global manager:

```cpp
#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`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/EventManager.hpp) | Declares `SHyprIPCEvent`, `CEventManager`, and the global `g_pEventManager` pointer |
| [`src/managers/EventManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/EventManager.cpp) | Implements socket setup, client lifecycle, and event broadcasting |
| [`src/desktop/view/Window.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.cpp) | Emits window-related events (`openwindow`, `closewindow`, `activewindow`) |
| [`src/output/Monitor.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/output/Monitor.cpp) | Broadcasts monitor and workspace events (`monitoradded`, `workspace`) |
| [`src/hyprctl/src/main.cpp`](https://github.com/hyprwm/Hyprland/blob/main/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`](https://github.com/hyprwm/Hyprland/blob/main/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`](https://github.com/hyprwm/Hyprland/blob/main/src/hyprctl/src/main.cpp), distinct from the event broadcasting system in [`EventManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/EventManager.cpp).