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
- Client binds the global. When a client connects to the
hyprland_session_lock_v1global, the compositor creates aCExtSessionLockManagerV1object. - Client requests a lock. The manager’s
onLock()callback spawns aCSessionLock, setsm_locked = true, and emitsCSessionLockProtocol::m_events.newLock. - Lock surface creation. The client calls
getLockSurface(); the protocol responds by creating aCSessionLockSurfacetied to a specific monitor output and issuing a configure event with the monitor’s size. - Compositor notifies lock.
CSessionLock::sendLocked()dispatches the Waylandlockedevent to the client and callsCLockNotifyProtocol::onLocked(). Listeners such as plugins or the built-in lock UI receive the state throughCSessionLockManager::m_events.lock. - Unlock and cleanup. When the client calls
unlock_and_destroy, the protocol clearsm_locked, invokesCLockNotifyProtocol::onUnlocked(), destroys the lock objects, and emits the manager’sunlocksignal.
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, ®istry_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
src/managers/SessionLockManager.hpp– DeclaresCSessionLockManager, its public API, and the internalSSessionLockstructure.src/protocols/SessionLock.cpp– Implements the Wayland session-lock protocol, lock surface handling, and lock/unlock logic.src/protocols/LockNotify.cpp– Broadcasts lock state changes to other compositor components.src/desktop/view/SessionLock.hpp– Declares the default lock-screen UI view.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
CSessionLockManagerfor high-level state tracking andCSessionLockProtocolfor Wayland protocol compliance. - The lock flow creates a
CSessionLock, spawns oneCSessionLockSurfaceper monitor, and broadcasts changes throughCLockNotifyProtocol. - You can lock the session instantly with
hyprctl dispatcher lock, which callsCSessionLockProtocol::forceLock(). - Custom clients bind to the
hyprland_session_lock_v1global and callgetLockSurface()to draw a lock UI. - Plugins and internal views react to
g_pSessionLockManager->m_events.lockandm_events.unlockto 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →