Compare commits

..

No commits in common. "main" and "v0.1.6" have entirely different histories.
main ... v0.1.6

14 changed files with 76 additions and 236 deletions

View file

@ -1,12 +1,12 @@
WarningsAsErrors: '*'
HeaderFilterRegex: '.*\.hpp'
FormatStyle: 'file'
FormatStyle: file
Checks: >
-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-forward-declaration-namespace,
-bugprone-forward-declaration-namespace,
-bugprone-forward-declararion-namespace,
-bugprone-forward-declararion-namespace,
-bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
-bugprone-branch-clone,

View file

@ -7,35 +7,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- 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
- uses: DeterminateSystems/nix-installer-action@main
# not needed (yet)
# - uses: cachix/cachix-action@v12

View file

@ -34,7 +34,6 @@ will make those events ignored.
## Dependencies
- wayland
- wayland-protocols
- hyprland-protocols
- hyprlang >= 0.4.0
- sdbus-c++
- hyprwayland-scanner
@ -43,8 +42,8 @@ will make those events ignored.
### Building:
```sh
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -S . -B ./build
cmake --build ./build --config Release --target hypridle -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF`
```
### Installation:

View file

@ -1 +1 @@
0.1.7
0.1.6

32
flake.lock generated
View file

@ -10,11 +10,11 @@
]
},
"locked": {
"lastModified": 1765214753,
"narHash": "sha256-P9zdGXOzToJJgu5sVjv7oeOGPIIwrd9hAUAP3PsmBBs=",
"lastModified": 1737556638,
"narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "3f3860b869014c00e8b9e0528c7b4ddc335c21ab",
"rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5",
"type": "github"
},
"original": {
@ -36,11 +36,13 @@
]
},
"locked": {
"lastModified": 1764612430,
"narHash": "sha256-54ltTSbI6W+qYGMchAgCR6QnC1kOdKXN6X6pJhOWxFg=",
"lastModified": 1734364628,
"narHash": "sha256-ii8fzJfI953n/EmIxVvq64ZAwhvwuuPHWfGd61/mJG8=",
"lastModified": 1737634606,
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "0d00dc118981531aa731150b6ea551ef037acddd",
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
"type": "github"
},
"original": {
@ -59,11 +61,11 @@
]
},
"locked": {
"lastModified": 1766160771,
"narHash": "sha256-roINUGikWRqqgKrD4iotKbGj3ZKJl3hjMz5l/SyKrHw=",
"lastModified": 1737632363,
"narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "5ac060bfcf2f12b3a6381156ebbc13826a05b09f",
"rev": "006620eb29d54ea9086538891404c78563d1bae1",
"type": "github"
},
"original": {
@ -82,11 +84,11 @@
]
},
"locked": {
"lastModified": 1763640274,
"narHash": "sha256-Uan1Nl9i4TF/kyFoHnTq1bd/rsWh4GAK/9/jDqLbY5A=",
"lastModified": 1735493474,
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "f6cf414ca0e16a4d30198fd670ec86df3c89f671",
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
"type": "github"
},
"original": {
@ -97,11 +99,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1766070988,
"narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=",
"lastModified": 1737469691,
"narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c6245e83d836d0433170a16eb185cefe0572f8b8",
"rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab",
"type": "github"
},
"original": {

View file

@ -6,7 +6,7 @@
hyprwayland-scanner,
lib,
pkg-config,
sdbus-cpp_2,
sdbus-cpp,
stdenv,
systemd,
wayland,
@ -30,7 +30,7 @@ stdenv.mkDerivation {
hyprland-protocols
hyprlang
hyprutils
sdbus-cpp_2
sdbus-cpp
systemd
wayland
wayland-protocols

View file

@ -17,12 +17,26 @@ in {
inputs.hyprlang.overlays.default
inputs.hyprutils.overlays.default
inputs.hyprwayland-scanner.overlays.default
inputs.self.overlays.sdbuscpp
(final: prev: {
hypridle = prev.callPackage ./default.nix {
stdenv = prev.gcc15Stdenv;
stdenv = prev.gcc14Stdenv;
version = version + "+date=" + (mkDate (inputs.self.lastModifiedDate or "19700101")) + "_" + (inputs.self.shortRev or "dirty");
inherit (final) hyprlang;
};
})
];
sdbuscpp = final: prev: {
sdbus-cpp = prev.sdbus-cpp.overrideAttrs (self: super: {
version = "2.0.0";
src = final.fetchFromGitHub {
owner = "Kistler-group";
repo = "sdbus-cpp";
rev = "refs/tags/v${self.version}";
hash = "sha256-W8V5FRhV3jtERMFrZ4gf30OpIQLYoj2yYGpnYOmH2+g=";
};
});
};
}

View file

@ -1,10 +1,6 @@
#include "ConfigManager.hpp"
#include "../helpers/Log.hpp"
#include "../helpers/MiscFunctions.hpp"
#include <hyprutils/path/Path.hpp>
#include <filesystem>
#include <glob.h>
#include <cstring>
static std::string getMainConfigPath() {
static const auto paths = Hyprutils::Path::findConfig("hypridle");
@ -17,20 +13,6 @@ static std::string getMainConfigPath() {
CConfigManager::CConfigManager(std::string configPath) :
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() {
@ -38,7 +20,6 @@ void CConfigManager::init() {
m_config.addSpecialConfigValue("listener", "timeout", Hyprlang::INT{-1});
m_config.addSpecialConfigValue("listener", "on-timeout", 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:unlock_cmd", Hyprlang::STRING{""});
@ -48,14 +29,8 @@ void CConfigManager::init() {
m_config.addConfigValue("general:after_sleep_cmd", Hyprlang::STRING{""});
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_wayland_inhibit", Hyprlang::INT{0});
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();
auto result = m_config.parse();
@ -87,8 +62,6 @@ Hyprlang::CParseResult CConfigManager::postParse() {
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.ignoreInhibit = std::any_cast<Hyprlang::INT>(m_config.getSpecialConfigValue("listener", "ignore_inhibit", k.c_str()));
if (timeout == -1) {
result.setError("Category has a missing timeout setting");
continue;
@ -98,8 +71,7 @@ Hyprlang::CParseResult CConfigManager::postParse() {
}
for (auto& r : m_vRules) {
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);
Debug::log(LOG, "Registered timeout rule for {}s:\n on-timeout: {}\n on-resume: {}", r.timeout, r.onTimeout, r.onResume);
}
return result;
@ -108,56 +80,3 @@ Hyprlang::CParseResult CConfigManager::postParse() {
std::vector<CConfigManager::STimeoutRule> CConfigManager::getRules() {
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 {};
}

View file

@ -4,7 +4,6 @@
#include <hyprlang.hpp>
#include <set>
#include <vector>
#include <memory>
@ -14,16 +13,12 @@ class CConfigManager {
void init();
struct STimeoutRule {
uint64_t timeout = 0;
std::string onTimeout = "";
std::string onResume = "";
bool ignoreInhibit = false;
uint64_t timeout = 0;
std::string onTimeout = "";
std::string onResume = "";
};
std::vector<STimeoutRule> getRules();
std::optional<std::string> handleSource(const std::string&, const std::string&);
std::string configCurrentPath, configHeadPath;
std::set<std::string> alreadyIncludedSourceFiles;
std::vector<STimeoutRule> getRules();
template <typename T>
Hyprlang::CSimpleConfigValue<T> getValue(const std::string& name) {

View file

@ -1,4 +1,3 @@
#include "Hypridle.hpp"
#include "../helpers/Log.hpp"
#include "../config/ConfigManager.hpp"
@ -55,27 +54,18 @@ void CHypridle::run() {
exit(1);
}
static const auto IGNOREWAYLANDINHIBIT = g_pConfigManager->getValue<Hyprlang::INT>("general:ignore_wayland_inhibit");
const auto RULES = g_pConfigManager->getRules();
const auto RULES = g_pConfigManager->getRules();
m_sWaylandIdleState.listeners.resize(RULES.size());
Debug::log(LOG, "found {} rules", RULES.size());
for (size_t i = 0; i < RULES.size(); ++i) {
auto& l = m_sWaylandIdleState.listeners[i];
const auto& r = RULES[i];
l.onRestore = r.onResume;
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()));
auto& l = m_sWaylandIdleState.listeners[i];
const auto& r = RULES[i];
l.onRestore = r.onResume;
l.onTimeout = r.onTimeout;
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()); });
@ -258,7 +248,7 @@ static void spawn(const std::string& args) {
void CHypridle::onIdled(SIdleListener* pListener) {
Debug::log(LOG, "Idled: rule {:x}", (uintptr_t)pListener);
isIdled = true;
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
if (g_pHypridle->m_iInhibitLocks > 0) {
Debug::log(LOG, "Ignoring from onIdled(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
return;
}
@ -275,7 +265,7 @@ void CHypridle::onIdled(SIdleListener* pListener) {
void CHypridle::onResumed(SIdleListener* pListener) {
Debug::log(LOG, "Resumed: rule {:x}", (uintptr_t)pListener);
isIdled = false;
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
if (g_pHypridle->m_iInhibitLocks > 0) {
Debug::log(LOG, "Ignoring from onResumed(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
return;
}
@ -298,22 +288,16 @@ void CHypridle::onInhibit(bool lock) {
}
if (m_iInhibitLocks == 0 && isIdled) {
static const auto IGNOREWAYLANDINHIBIT = g_pConfigManager->getValue<Hyprlang::INT>("general:ignore_wayland_inhibit");
const auto RULES = g_pConfigManager->getRules();
const auto RULES = g_pConfigManager->getRules();
for (size_t i = 0; i < RULES.size(); ++i) {
auto& l = m_sWaylandIdleState.listeners[i];
const auto& r = RULES[i];
l.notification->sendDestroy();
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->setIdled([this](CCExtIdleNotificationV1* n) { onIdled((CHypridle::SIdleListener*)n->data()); });
@ -329,7 +313,7 @@ void CHypridle::onLocked() {
m_isLocked = true;
static const auto LOCKCMD = g_pConfigManager->getValue<Hyprlang::STRING>("general:on_lock_cmd");
if (!std::string{*LOCKCMD}.empty())
if (*LOCKCMD)
spawn(*LOCKCMD);
if (m_inhibitSleepBehavior == SLEEP_INHIBIT_LOCK_NOTIFY)
@ -344,7 +328,7 @@ void CHypridle::onUnlocked() {
inhibitSleep();
static const auto UNLOCKCMD = g_pConfigManager->getValue<Hyprlang::STRING>("general:on_unlock_cmd");
if (!std::string{*UNLOCKCMD}.empty())
if (*UNLOCKCMD)
spawn(*UNLOCKCMD);
}
@ -371,8 +355,15 @@ bool CHypridle::unregisterDbusInhibitCookie(const CHypridle::SDbusInhibitCookie&
return true;
}
size_t CHypridle::unregisterDbusInhibitCookies(const std::string& ownerID) {
return std::erase_if(m_sDBUSState.inhibitCookies, [&ownerID](const CHypridle::SDbusInhibitCookie& item) { return item.ownerID == ownerID; });
bool CHypridle::unregisterDbusInhibitCookies(const std::string& ownerID) {
const auto IT = std::remove_if(m_sDBUSState.inhibitCookies.begin(), m_sDBUSState.inhibitCookies.end(),
[&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) {
@ -454,7 +445,6 @@ static void handleDbusBlockInhibitsPropertyChanged(sdbus::Message msg) {
static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint32_t cookie, bool inhibit, const char* sender) {
std::string ownerID = sender;
bool cookieFound = false;
if (!inhibit) {
Debug::log(TRACE, "Read uninhibit cookie: {}", cookie);
@ -465,7 +455,6 @@ static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint3
app = COOKIE.app;
reason = COOKIE.reason;
ownerID = COOKIE.ownerID;
cookieFound = true;
if (!g_pHypridle->unregisterDbusInhibitCookie(COOKIE))
Debug::log(WARN, "BUG THIS: attempted to unregister unknown cookie");
@ -476,7 +465,7 @@ static uint32_t handleDbusScreensaver(std::string app, std::string reason, uint3
if (inhibit)
g_pHypridle->onInhibit(true);
else if (cookieFound)
else
g_pHypridle->onInhibit(false);
static uint32_t cookieID = 1337;
@ -501,11 +490,9 @@ static void handleDbusNameOwnerChanged(sdbus::Message msg) {
if (!newOwner.empty())
return;
size_t removed = g_pHypridle->unregisterDbusInhibitCookies(oldOwner);
if (removed > 0) {
if (g_pHypridle->unregisterDbusInhibitCookies(oldOwner)) {
Debug::log(LOG, "App with owner {} disconnected", oldOwner);
for (size_t i = 0; i < removed; i++)
g_pHypridle->onInhibit(false);
g_pHypridle->onInhibit(false);
}
}
@ -564,13 +551,7 @@ void CHypridle::setupDBUS() {
m_sDBUSState.screenSaverServiceConnection->addMatch("type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'",
::handleDbusNameOwnerChanged);
} 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());
}
} catch (std::exception& e) { Debug::log(ERR, "Couldn't connect to session dbus\nerr: {}", e.what()); }
}
systemConnection.reset();
@ -589,11 +570,6 @@ void CHypridle::handleInhibitOnDbusSleep(bool toSleep) {
}
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()) {
Debug::log(WARN, "Called inhibitSleep, but previous sleep inhibitor is still active!");
m_sDBUSState.sleepInhibitFd.reset();

View file

@ -17,10 +17,9 @@ class CHypridle {
CHypridle();
struct SIdleListener {
SP<CCExtIdleNotificationV1> notification = nullptr;
std::string onTimeout = "";
std::string onRestore = "";
bool ignoreInhibit = false;
SP<CCExtIdleNotificationV1> notification = nullptr;
std::string onTimeout = "";
std::string onRestore = "";
};
struct SDbusInhibitCookie {
@ -44,7 +43,7 @@ class CHypridle {
SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie);
void registerDbusInhibitCookie(SDbusInhibitCookie& cookie);
bool unregisterDbusInhibitCookie(const SDbusInhibitCookie& cookie);
size_t unregisterDbusInhibitCookies(const std::string& ownerID);
bool unregisterDbusInhibitCookies(const std::string& ownerID);
void handleInhibitOnDbusSleep(bool toSleep);
void inhibitSleep();

View file

@ -1,19 +0,0 @@
#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);
}

View file

@ -1,5 +0,0 @@
#pragma once
#include <string>
std::string absolutePath(const std::string&, const std::string&);

View file

@ -37,18 +37,6 @@ int main(int argc, char** argv, char** envp) {
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 {