mirror of
https://github.com/hyprwm/hypridle.git
synced 2025-12-20 09:00:02 +01:00
Compare commits
14 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3d1f3b232 | ||
| f158b2fe92 | |||
| 5430b73ddf | |||
| dda793b66a | |||
|
|
25578b7137 | ||
| cff17e8b52 | |||
|
|
b2bc15baff | ||
|
|
a282131ac7 | ||
|
|
63d08e8e72 | ||
|
|
4f1c165d3e | ||
|
|
ecf2a3649d | ||
|
|
a0037ac40c | ||
|
|
b18d830276 | ||
|
|
66d1815b5e |
13 changed files with 234 additions and 60 deletions
|
|
@ -1,12 +1,12 @@
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
HeaderFilterRegex: '.*\.hpp'
|
HeaderFilterRegex: '.*\.hpp'
|
||||||
FormatStyle: file
|
FormatStyle: 'file'
|
||||||
Checks: >
|
Checks: >
|
||||||
-*,
|
-*,
|
||||||
bugprone-*,
|
bugprone-*,
|
||||||
-bugprone-easily-swappable-parameters,
|
-bugprone-easily-swappable-parameters,
|
||||||
-bugprone-forward-declararion-namespace,
|
-bugprone-forward-declaration-namespace,
|
||||||
-bugprone-forward-declararion-namespace,
|
-bugprone-forward-declaration-namespace,
|
||||||
-bugprone-macro-parentheses,
|
-bugprone-macro-parentheses,
|
||||||
-bugprone-narrowing-conversions,
|
-bugprone-narrowing-conversions,
|
||||||
-bugprone-branch-clone,
|
-bugprone-branch-clone,
|
||||||
|
|
|
||||||
30
.github/workflows/nix.yml
vendored
30
.github/workflows/nix.yml
vendored
|
|
@ -7,7 +7,35 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
- name: Install Nix
|
||||||
|
uses: nixbuild/nix-quick-install-action@v31
|
||||||
|
with:
|
||||||
|
nix_conf: |
|
||||||
|
keep-env-derivations = true
|
||||||
|
keep-outputs = true
|
||||||
|
|
||||||
|
- name: Restore and save Nix store
|
||||||
|
uses: nix-community/cache-nix-action@v6
|
||||||
|
with:
|
||||||
|
# restore and save a cache using this key
|
||||||
|
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
|
||||||
|
# if there's no cache hit, restore a cache by this prefix
|
||||||
|
restore-prefixes-first-match: nix-${{ runner.os }}-
|
||||||
|
# collect garbage until the Nix store size (in bytes) is at most this number
|
||||||
|
# before trying to save a new cache
|
||||||
|
# 1G = 1073741824
|
||||||
|
gc-max-store-size-linux: 1G
|
||||||
|
# do purge caches
|
||||||
|
purge: true
|
||||||
|
# purge all versions of the cache
|
||||||
|
purge-prefixes: nix-${{ runner.os }}-
|
||||||
|
# created more than this number of seconds ago
|
||||||
|
purge-created: 0
|
||||||
|
# or, last accessed more than this number of seconds ago
|
||||||
|
# relative to the start of the `Post Restore and save Nix store` phase
|
||||||
|
purge-last-accessed: 0
|
||||||
|
# except any version with the key that is the same as the `primary-key`
|
||||||
|
purge-primary-key: never
|
||||||
|
|
||||||
# not needed (yet)
|
# not needed (yet)
|
||||||
# - uses: cachix/cachix-action@v12
|
# - uses: cachix/cachix-action@v12
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ will make those events ignored.
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- wayland
|
- wayland
|
||||||
- wayland-protocols
|
- wayland-protocols
|
||||||
|
- hyprland-protocols
|
||||||
- hyprlang >= 0.4.0
|
- hyprlang >= 0.4.0
|
||||||
- sdbus-c++
|
- sdbus-c++
|
||||||
- hyprwayland-scanner
|
- hyprwayland-scanner
|
||||||
|
|
@ -42,8 +43,8 @@ will make those events ignored.
|
||||||
|
|
||||||
### Building:
|
### Building:
|
||||||
```sh
|
```sh
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -S . -B ./build
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
|
||||||
cmake --build ./build --config Release --target hypridle -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF`
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installation:
|
### Installation:
|
||||||
|
|
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
0.1.6
|
0.1.7
|
||||||
|
|
|
||||||
32
flake.lock
generated
32
flake.lock
generated
|
|
@ -10,11 +10,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737556638,
|
"lastModified": 1749046714,
|
||||||
"narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=",
|
"narHash": "sha256-kymV5FMnddYGI+UjwIw8ceDjdeg7ToDVjbHCvUlhn14=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprland-protocols",
|
"repo": "hyprland-protocols",
|
||||||
"rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5",
|
"rev": "613878cb6f459c5e323aaafe1e6f388ac8a36330",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -36,13 +36,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734364628,
|
"lastModified": 1749145882,
|
||||||
"narHash": "sha256-ii8fzJfI953n/EmIxVvq64ZAwhvwuuPHWfGd61/mJG8=",
|
"narHash": "sha256-qr0KXeczF8Sma3Ae7+dR2NHhvG7YeLBJv19W4oMu6ZE=",
|
||||||
"lastModified": 1737634606,
|
|
||||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprlang",
|
"repo": "hyprlang",
|
||||||
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
|
"rev": "1bfb84f54d50c7ae6558c794d3cfd5f6a7e6e676",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -61,11 +59,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737632363,
|
"lastModified": 1749135356,
|
||||||
"narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=",
|
"narHash": "sha256-Q8mAKMDsFbCEuq7zoSlcTuxgbIBVhfIYpX0RjE32PS0=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprutils",
|
"repo": "hyprutils",
|
||||||
"rev": "006620eb29d54ea9086538891404c78563d1bae1",
|
"rev": "e36db00dfb3a3d3fdcc4069cb292ff60d2699ccb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -84,11 +82,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1735493474,
|
"lastModified": 1749145760,
|
||||||
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
|
"narHash": "sha256-IHaGWpGrv7seFWdw/1A+wHtTsPlOGIKMrk1TUIYJEFI=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprwayland-scanner",
|
"repo": "hyprwayland-scanner",
|
||||||
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
|
"rev": "817918315ea016cc2d94004bfb3223b5fd9dfcc6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -99,11 +97,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737469691,
|
"lastModified": 1748929857,
|
||||||
"narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
|
"narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab",
|
"rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ in {
|
||||||
inputs.self.overlays.sdbuscpp
|
inputs.self.overlays.sdbuscpp
|
||||||
(final: prev: {
|
(final: prev: {
|
||||||
hypridle = prev.callPackage ./default.nix {
|
hypridle = prev.callPackage ./default.nix {
|
||||||
stdenv = prev.gcc14Stdenv;
|
stdenv = prev.gcc15Stdenv;
|
||||||
version = version + "+date=" + (mkDate (inputs.self.lastModifiedDate or "19700101")) + "_" + (inputs.self.shortRev or "dirty");
|
version = version + "+date=" + (mkDate (inputs.self.lastModifiedDate or "19700101")) + "_" + (inputs.self.shortRev or "dirty");
|
||||||
inherit (final) hyprlang;
|
inherit (final) hyprlang;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
#include "ConfigManager.hpp"
|
#include "ConfigManager.hpp"
|
||||||
|
#include "../helpers/Log.hpp"
|
||||||
|
#include "../helpers/MiscFunctions.hpp"
|
||||||
#include <hyprutils/path/Path.hpp>
|
#include <hyprutils/path/Path.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <glob.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
static std::string getMainConfigPath() {
|
static std::string getMainConfigPath() {
|
||||||
static const auto paths = Hyprutils::Path::findConfig("hypridle");
|
static const auto paths = Hyprutils::Path::findConfig("hypridle");
|
||||||
|
|
@ -13,6 +17,20 @@ static std::string getMainConfigPath() {
|
||||||
CConfigManager::CConfigManager(std::string configPath) :
|
CConfigManager::CConfigManager(std::string configPath) :
|
||||||
m_config(configPath.empty() ? getMainConfigPath().c_str() : configPath.c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = false}) {
|
m_config(configPath.empty() ? getMainConfigPath().c_str() : configPath.c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = false}) {
|
||||||
;
|
;
|
||||||
|
configCurrentPath = configPath.empty() ? getMainConfigPath() : configPath;
|
||||||
|
configHeadPath = configCurrentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleSource(const char* c, const char* v) {
|
||||||
|
const std::string VALUE = v;
|
||||||
|
const std::string COMMAND = c;
|
||||||
|
|
||||||
|
const auto RESULT = g_pConfigManager->handleSource(COMMAND, VALUE);
|
||||||
|
|
||||||
|
Hyprlang::CParseResult result;
|
||||||
|
if (RESULT.has_value())
|
||||||
|
result.setError(RESULT.value().c_str());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::init() {
|
void CConfigManager::init() {
|
||||||
|
|
@ -20,6 +38,7 @@ void CConfigManager::init() {
|
||||||
m_config.addSpecialConfigValue("listener", "timeout", Hyprlang::INT{-1});
|
m_config.addSpecialConfigValue("listener", "timeout", Hyprlang::INT{-1});
|
||||||
m_config.addSpecialConfigValue("listener", "on-timeout", Hyprlang::STRING{""});
|
m_config.addSpecialConfigValue("listener", "on-timeout", Hyprlang::STRING{""});
|
||||||
m_config.addSpecialConfigValue("listener", "on-resume", Hyprlang::STRING{""});
|
m_config.addSpecialConfigValue("listener", "on-resume", Hyprlang::STRING{""});
|
||||||
|
m_config.addSpecialConfigValue("listener", "ignore_inhibit", Hyprlang::INT{0});
|
||||||
|
|
||||||
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{""});
|
||||||
|
|
@ -29,8 +48,14 @@ void CConfigManager::init() {
|
||||||
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:ignore_wayland_inhibit", Hyprlang::INT{0});
|
||||||
m_config.addConfigValue("general:inhibit_sleep", Hyprlang::INT{2});
|
m_config.addConfigValue("general:inhibit_sleep", Hyprlang::INT{2});
|
||||||
|
|
||||||
|
// track the file in the circular dependency chain
|
||||||
|
alreadyIncludedSourceFiles.insert(std::filesystem::canonical(configHeadPath));
|
||||||
|
|
||||||
|
m_config.registerHandler(&::handleSource, "source", {.allowFlags = false});
|
||||||
|
|
||||||
m_config.commence();
|
m_config.commence();
|
||||||
|
|
||||||
auto result = m_config.parse();
|
auto result = m_config.parse();
|
||||||
|
|
@ -62,6 +87,8 @@ Hyprlang::CParseResult CConfigManager::postParse() {
|
||||||
rule.onTimeout = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("listener", "on-timeout", k.c_str()));
|
rule.onTimeout = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("listener", "on-timeout", k.c_str()));
|
||||||
rule.onResume = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("listener", "on-resume", k.c_str()));
|
rule.onResume = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("listener", "on-resume", k.c_str()));
|
||||||
|
|
||||||
|
rule.ignoreInhibit = std::any_cast<Hyprlang::INT>(m_config.getSpecialConfigValue("listener", "ignore_inhibit", k.c_str()));
|
||||||
|
|
||||||
if (timeout == -1) {
|
if (timeout == -1) {
|
||||||
result.setError("Category has a missing timeout setting");
|
result.setError("Category has a missing timeout setting");
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -71,7 +98,8 @@ Hyprlang::CParseResult CConfigManager::postParse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& r : m_vRules) {
|
for (auto& r : m_vRules) {
|
||||||
Debug::log(LOG, "Registered timeout rule for {}s:\n on-timeout: {}\n on-resume: {}", r.timeout, r.onTimeout, r.onResume);
|
Debug::log(LOG, "Registered timeout rule for {}s:\n on-timeout: {}\n on-resume: {}\n ignore_inhibit: {}", r.timeout, r.onTimeout, r.onResume,
|
||||||
|
r.ignoreInhibit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -80,3 +108,56 @@ Hyprlang::CParseResult CConfigManager::postParse() {
|
||||||
std::vector<CConfigManager::STimeoutRule> CConfigManager::getRules() {
|
std::vector<CConfigManager::STimeoutRule> CConfigManager::getRules() {
|
||||||
return m_vRules;
|
return m_vRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> CConfigManager::handleSource(const std::string& command, const std::string& rawpath) {
|
||||||
|
if (rawpath.length() < 2) {
|
||||||
|
return "source path " + rawpath + " bogus!";
|
||||||
|
}
|
||||||
|
std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{new glob_t, [](glob_t* g) { globfree(g); }};
|
||||||
|
memset(glob_buf.get(), 0, sizeof(glob_t));
|
||||||
|
|
||||||
|
const auto CURRENTDIR = std::filesystem::path(configCurrentPath).parent_path().string();
|
||||||
|
|
||||||
|
if (auto r = glob(absolutePath(rawpath, CURRENTDIR).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) {
|
||||||
|
std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory");
|
||||||
|
Debug::log(ERR, "{}", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
|
||||||
|
const auto PATH = absolutePath(glob_buf->gl_pathv[i], CURRENTDIR);
|
||||||
|
|
||||||
|
if (PATH.empty() || PATH == configCurrentPath) {
|
||||||
|
Debug::log(WARN, "source= skipping invalid path");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::find(alreadyIncludedSourceFiles.begin(), alreadyIncludedSourceFiles.end(), PATH) != alreadyIncludedSourceFiles.end()) {
|
||||||
|
Debug::log(WARN, "source= skipping already included source file {} to prevent circular dependency", PATH);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::is_regular_file(PATH)) {
|
||||||
|
if (std::filesystem::exists(PATH)) {
|
||||||
|
Debug::log(WARN, "source= skipping non-file {}", PATH);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(ERR, "source= file doesnt exist");
|
||||||
|
return "source file " + PATH + " doesn't exist!";
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the file in the circular dependency chain
|
||||||
|
alreadyIncludedSourceFiles.insert(PATH);
|
||||||
|
|
||||||
|
// allow for nested config parsing
|
||||||
|
auto backupConfigPath = configCurrentPath;
|
||||||
|
configCurrentPath = PATH;
|
||||||
|
|
||||||
|
m_config.parseFile(PATH.c_str());
|
||||||
|
|
||||||
|
configCurrentPath = backupConfigPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <hyprlang.hpp>
|
#include <hyprlang.hpp>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -13,12 +14,16 @@ class CConfigManager {
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
struct STimeoutRule {
|
struct STimeoutRule {
|
||||||
uint64_t timeout = 0;
|
uint64_t timeout = 0;
|
||||||
std::string onTimeout = "";
|
std::string onTimeout = "";
|
||||||
std::string onResume = "";
|
std::string onResume = "";
|
||||||
|
bool ignoreInhibit = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<STimeoutRule> getRules();
|
std::vector<STimeoutRule> getRules();
|
||||||
|
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
||||||
|
std::string configCurrentPath, configHeadPath;
|
||||||
|
std::set<std::string> alreadyIncludedSourceFiles;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Hyprlang::CSimpleConfigValue<T> getValue(const std::string& name) {
|
Hyprlang::CSimpleConfigValue<T> getValue(const std::string& name) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#include "Hypridle.hpp"
|
#include "Hypridle.hpp"
|
||||||
#include "../helpers/Log.hpp"
|
#include "../helpers/Log.hpp"
|
||||||
#include "../config/ConfigManager.hpp"
|
#include "../config/ConfigManager.hpp"
|
||||||
|
|
@ -54,18 +55,27 @@ void CHypridle::run() {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto RULES = g_pConfigManager->getRules();
|
static const auto IGNOREWAYLANDINHIBIT = g_pConfigManager->getValue<Hyprlang::INT>("general:ignore_wayland_inhibit");
|
||||||
|
|
||||||
|
const auto RULES = g_pConfigManager->getRules();
|
||||||
m_sWaylandIdleState.listeners.resize(RULES.size());
|
m_sWaylandIdleState.listeners.resize(RULES.size());
|
||||||
|
|
||||||
Debug::log(LOG, "found {} rules", RULES.size());
|
Debug::log(LOG, "found {} rules", RULES.size());
|
||||||
|
|
||||||
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.onRestore = r.onResume;
|
l.onRestore = r.onResume;
|
||||||
l.onTimeout = r.onTimeout;
|
l.onTimeout = r.onTimeout;
|
||||||
|
l.ignoreInhibit = r.ignoreInhibit;
|
||||||
|
|
||||||
|
if (*IGNOREWAYLANDINHIBIT || r.ignoreInhibit)
|
||||||
|
l.notification =
|
||||||
|
makeShared<CCExtIdleNotificationV1>(m_sWaylandIdleState.notifier->sendGetInputIdleNotification(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));
|
||||||
|
else
|
||||||
|
l.notification =
|
||||||
|
makeShared<CCExtIdleNotificationV1>(m_sWaylandIdleState.notifier->sendGetIdleNotification(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));
|
||||||
|
|
||||||
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->setData(&m_sWaylandIdleState.listeners[i]);
|
||||||
|
|
||||||
l.notification->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
|
l.notification->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
|
||||||
|
|
@ -248,7 +258,7 @@ static void spawn(const std::string& args) {
|
||||||
void CHypridle::onIdled(SIdleListener* pListener) {
|
void CHypridle::onIdled(SIdleListener* pListener) {
|
||||||
Debug::log(LOG, "Idled: rule {:x}", (uintptr_t)pListener);
|
Debug::log(LOG, "Idled: rule {:x}", (uintptr_t)pListener);
|
||||||
isIdled = true;
|
isIdled = true;
|
||||||
if (g_pHypridle->m_iInhibitLocks > 0) {
|
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
|
||||||
Debug::log(LOG, "Ignoring from onIdled(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
|
Debug::log(LOG, "Ignoring from onIdled(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +275,7 @@ void CHypridle::onIdled(SIdleListener* pListener) {
|
||||||
void CHypridle::onResumed(SIdleListener* pListener) {
|
void CHypridle::onResumed(SIdleListener* pListener) {
|
||||||
Debug::log(LOG, "Resumed: rule {:x}", (uintptr_t)pListener);
|
Debug::log(LOG, "Resumed: rule {:x}", (uintptr_t)pListener);
|
||||||
isIdled = false;
|
isIdled = false;
|
||||||
if (g_pHypridle->m_iInhibitLocks > 0) {
|
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
|
||||||
Debug::log(LOG, "Ignoring from onResumed(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
|
Debug::log(LOG, "Ignoring from onResumed(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -288,16 +298,22 @@ void CHypridle::onInhibit(bool lock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_iInhibitLocks == 0 && isIdled) {
|
if (m_iInhibitLocks == 0 && isIdled) {
|
||||||
const auto RULES = g_pConfigManager->getRules();
|
static const auto IGNOREWAYLANDINHIBIT = g_pConfigManager->getValue<Hyprlang::INT>("general:ignore_wayland_inhibit");
|
||||||
|
|
||||||
|
const auto RULES = g_pConfigManager->getRules();
|
||||||
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->sendDestroy();
|
l.notification->sendDestroy();
|
||||||
|
|
||||||
l.notification =
|
if (*IGNOREWAYLANDINHIBIT || r.ignoreInhibit)
|
||||||
makeShared<CCExtIdleNotificationV1>(m_sWaylandIdleState.notifier->sendGetIdleNotification(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));
|
l.notification =
|
||||||
|
makeShared<CCExtIdleNotificationV1>(m_sWaylandIdleState.notifier->sendGetInputIdleNotification(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));
|
||||||
|
else
|
||||||
|
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->setData(&m_sWaylandIdleState.listeners[i]);
|
||||||
|
|
||||||
l.notification->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
|
l.notification->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
|
||||||
|
|
@ -313,7 +329,7 @@ void CHypridle::onLocked() {
|
||||||
m_isLocked = true;
|
m_isLocked = true;
|
||||||
|
|
||||||
static const auto LOCKCMD = g_pConfigManager->getValue<Hyprlang::STRING>("general:on_lock_cmd");
|
static const auto LOCKCMD = g_pConfigManager->getValue<Hyprlang::STRING>("general:on_lock_cmd");
|
||||||
if (*LOCKCMD)
|
if (!std::string{*LOCKCMD}.empty())
|
||||||
spawn(*LOCKCMD);
|
spawn(*LOCKCMD);
|
||||||
|
|
||||||
if (m_inhibitSleepBehavior == SLEEP_INHIBIT_LOCK_NOTIFY)
|
if (m_inhibitSleepBehavior == SLEEP_INHIBIT_LOCK_NOTIFY)
|
||||||
|
|
@ -328,7 +344,7 @@ void CHypridle::onUnlocked() {
|
||||||
inhibitSleep();
|
inhibitSleep();
|
||||||
|
|
||||||
static const auto UNLOCKCMD = g_pConfigManager->getValue<Hyprlang::STRING>("general:on_unlock_cmd");
|
static const auto UNLOCKCMD = g_pConfigManager->getValue<Hyprlang::STRING>("general:on_unlock_cmd");
|
||||||
if (*UNLOCKCMD)
|
if (!std::string{*UNLOCKCMD}.empty())
|
||||||
spawn(*UNLOCKCMD);
|
spawn(*UNLOCKCMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,15 +371,8 @@ bool CHypridle::unregisterDbusInhibitCookie(const CHypridle::SDbusInhibitCookie&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CHypridle::unregisterDbusInhibitCookies(const std::string& ownerID) {
|
size_t CHypridle::unregisterDbusInhibitCookies(const std::string& ownerID) {
|
||||||
const auto IT = std::remove_if(m_sDBUSState.inhibitCookies.begin(), m_sDBUSState.inhibitCookies.end(),
|
return std::erase_if(m_sDBUSState.inhibitCookies, [&ownerID](const CHypridle::SDbusInhibitCookie& item) { return item.ownerID == ownerID; });
|
||||||
[&ownerID](const CHypridle::SDbusInhibitCookie& item) { return item.ownerID == ownerID; });
|
|
||||||
|
|
||||||
if (IT == m_sDBUSState.inhibitCookies.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_sDBUSState.inhibitCookies.erase(IT, m_sDBUSState.inhibitCookies.end());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDbusLogin(sdbus::Message msg) {
|
static void handleDbusLogin(sdbus::Message msg) {
|
||||||
|
|
@ -445,6 +454,7 @@ static void handleDbusBlockInhibitsPropertyChanged(sdbus::Message msg) {
|
||||||
|
|
||||||
static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint32_t cookie, bool inhibit, const char* sender) {
|
static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint32_t cookie, bool inhibit, const char* sender) {
|
||||||
std::string ownerID = sender;
|
std::string ownerID = sender;
|
||||||
|
bool cookieFound = false;
|
||||||
|
|
||||||
if (!inhibit) {
|
if (!inhibit) {
|
||||||
Debug::log(TRACE, "Read uninhibit cookie: {}", cookie);
|
Debug::log(TRACE, "Read uninhibit cookie: {}", cookie);
|
||||||
|
|
@ -455,6 +465,7 @@ static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint3
|
||||||
app = COOKIE.app;
|
app = COOKIE.app;
|
||||||
reason = COOKIE.reason;
|
reason = COOKIE.reason;
|
||||||
ownerID = COOKIE.ownerID;
|
ownerID = COOKIE.ownerID;
|
||||||
|
cookieFound = true;
|
||||||
|
|
||||||
if (!g_pHypridle->unregisterDbusInhibitCookie(COOKIE))
|
if (!g_pHypridle->unregisterDbusInhibitCookie(COOKIE))
|
||||||
Debug::log(WARN, "BUG THIS: attempted to unregister unknown cookie");
|
Debug::log(WARN, "BUG THIS: attempted to unregister unknown cookie");
|
||||||
|
|
@ -465,7 +476,7 @@ static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint3
|
||||||
|
|
||||||
if (inhibit)
|
if (inhibit)
|
||||||
g_pHypridle->onInhibit(true);
|
g_pHypridle->onInhibit(true);
|
||||||
else
|
else if (cookieFound)
|
||||||
g_pHypridle->onInhibit(false);
|
g_pHypridle->onInhibit(false);
|
||||||
|
|
||||||
static uint32_t cookieID = 1337;
|
static uint32_t cookieID = 1337;
|
||||||
|
|
@ -490,9 +501,11 @@ static void handleDbusNameOwnerChanged(sdbus::Message msg) {
|
||||||
if (!newOwner.empty())
|
if (!newOwner.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_pHypridle->unregisterDbusInhibitCookies(oldOwner)) {
|
size_t removed = g_pHypridle->unregisterDbusInhibitCookies(oldOwner);
|
||||||
|
if (removed > 0) {
|
||||||
Debug::log(LOG, "App with owner {} disconnected", oldOwner);
|
Debug::log(LOG, "App with owner {} disconnected", oldOwner);
|
||||||
g_pHypridle->onInhibit(false);
|
for (size_t i = 0; i < removed; i++)
|
||||||
|
g_pHypridle->onInhibit(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -551,7 +564,13 @@ void CHypridle::setupDBUS() {
|
||||||
|
|
||||||
m_sDBUSState.screenSaverServiceConnection->addMatch("type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'",
|
m_sDBUSState.screenSaverServiceConnection->addMatch("type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'",
|
||||||
::handleDbusNameOwnerChanged);
|
::handleDbusNameOwnerChanged);
|
||||||
} catch (std::exception& e) { Debug::log(ERR, "Couldn't connect to session dbus\nerr: {}", e.what()); }
|
} catch (sdbus::Error& e) {
|
||||||
|
if (e.getName() == sdbus::Error::Name{"org.freedesktop.DBus.Error.FileExists"}) {
|
||||||
|
Debug::log(ERR, "Another service is already providing the org.freedesktop.ScreenSaver interface");
|
||||||
|
Debug::log(ERR, "Is hypridle already running?");
|
||||||
|
} else
|
||||||
|
Debug::log(ERR, "Failed to connect to ScreenSaver service\nerr: {}", e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
systemConnection.reset();
|
systemConnection.reset();
|
||||||
|
|
@ -570,6 +589,11 @@ void CHypridle::handleInhibitOnDbusSleep(bool toSleep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHypridle::inhibitSleep() {
|
void CHypridle::inhibitSleep() {
|
||||||
|
if (!m_sDBUSState.login) {
|
||||||
|
Debug::log(WARN, "Can't inhibit sleep. Dbus logind interface is not available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_sDBUSState.sleepInhibitFd.isValid()) {
|
if (m_sDBUSState.sleepInhibitFd.isValid()) {
|
||||||
Debug::log(WARN, "Called inhibitSleep, but previous sleep inhibitor is still active!");
|
Debug::log(WARN, "Called inhibitSleep, but previous sleep inhibitor is still active!");
|
||||||
m_sDBUSState.sleepInhibitFd.reset();
|
m_sDBUSState.sleepInhibitFd.reset();
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@ class CHypridle {
|
||||||
CHypridle();
|
CHypridle();
|
||||||
|
|
||||||
struct SIdleListener {
|
struct SIdleListener {
|
||||||
SP<CCExtIdleNotificationV1> notification = nullptr;
|
SP<CCExtIdleNotificationV1> notification = nullptr;
|
||||||
std::string onTimeout = "";
|
std::string onTimeout = "";
|
||||||
std::string onRestore = "";
|
std::string onRestore = "";
|
||||||
|
bool ignoreInhibit = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SDbusInhibitCookie {
|
struct SDbusInhibitCookie {
|
||||||
|
|
@ -43,7 +44,7 @@ class CHypridle {
|
||||||
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);
|
size_t unregisterDbusInhibitCookies(const std::string& ownerID);
|
||||||
|
|
||||||
void handleInhibitOnDbusSleep(bool toSleep);
|
void handleInhibitOnDbusSleep(bool toSleep);
|
||||||
void inhibitSleep();
|
void inhibitSleep();
|
||||||
|
|
|
||||||
19
src/helpers/MiscFunctions.cpp
Normal file
19
src/helpers/MiscFunctions.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include "MiscFunctions.hpp"
|
||||||
|
|
||||||
|
std::string absolutePath(const std::string& rawpath, const std::string& currentDir) {
|
||||||
|
std::filesystem::path path(rawpath);
|
||||||
|
|
||||||
|
// Handling where rawpath starts with '~'
|
||||||
|
if (!rawpath.empty() && rawpath[0] == '~') {
|
||||||
|
static const char* const ENVHOME = getenv("HOME");
|
||||||
|
path = std::filesystem::path(ENVHOME) / path.relative_path().string().substr(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling e.g. ./, ../
|
||||||
|
if (path.is_relative())
|
||||||
|
return std::filesystem::weakly_canonical(std::filesystem::path(currentDir) / path);
|
||||||
|
else
|
||||||
|
return std::filesystem::weakly_canonical(path);
|
||||||
|
}
|
||||||
5
src/helpers/MiscFunctions.hpp
Normal file
5
src/helpers/MiscFunctions.hpp
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string absolutePath(const std::string&, const std::string&);
|
||||||
12
src/main.cpp
12
src/main.cpp
|
|
@ -37,6 +37,18 @@ int main(int argc, char** argv, char** envp) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (arg == "--help" || arg == "-h") {
|
||||||
|
Debug::log(NONE,
|
||||||
|
"Usage: hypridle [options]\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -v, --verbose Enable verbose logging\n"
|
||||||
|
" -q, --quiet Suppress all output except errors\n"
|
||||||
|
" -V, --version Show version information\n"
|
||||||
|
" -c, --config <path> Specify a custom config file path\n"
|
||||||
|
" -h, --help Show this help message");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue