core: add hyprland-lock-notify-v1 protocol implementation

This commit is contained in:
Maximilian Seidler 2025-01-17 07:57:58 +01:00
parent 413564cb98
commit 0b702aa32f
8 changed files with 89 additions and 5 deletions

6
.gitignore vendored
View file

@ -1,3 +1,7 @@
.vscode/
build/
protocols/
protocols/
.clangd/
.direnv/
.cache/
compile_commands.json

View file

@ -85,10 +85,17 @@ function(protocol protoPath protoName external)
endif()
endfunction()
pkg_check_modules(hyprland_protocols_dep REQUIRED IMPORTED_TARGET hyprland-protocols>=0.4.0)
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
make_directory(${CMAKE_SOURCE_DIR}/protocols) # we don't ship any custom ones so
# the dir won't be there
protocol("staging/ext-idle-notify/ext-idle-notify-v1.xml" "ext-idle-notify-v1"
false)
protocol("${HYPRLAND_PROTOCOLS}/protocols/hyprland-lock-notify-v1.xml" "hyprland-lock-notify-v1"
true)
# Installation
install(TARGETS hypridle)

23
flake.lock generated
View file

@ -1,5 +1,27 @@
{
"nodes": {
"hyprland-protocols": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1737053288,
"narHash": "sha256-RV6n5M5kewrOfpDMdVzj5oVRhVHiZpjDcaOHGYMcnRo=",
"rev": "5b17e27fde2155eeb96ff487b7721e5df0a72296",
"revCount": 30,
"type": "git",
"url": "file:///home/max/desk/hyprland-protocols"
},
"original": {
"type": "git",
"url": "file:///home/max/desk/hyprland-protocols"
}
},
"hyprlang": {
"inputs": {
"hyprutils": [
@ -67,6 +89,7 @@
},
"root": {
"inputs": {
"hyprland-protocols": "hyprland-protocols",
"hyprlang": "hyprlang",
"hyprutils": "hyprutils",
"nixpkgs": "nixpkgs",

View file

@ -17,6 +17,12 @@
inputs.nixpkgs.follows = "nixpkgs";
inputs.systems.follows = "systems";
};
hyprland-protocols = {
url = "github:hyprwm/hyprland-protocols";
inputs.nixpkgs.follows = "nixpkgs";
inputs.systems.follows = "systems";
};
};
outputs = {

View file

@ -2,9 +2,10 @@
lib,
stdenv,
cmake,
pkg-config,
hyprland-protocols,
hyprlang,
hyprutils,
pkg-config,
sdbus-cpp,
systemd,
wayland,
@ -24,6 +25,7 @@ stdenv.mkDerivation {
];
buildInputs = [
hyprland-protocols
hyprlang
hyprutils
sdbus-cpp

View file

@ -13,6 +13,7 @@ in {
default = inputs.self.overlays.hypridle;
hypridle = lib.composeManyExtensions [
inputs.hyprland-protocols.overlays.default
inputs.hyprlang.overlays.default
inputs.hyprutils.overlays.default
inputs.self.overlays.sdbuscpp

View file

@ -1,6 +1,8 @@
#include "Hypridle.hpp"
#include "../helpers/Log.hpp"
#include "../config/ConfigManager.hpp"
#include "ext-idle-notify-v1-protocol.h"
#include "hyprland-lock-notify-v1-protocol.h"
#include "signal.h"
#include <sys/wait.h>
#include <sys/poll.h>
@ -44,6 +46,19 @@ inline const ext_idle_notification_v1_listener idleListener = {
.resumed = handleResumed,
};
void handleLocked(void* data, hyprland_lock_notification_v1* hyprland_lock_notification_v1) {
Debug::log(LOG, "Locked");
}
void handleUnlocked(void* data, hyprland_lock_notification_v1* hyprland_lock_notification_v1) {
Debug::log(LOG, "Unlocked");
}
inline const hyprland_lock_notification_v1_listener lockListener = {
.locked = handleLocked,
.unlocked = handleUnlocked,
};
void CHypridle::run() {
m_sWaylandState.registry = wl_display_get_registry(m_sWaylandState.display);
@ -73,6 +88,12 @@ void CHypridle::run() {
wl_display_roundtrip(m_sWaylandState.display);
if (m_sWaylandState.lockNotifier) {
m_sWaylandState.lockNotification = hyprland_lock_notifier_v1_get_lock_notification(m_sWaylandState.lockNotifier);
hyprland_lock_notification_v1_add_listener(m_sWaylandState.lockNotification, &lockListener, nullptr);
}
Debug::log(LOG, "wayland done, registering dbus");
try {
@ -194,6 +215,9 @@ void CHypridle::onGlobal(void* data, struct wl_registry* registry, uint32_t name
if (IFACE == ext_idle_notifier_v1_interface.name) {
m_sWaylandIdleState.notifier = (ext_idle_notifier_v1*)wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, version);
Debug::log(LOG, " > Bound to {} v{}", IFACE, version);
} else if (IFACE == hyprland_lock_notifier_v1_interface.name) {
m_sWaylandState.lockNotifier = (hyprland_lock_notifier_v1*)wl_registry_bind(registry, name, &hyprland_lock_notifier_v1_interface, version);
Debug::log(LOG, " > Bound to {} v{}", IFACE, version);
} else if (IFACE == wl_seat_interface.name) {
if (m_sWaylandState.seat) {
Debug::log(WARN, "Hypridle does not support multi-seat configurations. Only binding to the first seat.");
@ -295,6 +319,16 @@ void CHypridle::onResumed(SIdleListener* pListener) {
spawn(pListener->onRestore);
}
void CHypridle::onLocked() {
Debug::log(LOG, "Locked");
m_isLocked = true;
if (const auto* const PLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:on_lock_cmd"); !PLOCKCMD->empty()) {
Debug::log(LOG, "Running {}", *PLOCKCMD);
spawn(*PLOCKCMD);
}
}
void CHypridle::onInhibit(bool lock) {
m_iInhibitLocks += lock ? 1 : -1;

View file

@ -7,6 +7,7 @@
#include <condition_variable>
#include "ext-idle-notify-v1-protocol.h"
#include "hyprland-lock-notify-v1-protocol.h"
class CHypridle {
public:
@ -31,6 +32,9 @@ class CHypridle {
void onIdled(SIdleListener*);
void onResumed(SIdleListener*);
void onLocked();
void onUnlocked();
void onInhibit(bool lock);
SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie);
@ -44,12 +48,15 @@ class CHypridle {
bool m_bTerminate = false;
bool isIdled = false;
bool m_isLocked = false;
int64_t m_iInhibitLocks = 0;
struct {
wl_display* display = nullptr;
wl_registry* registry = nullptr;
wl_seat* seat = nullptr;
wl_display* display = nullptr;
wl_registry* registry = nullptr;
wl_seat* seat = nullptr;
hyprland_lock_notifier_v1* lockNotifier = nullptr;
hyprland_lock_notification_v1* lockNotification = nullptr;
} m_sWaylandState;
struct {