# Hyprland Session Lock Manager Usage: Protocol Architecture and Examples

> Learn to use Hyprland's session lock manager protocol. Discover how to lock sessions, manage per-monitor surfaces, and handle lock/unlock notifications with clear examples.

- Repository: [Hypr Development/Hyprland](https://github.com/hyprwm/Hyprland)
- Tags: how-to-guide
- Published: 2026-07-27

---

**Hyprland's session lock manager exposes a Wayland protocol through `CSessionLockProtocol` and `CSessionLockManager` that lets clients lock the session, spawn per-monitor lock surfaces, and receive lock or unlock notifications via dedicated signals.**

Hyprland session lock manager usage spans CLI dispatchers, custom Wayland clients, and internal plugins in the `hyprwm/Hyprland` repository. The implementation centers on a small set of C++ classes that track lock state, negotiate surfaces per monitor, and broadcast events to compositor components.

## Core Architecture

### CSessionLockManager

The high-level coordinator lives in [`src/managers/SessionLockManager.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/SessionLockManager.hpp). It stores the active session through an `SSessionLock` instance named `m_sessionLock` and exposes helpers such as `isSessionLocked()`, `forceLock()`, `forceUnlock()`, and `onLockscreenRenderedOnMonitor()`. The manager also emits its own `m_events.lock` and `m_events.unlock` signals that other components— including the default lock-screen view—can subscribe to.

### CSessionLockProtocol and CSessionLock

The Wayland protocol implementation resides in [`src/protocols/SessionLock.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/SessionLock.cpp). When a client requests a lock, the protocol’s `onLock()` handler instantiates a `CSessionLock` object, marks `m_locked = true`, and triggers the `m_events.newLock` event. Each `CSessionLock` instance (lines 46–61 in the same file) sends `locked` and `finished` events back to the client, forwards unlock requests, and toggles an inert state via `m_inert`.

### CSessionLockSurface

For every monitor that should display a lock UI, the protocol creates a `CSessionLockSurface` (lines 11–70 of [`src/protocols/SessionLock.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/SessionLock.cpp)). This object listens to surface commits, watches for mode changes on its bound output, and sends configure events carrying the monitor’s current geometry.

### CLockNotifyProtocol

`CLockNotifyProtocol`, implemented in [`src/protocols/LockNotify.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/LockNotify.cpp), acts as a lightweight broadcaster. It is invoked from `CSessionLock::sendLocked()`, `CSessionLockProtocol::forceLock()`, and `CSessionLockProtocol::forceUnlock()` so that unrelated compositor modules can react to lock state transitions without directly linking against the session lock protocol.

## How the Session Lock Flow Works

1. **Client binds the global.** When a client connects to the `hyprland_session_lock_v1` global, the compositor creates a `CExtSessionLockManagerV1` object.
2. **Client requests a lock.** The manager’s `onLock()` callback spawns a `CSessionLock`, sets `m_locked = true`, and emits `CSessionLockProtocol::m_events.newLock`.
3. **Lock surface creation.** The client calls `getLockSurface()`; the protocol responds by creating a `CSessionLockSurface` tied to a specific monitor output and issuing a configure event with the monitor’s size.
4. **Compositor notifies lock.** `CSessionLock::sendLocked()` dispatches the Wayland `locked` event to the client and calls `CLockNotifyProtocol::onLocked()`. Listeners such as plugins or the built-in lock UI receive the state through `CSessionLockManager::m_events.lock`.
5. **Unlock and cleanup.** When the client calls `unlock_and_destroy`, the protocol clears `m_locked`, invokes `CLockNotifyProtocol::onUnlocked()`, destroys the lock objects, and emits the manager’s `unlock` signal.

## Practical Hyprland Session Lock Manager Usage Examples

### Locking the Session via hyprctl

You can force a lock immediately from a terminal or script without writing a custom client.

```bash

# Optional: disable animations for a snappier lock

hyprctl keyword disableanimations on

# Trigger the lock dispatcher

hyprctl dispatcher lock

```

The `lock` dispatcher ultimately reaches `CSessionLockProtocol::forceLock()`, which sets `m_locked = true` and notifies every registered listener.

### Creating a Custom Wayland Lock Client

A minimal C++ client binds to the `hyprland_session_lock_v1` global and requests a lock.

```cpp
// Bind to the Hyprland session-lock global
wl_registry *reg = wl_display_get_registry(display);
wl_registry_add_listener(reg, &registry_listener, nullptr);

// Inside registryListener, bind the lock global
auto *sessionLockMgr = wl_registry_bind(
    reg,
    lockGlobalId,
    &hyprland_session_lock_manager_interface,
    1
);

// Request the session lock
hyprland_session_lock_manager_v1_lock(sessionLockMgr, 0);

```

After the compositor acknowledges the lock, create a surface on the target monitor.

```cpp
// 'lock' is the CSessionLock object returned by the protocol
wl_output *output = /* target monitor */;
hyprland_session_lock_v1_get_lock_surface(lock, &surface, 1, output);

```

This flow mirrors the internal logic in `CSessionLockProtocol::onLock()` (lines 85–100) and `CSessionLockProtocol::onGetLockSurface()` (lines 203–236). The client should expect `locked` and later `unlock` events.

### Receiving Lock Events in a Hyprland Plugin

Plugins can observe state changes by connecting to the manager’s signals.

```cpp
#include <hyprutils/signal/Signal.hpp>

extern UP<CSessionLockManager> g_pSessionLockManager;

void onLock() {
    showLockScreen();
}

void onUnlock() {
    hideLockScreen();
}

int main() {
    g_pSessionLockManager->m_events.lock.listen([](auto) { onLock(); });
    g_pSessionLockManager->m_events.unlock.listen([](auto) { onUnlock(); });
    return 0;
}

```

The manager’s `lock` and `unlock` signals are emitted whenever the protocol processes a state change, specifically inside `CSessionLockProtocol::forceLock()` and `CSessionLockProtocol::forceUnlock()` (lines 52–60 and 42–50).

## Key Source Files

- [`src/managers/SessionLockManager.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/SessionLockManager.hpp) – Declares `CSessionLockManager`, its public API, and the internal `SSessionLock` structure.
- [`src/protocols/SessionLock.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/SessionLock.cpp) – Implements the Wayland session-lock protocol, lock surface handling, and lock/unlock logic.
- [`src/protocols/LockNotify.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/LockNotify.cpp) – Broadcasts lock state changes to other compositor components.
- [`src/desktop/view/SessionLock.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/SessionLock.hpp) – Declares the default lock-screen UI view.
- [`src/desktop/view/SessionLock.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/SessionLock.cpp) – Renders the built-in lock screen by consuming the manager’s events.

## Summary

- **Hyprland session lock manager usage** centers on `CSessionLockManager` for high-level state tracking and `CSessionLockProtocol` for Wayland protocol compliance.
- The lock flow creates a `CSessionLock`, spawns one `CSessionLockSurface` per monitor, and broadcasts changes through `CLockNotifyProtocol`.
- You can lock the session instantly with `hyprctl dispatcher lock`, which calls `CSessionLockProtocol::forceLock()`.
- Custom clients bind to the `hyprland_session_lock_v1` global and call `getLockSurface()` to draw a lock UI.
- Plugins and internal views react to `g_pSessionLockManager->m_events.lock` and `m_events.unlock` to show or hide lock-screen content.

## Frequently Asked Questions

### What is the entry point for Hyprland session lock manager usage in the source code?

The primary entry point is [`src/managers/SessionLockManager.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/SessionLockManager.hpp), which declares `CSessionLockManager`. The corresponding Wayland protocol logic lives in [`src/protocols/SessionLock.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/SessionLock.cpp), where `CSessionLockProtocol` handles client requests and `CSessionLockSurface` manages per-monitor surfaces.

### How can I force a session lock without a dedicated lock client?

Run `hyprctl dispatcher lock` from any terminal. This command invokes `CSessionLockProtocol::forceLock()`, sets the compositor’s internal `m_locked` flag to `true`, and notifies all registered listeners.

### Which component notifies other parts of the compositor when a lock occurs?

`CLockNotifyProtocol`, defined in [`src/protocols/LockNotify.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/LockNotify.cpp), broadcasts lock state changes. It is triggered by `CSessionLock::sendLocked()` as well as by `CSessionLockProtocol::forceLock()` and `CSessionLockProtocol::forceUnlock()`.

### Can a Hyprland plugin render UI when the session locks?

Yes. Plugins can connect to `g_pSessionLockManager->m_events.lock` and `m_events.unlock`. The default lock-screen implementation in [`src/desktop/view/SessionLock.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/SessionLock.cpp) demonstrates how to consume these events and render content on lock surfaces.