mirror of
https://github.com/hyprwm/hypridle.git
synced 2025-05-14 06:00:39 +01:00
fix conflicts (merge main)
This commit is contained in:
commit
b5cdfbcf64
11 changed files with 316 additions and 107 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1,7 @@
|
||||||
.vscode/
|
.vscode/
|
||||||
build/
|
build/
|
||||||
protocols/
|
protocols/
|
||||||
|
.clangd/
|
||||||
|
.direnv/
|
||||||
|
.cache/
|
||||||
|
compile_commands.json
|
||||||
|
|
|
@ -35,6 +35,7 @@ message(STATUS "Checking deps...")
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
find_package(hyprwayland-scanner 0.4.4 REQUIRED)
|
||||||
pkg_check_modules(
|
pkg_check_modules(
|
||||||
deps
|
deps
|
||||||
REQUIRED
|
REQUIRED
|
||||||
|
@ -50,45 +51,47 @@ add_executable(hypridle ${SRCFILES})
|
||||||
target_link_libraries(hypridle PRIVATE rt Threads::Threads PkgConfig::deps)
|
target_link_libraries(hypridle PRIVATE rt Threads::Threads PkgConfig::deps)
|
||||||
|
|
||||||
# protocols
|
# protocols
|
||||||
find_program(WaylandScanner NAMES wayland-scanner)
|
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||||
message(STATUS "Found WaylandScanner at ${WaylandScanner}")
|
|
||||||
execute_process(
|
|
||||||
COMMAND pkg-config --variable=pkgdatadir wayland-protocols
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
||||||
|
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
|
||||||
|
message(STATUS "Found wayland-scanner pkgdatadir at ${WAYLAND_SCANNER_PKGDATA_DIR}")
|
||||||
|
|
||||||
function(protocol protoPath protoName external)
|
pkg_check_modules(hyprland_protocols_dep REQUIRED IMPORTED_TARGET hyprland-protocols>=0.6.0)
|
||||||
|
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
||||||
|
message(STATUS "Found hyprland-protocols at ${HYPRLAND_PROTOCOLS}")
|
||||||
|
|
||||||
|
function(protocolnew protoPath protoName external)
|
||||||
if(external)
|
if(external)
|
||||||
execute_process(
|
set(path ${protoPath})
|
||||||
COMMAND ${WaylandScanner} client-header ${protoPath}
|
|
||||||
protocols/${protoName}-protocol.h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} private-code ${protoPath}
|
|
||||||
protocols/${protoName}-protocol.c
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
target_sources(hypridle PRIVATE protocols/${protoName}-protocol.c)
|
|
||||||
else()
|
else()
|
||||||
execute_process(
|
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
||||||
COMMAND
|
|
||||||
${WaylandScanner} client-header ${WAYLAND_PROTOCOLS_DIR}/${protoPath}
|
|
||||||
protocols/${protoName}-protocol.h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
execute_process(
|
|
||||||
COMMAND
|
|
||||||
${WaylandScanner} private-code ${WAYLAND_PROTOCOLS_DIR}/${protoPath}
|
|
||||||
protocols/${protoName}-protocol.c
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
target_sources(hypridle PRIVATE protocols/${protoName}-protocol.c)
|
|
||||||
endif()
|
endif()
|
||||||
|
message(STATUS "Full proto path: ${path}")
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/${protoName}.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/${protoName}.hpp
|
||||||
|
COMMAND hyprwayland-scanner --client ${path}/${protoName}.xml
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
target_sources(hypridle PRIVATE protocols/${protoName}.cpp
|
||||||
|
protocols/${protoName}.hpp)
|
||||||
|
endfunction()
|
||||||
|
function(protocolWayland)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/wayland.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/wayland.hpp
|
||||||
|
COMMAND hyprwayland-scanner --wayland-enums --client
|
||||||
|
${WAYLAND_SCANNER_PKGDATA_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
target_sources(hypridle PRIVATE protocols/wayland.cpp protocols/wayland.hpp)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
make_directory(${CMAKE_SOURCE_DIR}/protocols) # we don't ship any custom ones so
|
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"
|
protocolwayland()
|
||||||
false)
|
|
||||||
|
protocolnew("staging/ext-idle-notify" "ext-idle-notify-v1" false)
|
||||||
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-lock-notify-v1" true)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
install(TARGETS hypridle)
|
install(TARGETS hypridle)
|
||||||
|
|
|
@ -36,6 +36,7 @@ will make those events ignored.
|
||||||
- wayland-protocols
|
- wayland-protocols
|
||||||
- hyprlang >= 0.4.0
|
- hyprlang >= 0.4.0
|
||||||
- sdbus-c++
|
- sdbus-c++
|
||||||
|
- hyprwayland-scanner
|
||||||
|
|
||||||
## Building & Installation
|
## Building & Installation
|
||||||
|
|
||||||
|
|
50
flake.lock
50
flake.lock
|
@ -1,5 +1,28 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"hyprland-protocols": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1737556638,
|
||||||
|
"narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprland-protocols",
|
||||||
|
"rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprland-protocols",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hyprlang": {
|
"hyprlang": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprutils": [
|
"hyprutils": [
|
||||||
|
@ -13,6 +36,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
|
"lastModified": 1734364628,
|
||||||
|
"narHash": "sha256-ii8fzJfI953n/EmIxVvq64ZAwhvwuuPHWfGd61/mJG8=",
|
||||||
"lastModified": 1737634606,
|
"lastModified": 1737634606,
|
||||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
|
@ -49,6 +74,29 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hyprwayland-scanner": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1735493474,
|
||||||
|
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprwayland-scanner",
|
||||||
|
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprwayland-scanner",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737469691,
|
"lastModified": 1737469691,
|
||||||
|
@ -67,8 +115,10 @@
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"hyprland-protocols": "hyprland-protocols",
|
||||||
"hyprlang": "hyprlang",
|
"hyprlang": "hyprlang",
|
||||||
"hyprutils": "hyprutils",
|
"hyprutils": "hyprutils",
|
||||||
|
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
}
|
}
|
||||||
|
|
12
flake.nix
12
flake.nix
|
@ -17,6 +17,18 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.systems.follows = "systems";
|
inputs.systems.follows = "systems";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hyprland-protocols = {
|
||||||
|
url = "github:hyprwm/hyprland-protocols";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
|
|
||||||
|
hyprwayland-scanner = {
|
||||||
|
url = "github:hyprwm/hyprwayland-scanner";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = {
|
outputs = {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
{
|
{
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
cmake,
|
cmake,
|
||||||
pkg-config,
|
hyprland-protocols,
|
||||||
hyprlang,
|
hyprlang,
|
||||||
hyprutils,
|
hyprutils,
|
||||||
|
hyprwayland-scanner,
|
||||||
|
lib,
|
||||||
|
pkg-config,
|
||||||
sdbus-cpp,
|
sdbus-cpp,
|
||||||
|
stdenv,
|
||||||
systemd,
|
systemd,
|
||||||
wayland,
|
wayland,
|
||||||
wayland-protocols,
|
wayland-protocols,
|
||||||
|
@ -19,11 +21,13 @@ stdenv.mkDerivation {
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
cmake
|
cmake
|
||||||
|
hyprwayland-scanner
|
||||||
pkg-config
|
pkg-config
|
||||||
wayland-scanner
|
wayland-scanner
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
|
hyprland-protocols
|
||||||
hyprlang
|
hyprlang
|
||||||
hyprutils
|
hyprutils
|
||||||
sdbus-cpp
|
sdbus-cpp
|
||||||
|
|
|
@ -13,8 +13,10 @@ in {
|
||||||
default = inputs.self.overlays.hypridle;
|
default = inputs.self.overlays.hypridle;
|
||||||
|
|
||||||
hypridle = lib.composeManyExtensions [
|
hypridle = lib.composeManyExtensions [
|
||||||
|
inputs.hyprland-protocols.overlays.default
|
||||||
inputs.hyprlang.overlays.default
|
inputs.hyprlang.overlays.default
|
||||||
inputs.hyprutils.overlays.default
|
inputs.hyprutils.overlays.default
|
||||||
|
inputs.hyprwayland-scanner.overlays.default
|
||||||
inputs.self.overlays.sdbuscpp
|
inputs.self.overlays.sdbuscpp
|
||||||
(final: prev: {
|
(final: prev: {
|
||||||
hypridle = prev.callPackage ./default.nix {
|
hypridle = prev.callPackage ./default.nix {
|
||||||
|
|
|
@ -23,10 +23,13 @@ void CConfigManager::init() {
|
||||||
|
|
||||||
m_config.addConfigValue("general:lock_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:lock_cmd", Hyprlang::STRING{""});
|
||||||
m_config.addConfigValue("general:unlock_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:unlock_cmd", Hyprlang::STRING{""});
|
||||||
|
m_config.addConfigValue("general:on_lock_cmd", Hyprlang::STRING{""});
|
||||||
|
m_config.addConfigValue("general:on_unlock_cmd", Hyprlang::STRING{""});
|
||||||
m_config.addConfigValue("general:before_sleep_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:before_sleep_cmd", Hyprlang::STRING{""});
|
||||||
m_config.addConfigValue("general:after_sleep_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:after_sleep_cmd", Hyprlang::STRING{""});
|
||||||
m_config.addConfigValue("general:ignore_dbus_inhibit", Hyprlang::INT{0});
|
m_config.addConfigValue("general:ignore_dbus_inhibit", Hyprlang::INT{0});
|
||||||
m_config.addConfigValue("general:ignore_systemd_inhibit", Hyprlang::INT{0});
|
m_config.addConfigValue("general:ignore_systemd_inhibit", Hyprlang::INT{0});
|
||||||
|
m_config.addConfigValue("general:inhibit_sleep", Hyprlang::INT{2});
|
||||||
|
|
||||||
m_config.commence();
|
m_config.commence();
|
||||||
|
|
||||||
|
|
|
@ -18,36 +18,32 @@ CHypridle::CHypridle() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
|
|
||||||
g_pHypridle->onGlobal(data, registry, name, interface, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name) {
|
|
||||||
g_pHypridle->onGlobalRemoved(data, registry, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const wl_registry_listener registryListener = {
|
|
||||||
.global = handleGlobal,
|
|
||||||
.global_remove = handleGlobalRemove,
|
|
||||||
};
|
|
||||||
|
|
||||||
void handleIdled(void* data, ext_idle_notification_v1* ext_idle_notification_v1) {
|
|
||||||
g_pHypridle->onIdled((CHypridle::SIdleListener*)data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleResumed(void* data, ext_idle_notification_v1* ext_idle_notification_v1) {
|
|
||||||
g_pHypridle->onResumed((CHypridle::SIdleListener*)data);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const ext_idle_notification_v1_listener idleListener = {
|
|
||||||
.idled = handleIdled,
|
|
||||||
.resumed = handleResumed,
|
|
||||||
};
|
|
||||||
|
|
||||||
void CHypridle::run() {
|
void CHypridle::run() {
|
||||||
m_sWaylandState.registry = wl_display_get_registry(m_sWaylandState.display);
|
m_sWaylandState.registry = makeShared<CCWlRegistry>((wl_proxy*)wl_display_get_registry(m_sWaylandState.display));
|
||||||
|
m_sWaylandState.registry->setGlobal([this](CCWlRegistry* r, uint32_t name, const char* interface, uint32_t version) {
|
||||||
|
const std::string IFACE = interface;
|
||||||
|
Debug::log(LOG, " | got iface: {} v{}", IFACE, version);
|
||||||
|
|
||||||
wl_registry_add_listener(m_sWaylandState.registry, ®istryListener, nullptr);
|
if (IFACE == ext_idle_notifier_v1_interface.name) {
|
||||||
|
m_sWaylandIdleState.notifier =
|
||||||
|
makeShared<CCExtIdleNotifierV1>((wl_proxy*)wl_registry_bind((wl_registry*)r->resource(), 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 =
|
||||||
|
makeShared<CCHyprlandLockNotifierV1>((wl_proxy*)wl_registry_bind((wl_registry*)r->resource(), 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.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sWaylandState.seat = makeShared<CCWlSeat>((wl_proxy*)wl_registry_bind((wl_registry*)r->resource(), name, &wl_seat_interface, version));
|
||||||
|
Debug::log(LOG, " > Bound to {} v{}", IFACE, version);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_sWaylandState.registry->setGlobalRemove([](CCWlRegistry* r, uint32_t name) { Debug::log(LOG, " | removed iface {}", name); });
|
||||||
|
|
||||||
wl_display_roundtrip(m_sWaylandState.display);
|
wl_display_roundtrip(m_sWaylandState.display);
|
||||||
|
|
||||||
|
@ -64,15 +60,24 @@ void CHypridle::run() {
|
||||||
for (size_t i = 0; i < RULES.size(); ++i) {
|
for (size_t i = 0; i < RULES.size(); ++i) {
|
||||||
auto& l = m_sWaylandIdleState.listeners[i];
|
auto& l = m_sWaylandIdleState.listeners[i];
|
||||||
const auto& r = RULES[i];
|
const auto& r = RULES[i];
|
||||||
l.notification = ext_idle_notifier_v1_get_idle_notification(m_sWaylandIdleState.notifier, r.timeout * 1000 /* ms */, m_sWaylandState.seat);
|
|
||||||
l.onRestore = r.onResume;
|
l.onRestore = r.onResume;
|
||||||
l.onTimeout = r.onTimeout;
|
l.onTimeout = r.onTimeout;
|
||||||
|
|
||||||
ext_idle_notification_v1_add_listener(l.notification, &idleListener, &l);
|
l.notification = makeShared<CCExtIdleNotificationV1>(m_sWaylandIdleState.notifier->sendGetIdleNotification(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));
|
||||||
|
l.notification->setData(&m_sWaylandIdleState.listeners[i]);
|
||||||
|
|
||||||
|
l.notification->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
|
||||||
|
l.notification->setResumed([this](CCExtIdleNotificationV1* n) { onResumed((CHypridle::SIdleListener*)n->data()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_display_roundtrip(m_sWaylandState.display);
|
wl_display_roundtrip(m_sWaylandState.display);
|
||||||
|
|
||||||
|
if (m_sWaylandState.lockNotifier) {
|
||||||
|
m_sWaylandState.lockNotification = makeShared<CCHyprlandLockNotificationV1>(m_sWaylandState.lockNotifier->sendGetLockNotification());
|
||||||
|
m_sWaylandState.lockNotification->setLocked([this](CCHyprlandLockNotificationV1* n) { onLocked(); });
|
||||||
|
m_sWaylandState.lockNotification->setUnlocked([this](CCHyprlandLockNotificationV1* n) { onUnlocked(); });
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "wayland done, registering dbus");
|
Debug::log(LOG, "wayland done, registering dbus");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -82,7 +87,46 @@ void CHypridle::run() {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_sWaylandState.lockNotifier)
|
||||||
|
Debug::log(WARN,
|
||||||
|
"Compositor is missing hyprland-lock-notify-v1!\n"
|
||||||
|
"general:inhibit_sleep=3, general:on_lock_cmd and general:on_unlock_cmd will not work.");
|
||||||
|
|
||||||
|
static auto* const PINHIBIT = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:inhibit_sleep");
|
||||||
|
static auto* const PSLEEPCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:before_sleep_cmd");
|
||||||
|
static auto* const PLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:lock_cmd");
|
||||||
|
|
||||||
|
switch (**PINHIBIT) {
|
||||||
|
case 0: // disabled
|
||||||
|
m_inhibitSleepBehavior = SLEEP_INHIBIT_NONE;
|
||||||
|
break;
|
||||||
|
case 1: // enabled
|
||||||
|
m_inhibitSleepBehavior = SLEEP_INHIBIT_NORMAL;
|
||||||
|
break;
|
||||||
|
case 2: { // auto (enable, but wait until locked if before_sleep_cmd contains hyprlock, or loginctl lock-session and lock_cmd contains hyprlock.)
|
||||||
|
if (m_sWaylandState.lockNotifier && std::string{*PSLEEPCMD}.contains("hyprlock"))
|
||||||
|
m_inhibitSleepBehavior = SLEEP_INHIBIT_LOCK_NOTIFY;
|
||||||
|
else if (m_sWaylandState.lockNotifier && std::string{*PLOCKCMD}.contains("hyprlock") && std::string{*PSLEEPCMD}.contains("lock-session"))
|
||||||
|
m_inhibitSleepBehavior = SLEEP_INHIBIT_LOCK_NOTIFY;
|
||||||
|
else
|
||||||
|
m_inhibitSleepBehavior = SLEEP_INHIBIT_NORMAL;
|
||||||
|
} break;
|
||||||
|
case 3: // wait until locked
|
||||||
|
if (m_sWaylandState.lockNotifier)
|
||||||
|
m_inhibitSleepBehavior = SLEEP_INHIBIT_LOCK_NOTIFY;
|
||||||
|
break;
|
||||||
|
default: Debug::log(ERR, "Invalid inhibit_sleep value: {}", **PINHIBIT); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_inhibitSleepBehavior) {
|
||||||
|
case SLEEP_INHIBIT_NONE: Debug::log(LOG, "Sleep inhibition disabled"); break;
|
||||||
|
case SLEEP_INHIBIT_NORMAL: Debug::log(LOG, "Sleep inhibition enabled"); break;
|
||||||
|
case SLEEP_INHIBIT_LOCK_NOTIFY: Debug::log(LOG, "Sleep inhibition enabled - inhibiting until the wayland session gets locked"); break;
|
||||||
|
}
|
||||||
|
|
||||||
setupDBUS();
|
setupDBUS();
|
||||||
|
if (m_inhibitSleepBehavior != SLEEP_INHIBIT_NONE)
|
||||||
|
inhibitSleep();
|
||||||
enterEventLoop();
|
enterEventLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,28 +231,6 @@ void CHypridle::enterEventLoop() {
|
||||||
Debug::log(ERR, "[core] Terminated");
|
Debug::log(ERR, "[core] Terminated");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHypridle::onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
|
|
||||||
const std::string IFACE = interface;
|
|
||||||
Debug::log(LOG, " | got iface: {} v{}", IFACE, version);
|
|
||||||
|
|
||||||
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 == wl_seat_interface.name) {
|
|
||||||
if (m_sWaylandState.seat) {
|
|
||||||
Debug::log(WARN, "Hypridle does not support multi-seat configurations. Only binding to the first seat.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sWaylandState.seat = (wl_seat*)wl_registry_bind(registry, name, &wl_seat_interface, version);
|
|
||||||
Debug::log(LOG, " > Bound to {} v{}", IFACE, version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHypridle::onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void spawn(const std::string& args) {
|
static void spawn(const std::string& args) {
|
||||||
Debug::log(LOG, "Executing {}", args);
|
Debug::log(LOG, "Executing {}", args);
|
||||||
|
|
||||||
|
@ -244,6 +266,7 @@ static void spawn(const std::string& args) {
|
||||||
close(socket[0]);
|
close(socket[0]);
|
||||||
write(socket[1], &grandchild, sizeof(grandchild));
|
write(socket[1], &grandchild, sizeof(grandchild));
|
||||||
close(socket[1]);
|
close(socket[1]);
|
||||||
|
waitpid(grandchild, NULL, 0);
|
||||||
// exit child
|
// exit child
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
@ -310,17 +333,42 @@ void CHypridle::onInhibit(bool lock) {
|
||||||
auto& l = m_sWaylandIdleState.listeners[i];
|
auto& l = m_sWaylandIdleState.listeners[i];
|
||||||
const auto& r = RULES[i];
|
const auto& r = RULES[i];
|
||||||
|
|
||||||
ext_idle_notification_v1_destroy(l.notification);
|
l.notification->sendDestroy();
|
||||||
|
|
||||||
l.notification = ext_idle_notifier_v1_get_idle_notification(m_sWaylandIdleState.notifier, r.timeout * 1000 /* ms */, m_sWaylandState.seat);
|
l.notification =
|
||||||
|
makeShared<CCExtIdleNotificationV1>(m_sWaylandIdleState.notifier->sendGetIdleNotification(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));
|
||||||
|
l.notification->setData(&m_sWaylandIdleState.listeners[i]);
|
||||||
|
|
||||||
ext_idle_notification_v1_add_listener(l.notification, &idleListener, &l);
|
l.notification->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
|
||||||
|
l.notification->setResumed([this](CCExtIdleNotificationV1* n) { onResumed((CHypridle::SIdleListener*)n->data()); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Inhibit locks: {}", m_iInhibitLocks);
|
Debug::log(LOG, "Inhibit locks: {}", m_iInhibitLocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHypridle::onLocked() {
|
||||||
|
Debug::log(LOG, "Wayland session got locked");
|
||||||
|
m_isLocked = true;
|
||||||
|
|
||||||
|
if (const auto* const PLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:on_lock_cmd"); PLOCKCMD && strlen(*PLOCKCMD) > 0)
|
||||||
|
spawn(*PLOCKCMD);
|
||||||
|
|
||||||
|
if (m_inhibitSleepBehavior == SLEEP_INHIBIT_LOCK_NOTIFY)
|
||||||
|
uninhibitSleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHypridle::onUnlocked() {
|
||||||
|
Debug::log(LOG, "Wayland session got unlocked");
|
||||||
|
m_isLocked = false;
|
||||||
|
|
||||||
|
if (m_inhibitSleepBehavior == SLEEP_INHIBIT_LOCK_NOTIFY)
|
||||||
|
inhibitSleep();
|
||||||
|
|
||||||
|
if (const auto* const PUNLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:on_unlock_cmd"); PUNLOCKCMD && strlen(*PUNLOCKCMD) > 0)
|
||||||
|
spawn(*PUNLOCKCMD);
|
||||||
|
}
|
||||||
|
|
||||||
CHypridle::SDbusInhibitCookie CHypridle::getDbusInhibitCookie(uint32_t cookie) {
|
CHypridle::SDbusInhibitCookie CHypridle::getDbusInhibitCookie(uint32_t cookie) {
|
||||||
for (auto& c : m_sDBUSState.inhibitCookies) {
|
for (auto& c : m_sDBUSState.inhibitCookies) {
|
||||||
if (c.cookie == cookie)
|
if (c.cookie == cookie)
|
||||||
|
@ -397,11 +445,14 @@ static void handleDbusSleep(sdbus::Message msg) {
|
||||||
|
|
||||||
std::string cmd = toSleep ? *PSLEEPCMD : *PAFTERSLEEPCMD;
|
std::string cmd = toSleep ? *PSLEEPCMD : *PAFTERSLEEPCMD;
|
||||||
|
|
||||||
if (cmd.empty())
|
if (!toSleep)
|
||||||
return;
|
g_pHypridle->handleInhibitOnDbusSleep(toSleep);
|
||||||
|
|
||||||
Debug::log(LOG, "Running: {}", cmd);
|
if (!cmd.empty())
|
||||||
spawn(cmd);
|
spawn(cmd);
|
||||||
|
|
||||||
|
if (toSleep)
|
||||||
|
g_pHypridle->handleInhibitOnDbusSleep(toSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDbusBlockInhibits(const std::string& inhibits) {
|
void handleDbusBlockInhibits(const std::string& inhibits) {
|
||||||
|
@ -496,6 +547,7 @@ void CHypridle::setupDBUS() {
|
||||||
|
|
||||||
m_sDBUSState.connection->addMatch("type='signal',path='" + path + "',interface='org.freedesktop.login1.Session'", ::handleDbusLogin);
|
m_sDBUSState.connection->addMatch("type='signal',path='" + path + "',interface='org.freedesktop.login1.Session'", ::handleDbusLogin);
|
||||||
m_sDBUSState.connection->addMatch("type='signal',path='/org/freedesktop/login1',interface='org.freedesktop.login1.Manager'", ::handleDbusSleep);
|
m_sDBUSState.connection->addMatch("type='signal',path='/org/freedesktop/login1',interface='org.freedesktop.login1.Manager'", ::handleDbusSleep);
|
||||||
|
m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"});
|
||||||
} catch (std::exception& e) { Debug::log(WARN, "Couldn't connect to logind service ({})", e.what()); }
|
} catch (std::exception& e) { Debug::log(WARN, "Couldn't connect to logind service ({})", e.what()); }
|
||||||
|
|
||||||
Debug::log(LOG, "Using dbus path {}", path.c_str());
|
Debug::log(LOG, "Using dbus path {}", path.c_str());
|
||||||
|
@ -542,3 +594,52 @@ void CHypridle::setupDBUS() {
|
||||||
|
|
||||||
systemConnection.reset();
|
systemConnection.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHypridle::handleInhibitOnDbusSleep(bool toSleep) {
|
||||||
|
if (m_inhibitSleepBehavior == SLEEP_INHIBIT_NONE || //
|
||||||
|
m_inhibitSleepBehavior == SLEEP_INHIBIT_LOCK_NOTIFY // Sleep inhibition handled via onLocked/onUnlocked
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!toSleep)
|
||||||
|
inhibitSleep();
|
||||||
|
else
|
||||||
|
uninhibitSleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHypridle::inhibitSleep() {
|
||||||
|
auto method = m_sDBUSState.login->createMethodCall(sdbus::InterfaceName{"org.freedesktop.login1.Manager"}, sdbus::MethodName{"Inhibit"});
|
||||||
|
method << "sleep";
|
||||||
|
method << "hypridle";
|
||||||
|
method << "Hypridle wants to delay sleep until it's before_sleep handling is done.";
|
||||||
|
method << "delay";
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto reply = m_sDBUSState.login->callMethod(method);
|
||||||
|
|
||||||
|
if (!reply || !reply.isValid()) {
|
||||||
|
Debug::log(ERR, "Failed to inhibit sleep");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply.isEmpty()) {
|
||||||
|
Debug::log(ERR, "Failed to inhibit sleep, empty reply");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reply >> m_sDBUSState.sleepInhibitFd;
|
||||||
|
Debug::log(TRACE, "Inhibited sleep with fd {}", m_sDBUSState.sleepInhibitFd.get());
|
||||||
|
} catch (const std::exception& e) { Debug::log(ERR, "Failed to inhibit sleep ({})", e.what()); }
|
||||||
|
|
||||||
|
Debug::log(LOG, "Inhibited sleep!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHypridle::uninhibitSleep() {
|
||||||
|
if (!m_sDBUSState.sleepInhibitFd.isValid()) {
|
||||||
|
Debug::log(ERR, "No sleep inhibitor fd to release");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Releasing the sleep inhibitor!");
|
||||||
|
close(m_sDBUSState.sleepInhibitFd.release());
|
||||||
|
}
|
||||||
|
|
|
@ -2,18 +2,21 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wayland-client.h>
|
|
||||||
#include <sdbus-c++/sdbus-c++.h>
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
#include "ext-idle-notify-v1-protocol.h"
|
#include "wayland.hpp"
|
||||||
|
#include "ext-idle-notify-v1.hpp"
|
||||||
|
#include "hyprland-lock-notify-v1.hpp"
|
||||||
|
|
||||||
|
#include "../defines.hpp"
|
||||||
|
|
||||||
class CHypridle {
|
class CHypridle {
|
||||||
public:
|
public:
|
||||||
CHypridle();
|
CHypridle();
|
||||||
|
|
||||||
struct SIdleListener {
|
struct SIdleListener {
|
||||||
ext_idle_notification_v1* notification = nullptr;
|
SP<CCExtIdleNotificationV1> notification = nullptr;
|
||||||
std::string onTimeout = "";
|
std::string onTimeout = "";
|
||||||
std::string onRestore = "";
|
std::string onRestore = "";
|
||||||
};
|
};
|
||||||
|
@ -33,27 +36,43 @@ class CHypridle {
|
||||||
|
|
||||||
void onInhibit(bool lock);
|
void onInhibit(bool lock);
|
||||||
|
|
||||||
|
void onLocked();
|
||||||
|
void onUnlocked();
|
||||||
|
|
||||||
SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie);
|
SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie);
|
||||||
void registerDbusInhibitCookie(SDbusInhibitCookie& cookie);
|
void registerDbusInhibitCookie(SDbusInhibitCookie& cookie);
|
||||||
bool unregisterDbusInhibitCookie(const SDbusInhibitCookie& cookie);
|
bool unregisterDbusInhibitCookie(const SDbusInhibitCookie& cookie);
|
||||||
bool unregisterDbusInhibitCookies(const std::string& ownerID);
|
bool unregisterDbusInhibitCookies(const std::string& ownerID);
|
||||||
|
|
||||||
|
void handleInhibitOnDbusSleep(bool toSleep);
|
||||||
|
void inhibitSleep();
|
||||||
|
void uninhibitSleep();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupDBUS();
|
void setupDBUS();
|
||||||
void enterEventLoop();
|
void enterEventLoop();
|
||||||
|
|
||||||
bool m_bTerminate = false;
|
bool m_bTerminate = false;
|
||||||
bool isIdled = false;
|
bool isIdled = false;
|
||||||
|
bool m_isLocked = false;
|
||||||
int64_t m_iInhibitLocks = 0;
|
int64_t m_iInhibitLocks = 0;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SLEEP_INHIBIT_NONE,
|
||||||
|
SLEEP_INHIBIT_NORMAL,
|
||||||
|
SLEEP_INHIBIT_LOCK_NOTIFY,
|
||||||
|
} m_inhibitSleepBehavior;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
wl_display* display = nullptr;
|
wl_display* display = nullptr;
|
||||||
wl_registry* registry = nullptr;
|
SP<CCWlRegistry> registry = nullptr;
|
||||||
wl_seat* seat = nullptr;
|
SP<CCWlSeat> seat = nullptr;
|
||||||
|
SP<CCHyprlandLockNotifierV1> lockNotifier = nullptr;
|
||||||
|
SP<CCHyprlandLockNotificationV1> lockNotification = nullptr;
|
||||||
} m_sWaylandState;
|
} m_sWaylandState;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
ext_idle_notifier_v1* notifier = nullptr;
|
SP<CCExtIdleNotifierV1> notifier = nullptr;
|
||||||
|
|
||||||
std::vector<SIdleListener> listeners;
|
std::vector<SIdleListener> listeners;
|
||||||
} m_sWaylandIdleState;
|
} m_sWaylandIdleState;
|
||||||
|
@ -61,8 +80,10 @@ class CHypridle {
|
||||||
struct {
|
struct {
|
||||||
std::unique_ptr<sdbus::IConnection> connection;
|
std::unique_ptr<sdbus::IConnection> connection;
|
||||||
std::unique_ptr<sdbus::IConnection> screenSaverServiceConnection;
|
std::unique_ptr<sdbus::IConnection> screenSaverServiceConnection;
|
||||||
|
std::unique_ptr<sdbus::IProxy> login;
|
||||||
std::vector<std::unique_ptr<sdbus::IObject>> screenSaverObjects;
|
std::vector<std::unique_ptr<sdbus::IObject>> screenSaverObjects;
|
||||||
std::vector<SDbusInhibitCookie> inhibitCookies;
|
std::vector<SDbusInhibitCookie> inhibitCookies;
|
||||||
|
sdbus::UnixFd sleepInhibitFd;
|
||||||
} m_sDBUSState;
|
} m_sDBUSState;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
8
src/defines.hpp
Normal file
8
src/defines.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "wayland.hpp"
|
||||||
|
#include "ext-idle-notify-v1.hpp"
|
||||||
|
#include "hyprland-lock-notify-v1.hpp"
|
||||||
|
|
||||||
|
#include <hyprutils/memory/WeakPtr.hpp>
|
||||||
|
using namespace Hyprutils::Memory;
|
||||||
|
#define SP CSharedPointer
|
||||||
|
#define WP CWeakPointer
|
Loading…
Reference in a new issue