core: force update labels on `SIGUSR2` (#169)

* core: force update labels on `SIGUSR2`

* allow 0ms and force
This commit is contained in:
bvr-yr 2024-03-11 00:38:01 +03:00 committed by GitHub
parent 0f44f76368
commit 066e0ae88f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 53 additions and 19 deletions

View File

@ -1,7 +1,8 @@
#include "Timer.hpp"
CTimer::CTimer(std::chrono::system_clock::duration timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data_) : cb(cb_), data(data_) {
expires = std::chrono::system_clock::now() + timeout;
CTimer::CTimer(std::chrono::system_clock::duration timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data_, bool force) : cb(cb_), data(data_) {
expires = std::chrono::system_clock::now() + timeout;
allowForceUpdate = force;
}
bool CTimer::passed() {
@ -22,4 +23,8 @@ void CTimer::call(std::shared_ptr<CTimer> self) {
float CTimer::leftMs() {
return std::chrono::duration_cast<std::chrono::milliseconds>(expires - std::chrono::system_clock::now()).count();
}
}
bool CTimer::canForceUpdate() {
return allowForceUpdate;
}

View File

@ -5,10 +5,11 @@
class CTimer {
public:
CTimer(std::chrono::system_clock::duration timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data_);
CTimer(std::chrono::system_clock::duration timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data_, bool force);
void cancel();
bool passed();
bool canForceUpdate();
float leftMs();
@ -19,5 +20,6 @@ class CTimer {
std::function<void(std::shared_ptr<CTimer> self, void* data)> cb;
void* data = nullptr;
std::chrono::system_clock::time_point expires;
bool wasCancelled = false;
};
bool wasCancelled = false;
bool allowForceUpdate = false;
};

View File

@ -307,6 +307,17 @@ static void handleUnlockSignal(int sig) {
}
}
static void handleForceUpdateSignal(int sig) {
if (sig == SIGUSR2) {
for (auto& t : g_pHyprlock->getTimers()) {
if (t->canForceUpdate()) {
t->call(t);
t->cancel();
}
}
}
}
static void handlePollTerminate(int sig) {
;
}
@ -355,7 +366,8 @@ void CHyprlock::run() {
lockSession();
registerSignalAction(SIGUSR1, handleUnlockSignal, SA_RESTART);
registerSignalAction(SIGUSR2, handlePollTerminate);
registerSignalAction(SIGUSR2, handleForceUpdateSignal);
registerSignalAction(SIGRTMIN, handlePollTerminate);
registerSignalAction(SIGSEGV, handleCriticalSignal);
registerSignalAction(SIGABRT, handleCriticalSignal);
@ -371,7 +383,7 @@ void CHyprlock::run() {
int ret = poll(pollfds, 1, 5000 /* 5 seconds, reasonable. Just in case we need to terminate and the signal fails */);
if (ret < 0) {
if (errno == EINTR)
if (errno == EINTR)
continue;
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
@ -493,7 +505,7 @@ void CHyprlock::run() {
wl_display_disconnect(m_sWaylandState.display);
pthread_kill(pollThr.native_handle(), SIGUSR2);
pthread_kill(pollThr.native_handle(), SIGRTMIN);
// wait for threads to exit cleanly to avoid a coredump
pollThr.join();
@ -834,14 +846,19 @@ size_t CHyprlock::getPasswordFailedAttempts() {
return m_sPasswordState.failedAttempts;
}
std::shared_ptr<CTimer> CHyprlock::addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data) {
std::shared_ptr<CTimer> CHyprlock::addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data,
bool force) {
std::lock_guard<std::mutex> lg(m_sLoopState.timersMutex);
const auto T = m_vTimers.emplace_back(std::make_shared<CTimer>(timeout, cb_, data));
const auto T = m_vTimers.emplace_back(std::make_shared<CTimer>(timeout, cb_, data, force));
m_sLoopState.timerEvent = true;
m_sLoopState.timerCV.notify_all();
return T;
}
std::vector<std::shared_ptr<CTimer>> CHyprlock::getTimers() {
return m_vTimers;
}
void CHyprlock::spawnAsync(const std::string& args) {
Debug::log(LOG, "Executing (async) {}", args);

View File

@ -35,7 +35,8 @@ class CHyprlock {
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
void onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
std::shared_ptr<CTimer> addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data);
std::shared_ptr<CTimer> addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data,
bool force = false);
void onLockLocked();
void onLockFinished();
@ -83,6 +84,7 @@ class CHyprlock {
Vector2D m_vLastEnterCoords = {};
std::vector<std::unique_ptr<COutput>> m_vOutputs;
std::vector<std::shared_ptr<CTimer>> getTimers();
struct {
void* linuxDmabuf = nullptr;

View File

@ -79,6 +79,11 @@ IWidget::SFormatResult IWidget::formatString(std::string in) {
for (const auto& v : vars) {
if (v.starts_with("update:")) {
try {
if (v.substr(7).contains(':')) {
auto str = v.substr(v.substr(7).find_first_of(':') + 8);
result.allowForceUpdate = str == "true" || std::stoull(str) == 1;
}
result.updateEveryMs = std::stoull(v.substr(7));
} catch (std::exception& e) { Debug::log(ERR, "Error parsing {} in cmd[]", v); }
} else {
@ -93,4 +98,4 @@ IWidget::SFormatResult IWidget::formatString(std::string in) {
result.formatted = in;
return result;
}
}

View File

@ -15,10 +15,11 @@ class IWidget {
struct SFormatResult {
std::string formatted;
float updateEveryMs = 0; // 0 means don't (static)
bool alwaysUpdate = false;
bool cmd = false;
float updateEveryMs = 0; // 0 means don't (static)
bool alwaysUpdate = false;
bool cmd = false;
bool allowForceUpdate = false;
};
virtual SFormatResult formatString(std::string in);
};
};

View File

@ -53,7 +53,9 @@ void CLabel::onTimerUpdate() {
void CLabel::plantTimer() {
if (label.updateEveryMs != 0)
labelTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)label.updateEveryMs), onTimer, this);
labelTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)label.updateEveryMs), onTimer, this, label.allowForceUpdate);
else if (label.updateEveryMs == 0 && label.allowForceUpdate)
labelTimer = g_pHyprlock->addTimer(std::chrono::hours(1), onTimer, this, true);
}
CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props, const std::string& output) :
@ -139,4 +141,4 @@ void CLabel::renderSuper() {
if (!pendingResourceID.empty()) /* did not consume the pending resource */
g_pHyprlock->addTimer(std::chrono::milliseconds(100), onAssetCallbackTimer, this);
}
}