Hyprland Session Lock Manager Usage: Protocol Architecture and Examples

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. 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. 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). 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, 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.


# 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.

// 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.

// '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.

#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

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, which declares CSessionLockManager. The corresponding Wayland protocol logic lives in 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, 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 demonstrates how to consume these events and render content on lock surfaces.

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 →