protocols: add hyprland_lock_notify_v1 implementation (#9092)

This commit is contained in:
Maximilian Seidler 2025-01-19 18:21:36 +00:00 committed by GitHub
parent 8dd2cd41fb
commit 407453166c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 154 additions and 7 deletions

View file

@ -298,7 +298,7 @@ endfunction()
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0)
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.0)
if(hyprland_protocols_dep_FOUND)
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
@ -329,6 +329,7 @@ protocolnew("protocols" "frog-color-management-v1" true)
protocolnew("protocols" "wayland-drm" true)
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true)
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-surface-v1" true)
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-lock-notify-v1" true)
protocolnew("staging/tearing-control" "tearing-control-v1" false)
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)

View file

@ -128,11 +128,11 @@
]
},
"locked": {
"lastModified": 1735774328,
"narHash": "sha256-vIRwLS9w+N99EU1aJ+XNOU6mJTxrUBa31i1r82l0V7s=",
"lastModified": 1737127640,
"narHash": "sha256-mIQ3/axCZ4g8ySwWRbW4fJcyC9v55uAii3cqlJRtW8g=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "e3b6af97ddcfaafbda8e2828c719a5af84f662cb",
"rev": "455c055883d9639d4fcbfcedb4c6d12ce313791e",
"type": "github"
},
"original": {

View file

@ -7,7 +7,7 @@ wayland_protos = dependency(
hyprland_protos = dependency(
'hyprland-protocols',
version: '>=0.4',
version: '>=0.6',
fallback: 'hyprland-protocols',
)
@ -40,6 +40,7 @@ protocols = [
hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml',
hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml',
hyprland_protocol_dir / 'protocols/hyprland-surface-v1.xml',
hyprland_protocol_dir / 'protocols/hyprland-lock-notify-v1.xml',
wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml',
wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',

View file

@ -20,6 +20,7 @@
#include "../protocols/OutputPower.hpp"
#include "../protocols/XDGActivation.hpp"
#include "../protocols/IdleNotify.hpp"
#include "../protocols/LockNotify.hpp"
#include "../protocols/SessionLock.hpp"
#include "../protocols/InputMethodV2.hpp"
#include "../protocols/VirtualKeyboard.hpp"
@ -145,6 +146,7 @@ CProtocolManager::CProtocolManager() {
PROTO::outputPower = std::make_unique<COutputPowerProtocol>(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
PROTO::activation = std::make_unique<CXDGActivationProtocol>(&xdg_activation_v1_interface, 1, "XDGActivation");
PROTO::idle = std::make_unique<CIdleNotifyProtocol>(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
PROTO::lockNotify = std::make_unique<CLockNotifyProtocol>(&hyprland_lock_notifier_v1_interface, 1, "IdleNotify");
PROTO::sessionLock = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
PROTO::ime = std::make_unique<CInputMethodV2Protocol>(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
PROTO::virtualKeyboard = std::make_unique<CVirtualKeyboardProtocol>(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
@ -224,6 +226,7 @@ CProtocolManager::~CProtocolManager() {
PROTO::outputPower.reset();
PROTO::activation.reset();
PROTO::idle.reset();
PROTO::lockNotify.reset();
PROTO::sessionLock.reset();
PROTO::ime.reset();
PROTO::virtualKeyboard.reset();
@ -296,7 +299,7 @@ bool CProtocolManager::isGlobalPrivileged(const wl_global* global) {
PROTO::xdgDialog->getGlobal(),
PROTO::singlePixel->getGlobal(),
PROTO::primarySelection->getGlobal(),
PROTO::hyprlandSurface->getGlobal(),
PROTO::hyprlandSurface->getGlobal(),
PROTO::sync ? PROTO::sync->getGlobal() : nullptr,
PROTO::mesaDRM ? PROTO::mesaDRM->getGlobal() : nullptr,
PROTO::linuxDma ? PROTO::linuxDma->getGlobal() : nullptr,

View file

@ -0,0 +1,88 @@
#include "LockNotify.hpp"
CHyprlandLockNotification::CHyprlandLockNotification(SP<CHyprlandLockNotificationV1> resource_) : m_resource(resource_) {
if UNLIKELY (!m_resource->resource())
return;
m_resource->setDestroy([this](CHyprlandLockNotificationV1* r) { PROTO::lockNotify->destroyNotification(this); });
m_resource->setOnDestroy([this](CHyprlandLockNotificationV1* r) { PROTO::lockNotify->destroyNotification(this); });
}
bool CHyprlandLockNotification::good() {
return m_resource->resource();
}
void CHyprlandLockNotification::onLocked() {
if LIKELY (!m_locked)
m_resource->sendLocked();
m_locked = true;
}
void CHyprlandLockNotification::onUnlocked() {
if LIKELY (m_locked)
m_resource->sendUnlocked();
m_locked = false;
}
CLockNotifyProtocol::CLockNotifyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
;
}
void CLockNotifyProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_managers.emplace_back(std::make_unique<CHyprlandLockNotifierV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CHyprlandLockNotifierV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CHyprlandLockNotifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
RESOURCE->setGetLockNotification([this](CHyprlandLockNotifierV1* pMgr, uint32_t id) { this->onGetNotification(pMgr, id); });
}
void CLockNotifyProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CLockNotifyProtocol::destroyNotification(CHyprlandLockNotification* notif) {
std::erase_if(m_notifications, [&](const auto& other) { return other.get() == notif; });
}
void CLockNotifyProtocol::onGetNotification(CHyprlandLockNotifierV1* pMgr, uint32_t id) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_notifications.emplace_back(makeShared<CHyprlandLockNotification>(makeShared<CHyprlandLockNotificationV1>(CLIENT, pMgr->version(), id))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_notifications.pop_back();
return;
}
// Already locked?? Send locked right away
if UNLIKELY (m_isLocked)
m_notifications.back()->onLocked();
}
void CLockNotifyProtocol::onLocked() {
if UNLIKELY (m_isLocked) {
LOGM(ERR, "Not sending lock notification. Already locked!");
return;
}
for (auto const& n : m_notifications) {
n->onLocked();
}
m_isLocked = true;
}
void CLockNotifyProtocol::onUnlocked() {
if UNLIKELY (!m_isLocked) {
LOGM(ERR, "Not sending unlock notification. Not locked!");
return;
}
for (auto const& n : m_notifications) {
n->onUnlocked();
}
m_isLocked = false;
}

View file

@ -0,0 +1,50 @@
#pragma once
#include <memory>
#include <vector>
#include <unordered_map>
#include "WaylandProtocol.hpp"
#include "hyprland-lock-notify-v1.hpp"
class CEventLoopTimer;
class CHyprlandLockNotification {
public:
CHyprlandLockNotification(SP<CHyprlandLockNotificationV1> resource_);
~CHyprlandLockNotification() = default;
bool good();
void onLocked();
void onUnlocked();
private:
SP<CHyprlandLockNotificationV1> m_resource;
bool m_locked = false;
};
class CLockNotifyProtocol : public IWaylandProtocol {
public:
CLockNotifyProtocol(const wl_interface* iface, const int& ver, const std::string& name);
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
void onLocked();
void onUnlocked();
private:
void onManagerResourceDestroy(wl_resource* res);
void destroyNotification(CHyprlandLockNotification* notif);
void onGetNotification(CHyprlandLockNotifierV1* pMgr, uint32_t id);
bool m_isLocked = false;
//
std::vector<UP<CHyprlandLockNotifierV1>> m_managers;
std::vector<SP<CHyprlandLockNotification>> m_notifications;
friend class CHyprlandLockNotification;
};
namespace PROTO {
inline UP<CLockNotifyProtocol> lockNotify;
};

View file

@ -2,6 +2,7 @@
#include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "FractionalScale.hpp"
#include "LockNotify.hpp"
#include "core/Compositor.hpp"
#include "core/Output.hpp"
#include "../helpers/Monitor.hpp"
@ -115,6 +116,8 @@ CSessionLock::CSessionLock(SP<CExtSessionLockV1> resource_) : resource(resource_
PROTO::sessionLock->locked = false;
PROTO::lockNotify->onUnlocked();
events.unlockAndDestroy.emit();
inert = true;
@ -128,6 +131,7 @@ CSessionLock::~CSessionLock() {
void CSessionLock::sendLocked() {
resource->sendLocked();
PROTO::lockNotify->onLocked();
}
bool CSessionLock::good() {

@ -1 +1 @@
Subproject commit 271df559dd30e4bc5ec6af02d017ac0aaabd63a7
Subproject commit 455c055883d9639d4fcbfcedb4c6d12ce313791e