core: more obvious api around isUnlocked related logic

This commit is contained in:
Maximilian Seidler 2026-04-29 19:20:09 +02:00
parent 927e09fb7d
commit 05ea55fd9c
10 changed files with 51 additions and 37 deletions

View file

@ -77,7 +77,7 @@ void CAuth::terminate() {
}
static void unlockCallback(ASP<CTimer> self, void* data) {
g_pHyprlock->unlock();
g_pHyprlock->fadeOutAndUnlock();
}
void CAuth::enqueueUnlock() {

View file

@ -37,7 +37,7 @@ int conv(int num_msg, const struct pam_message** msg, struct pam_response** resp
}
// Needed for unlocks via SIGUSR1
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isFadingOutOrTerminating())
return PAM_CONV_ERR;
pamReply[i].resp = strdup(CONVERSATIONSTATE->input.c_str());
@ -83,13 +83,13 @@ void CPam::init() {
resetConversation();
// For grace or SIGUSR1 unlocks
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isFadingOutOrTerminating())
return;
const auto AUTHENTICATED = auth();
// For SIGUSR1 unlocks
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isFadingOutOrTerminating())
return;
if (!AUTHENTICATED)
@ -143,7 +143,7 @@ void CPam::waitForInput() {
m_bBlockInput = false;
m_sConversationState.waitingForPamAuth = false;
m_sConversationState.inputRequested = true;
m_sConversationState.inputSubmittedCondition.wait(lk, [this] { return !m_sConversationState.inputRequested || g_pHyprlock->m_bTerminate; });
m_sConversationState.inputSubmittedCondition.wait(lk, [this] { return !m_sConversationState.inputRequested || g_pHyprlock->isFadingOutOrTerminating(); });
m_bBlockInput = true;
}

View file

@ -17,8 +17,8 @@ CSessionLockSurface::~CSessionLockSurface() {
wl_egl_window_destroy(eglWindow);
}
CSessionLockSurface::CSessionLockSurface(const SP<COutput>& pOutput) : m_outputRef(pOutput), m_outputID(pOutput->m_ID) {
surface = makeShared<CCWlSurface>(g_pHyprlock->getCompositor()->sendCreateSurface());
CSessionLockSurface::CSessionLockSurface(const SP<COutput>& pOutput) :
m_outputRef(pOutput), m_outputID(pOutput->m_ID), surface(makeShared<CCWlSurface>(g_pHyprlock->getCompositor()->sendCreateSurface())) {
RASSERT(surface, "Couldn't create wl_surface");
static const auto FRACTIONALSCALING = g_pConfigManager->getValue<Hyprlang::INT>("general:fractional_scaling");
@ -131,7 +131,7 @@ void CSessionLockSurface::render() {
const auto FEEDBACK = g_pRenderer->renderLock(*this);
frameCallback = makeShared<CCWlCallback>(surface->sendFrame());
frameCallback->setDone([this](CCWlCallback* r, uint32_t frameTime) {
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isTerminating())
return;
if (Log::logger->verbose()) {
@ -158,7 +158,7 @@ void CSessionLockSurface::render() {
void CSessionLockSurface::onCallback() {
frameCallback.reset();
if (needsFrame && !g_pHyprlock->m_bTerminate && g_pEGL) {
if (needsFrame && !g_pHyprlock->isTerminating() && g_pEGL) {
needsFrame = false;
render();
}

View file

@ -23,7 +23,7 @@ void COutput::create(WP<COutput> pSelf, SP<CCWlOutput> pWlOutput, uint32_t _name
m_wlOutput->setDone([this](CCWlOutput* r) {
done = true;
Log::logger->log(Log::INFO, "output {} done", m_ID);
if (g_pHyprlock->m_lockAquired && !m_sessionLockSurface) {
if (g_pHyprlock->isLockAquired() && !m_sessionLockSurface) {
Log::logger->log(Log::INFO, "output {} creating a new lock surface", m_ID);
createSessionLockSurface();
}

View file

@ -40,9 +40,9 @@ void CSeatManager::registerSeat(SP<CCWlSeat> seat) {
if (std::chrono::system_clock::now() > g_pHyprlock->m_tGraceEnds)
return;
if (!g_pHyprlock->isUnlocked() && g_pHyprlock->m_vLastEnterCoords.distance({wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)}) > 5) {
if (!g_pHyprlock->isFadingOutOrTerminating() && g_pHyprlock->m_vLastEnterCoords.distance({wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)}) > 5) {
Log::logger->log(Log::INFO, "In grace and cursor moved more than 5px, unlocking!");
g_pHyprlock->unlock();
g_pHyprlock->fadeOutAndUnlock();
}
});

View file

@ -512,8 +512,10 @@ void CHyprlock::run() {
Log::logger->log(Log::INFO, "Reached the end, exiting");
}
void CHyprlock::unlock() {
if (!m_bLocked) {
void CHyprlock::fadeOutAndUnlock() {
m_fadeOutOrTerminate = true;
if (!m_sLockState.locked) {
Log::logger->log(Log::WARN, "Unlock called, but not locked yet. This can happen when dpms is off during the grace period.");
return;
}
@ -523,8 +525,16 @@ void CHyprlock::unlock() {
renderAllOutputs();
}
bool CHyprlock::isUnlocked() {
return !m_bLocked;
bool CHyprlock::isFadingOutOrTerminating() {
return m_fadeOutOrTerminate;
}
bool CHyprlock::isTerminating() {
return m_bTerminate;
}
bool CHyprlock::isLockAquired() {
return m_lockAquired;
}
void CHyprlock::clearPasswordBuffer() {
@ -588,11 +598,11 @@ void CHyprlock::repeatKey(xkb_keysym_t sym) {
}
void CHyprlock::onKey(uint32_t key, bool down) {
if (isUnlocked())
if (!m_sLockState.locked)
return;
if (down && std::chrono::system_clock::now() < m_tGraceEnds) {
unlock();
fadeOutAndUnlock();
return;
}
@ -788,7 +798,7 @@ void CHyprlock::releaseSessionLock() {
return;
}
if (!m_bLocked) {
if (!m_sLockState.locked) {
// Would be a protocol error to allow this
Log::logger->log(Log::ERR, "Trying to unlock the session, but never recieved the locked event!");
return;
@ -799,8 +809,8 @@ void CHyprlock::releaseSessionLock() {
Log::logger->log(Log::INFO, "Unlocked, exiting!");
m_bTerminate = true;
m_bLocked = false;
m_bTerminate = true;
m_sLockState.locked = false;
wl_display_roundtrip(m_sWaylandState.display);
}
@ -808,7 +818,7 @@ void CHyprlock::releaseSessionLock() {
void CHyprlock::onLockLocked() {
Log::logger->log(Log::INFO, "onLockLocked called");
m_bLocked = true;
m_sLockState.locked = true;
}
void CHyprlock::onLockFinished() {
@ -819,7 +829,7 @@ void CHyprlock::onLockFinished() {
return;
}
if (m_bLocked)
if (m_sLockState.locked)
// The `finished` event specifies that whenever the `locked` event has been recieved and the compositor sends `finished`,
// `unlock_and_destroy` should be called by the client.
// This does not mean the session gets unlocked! That is ultimately the responsiblity of the compositor.
@ -827,8 +837,9 @@ void CHyprlock::onLockFinished() {
else
m_sLockState.lock.reset();
m_sLockState.lock = nullptr;
m_bTerminate = true;
m_sLockState.lock = nullptr;
m_sLockState.locked = false;
m_bTerminate = true;
}
SP<CCExtSessionLockManagerV1> CHyprlock::getSessionLockMgr() {

View file

@ -32,8 +32,11 @@ class CHyprlock {
void run();
void unlock();
bool isUnlocked();
void fadeOutAndUnlock();
bool isFadingOutOrTerminating();
bool isTerminating();
bool isLockAquired();
ASP<CTimer> addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(ASP<CTimer> self, void* data)> cb_, void* data, bool force = false);
void processTimers();
@ -77,11 +80,6 @@ class CHyprlock {
xkb_layout_index_t m_uiActiveLayout = 0;
bool m_bTerminate = false;
bool m_lockAquired = false;
bool m_bLocked = false;
bool m_bCapsLock = false;
bool m_bNumLock = false;
bool m_bCtrl = false;
@ -122,6 +120,10 @@ class CHyprlock {
void removeDmabufListener();
private:
bool m_lockAquired = false;
bool m_fadeOutOrTerminate = false;
bool m_bTerminate = false;
struct {
wl_display* display = nullptr;
SP<CCWlRegistry> registry = nullptr;
@ -134,7 +136,8 @@ class CHyprlock {
} m_sWaylandState;
struct {
SP<CCExtSessionLockV1> lock = nullptr;
SP<CCExtSessionLockV1> lock = nullptr;
bool locked = false;
} m_sLockState;
struct {

View file

@ -121,7 +121,7 @@ void CImage::reset() {
imageTimer.reset();
}
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isTerminating())
return;
imageFB.destroyBuffer();

View file

@ -116,7 +116,7 @@ void CLabel::reset() {
labelTimer.reset();
}
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isTerminating())
return;
if (asset)

View file

@ -107,7 +107,7 @@ void CPasswordInputField::reset() {
fade.fadeOutTimer.reset();
}
if (g_pHyprlock->m_bTerminate)
if (g_pHyprlock->isTerminating())
return;
if (placeholder.asset)
@ -346,7 +346,7 @@ void CPasswordInputField::updatePlaceholder() {
std::string newText = "";
if (displayFail) {
newText = formatString(configFailText).formatted;
newText = formatString(configFailText).formatted;
placeholder.failedAttempts = g_pAuth->getFailedAttempts();
} else if (checkWaiting && !configCheckText.empty())
newText = formatString(configCheckText).formatted;