2023-02-03 11:58:55 +00:00
|
|
|
#include "SessionLockManager.hpp"
|
|
|
|
|
#include "../Compositor.hpp"
|
2024-03-03 18:39:20 +00:00
|
|
|
#include "../config/ConfigValue.hpp"
|
2024-04-20 14:14:54 +01:00
|
|
|
#include "../protocols/FractionalScale.hpp"
|
2024-04-30 16:32:05 +01:00
|
|
|
#include "../protocols/SessionLock.hpp"
|
2024-10-17 20:05:55 +00:00
|
|
|
#include "../managers/SeatManager.hpp"
|
2025-01-17 15:21:35 +00:00
|
|
|
#include "../render/Renderer.hpp"
|
|
|
|
|
#include "../managers/input/InputManager.hpp"
|
2024-07-13 18:32:08 +08:00
|
|
|
#include <algorithm>
|
2024-08-29 23:30:12 +02:00
|
|
|
#include <ranges>
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : surface(surface_) {
|
2024-05-05 17:16:00 +01:00
|
|
|
pWlrSurface = surface->surface();
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
listeners.map = surface_->m_events.map.registerListener([this](std::any data) {
|
2024-04-30 16:32:05 +01:00
|
|
|
mapped = true;
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-06-25 14:22:38 -07:00
|
|
|
g_pInputManager->simulateMouseMovement();
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
if (PMONITOR)
|
|
|
|
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
|
|
|
|
});
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
listeners.destroy = surface_->m_events.destroy.registerListener([this](std::any data) {
|
2025-04-22 15:23:29 +02:00
|
|
|
if (pWlrSurface == g_pCompositor->m_lastFocus)
|
|
|
|
|
g_pCompositor->m_lastFocus.reset();
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
g_pSessionLockManager->removeSessionLockSurface(this);
|
|
|
|
|
});
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
listeners.commit = surface_->m_events.commit.registerListener([this](std::any data) {
|
2024-04-30 16:32:05 +01:00
|
|
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-04-22 15:23:29 +02:00
|
|
|
if (mapped && !g_pCompositor->m_lastFocus)
|
2024-09-04 15:59:00 +00:00
|
|
|
g_pInputManager->simulateMouseMovement();
|
|
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
if (PMONITOR)
|
|
|
|
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
|
|
|
|
});
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
CSessionLockManager::CSessionLockManager() {
|
2025-05-04 19:21:36 +02:00
|
|
|
m_listeners.newLock = PROTO::sessionLock->m_events.newLock.registerListener([this](std::any data) { this->onNewSessionLock(std::any_cast<SP<CSessionLock>>(data)); });
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-03-03 18:39:20 +00:00
|
|
|
static auto PALLOWRELOCK = CConfigValue<Hyprlang::INT>("misc:allow_session_lock_restore");
|
2023-05-13 12:36:36 +01:00
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
if (PROTO::sessionLock->isLocked() && !*PALLOWRELOCK) {
|
|
|
|
|
Debug::log(LOG, "Cannot re-lock, misc:allow_session_lock_restore is disabled");
|
2024-05-07 18:42:55 +01:00
|
|
|
pLock->sendDenied();
|
2023-02-03 11:58:55 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
Debug::log(LOG, "Session got locked by {:x}", (uintptr_t)pLock.get());
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
m_sessionLock = makeUnique<SSessionLock>();
|
|
|
|
|
m_sessionLock->lock = pLock;
|
|
|
|
|
m_sessionLock->mLockTimer.reset();
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
m_sessionLock->listeners.newSurface = pLock->m_events.newLockSurface.registerListener([this](std::any data) {
|
2024-04-30 16:32:05 +01:00
|
|
|
auto SURFACE = std::any_cast<SP<CSessionLockSurface>>(data);
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
const auto PMONITOR = SURFACE->monitor();
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
const auto NEWSURFACE = m_sessionLock->vSessionLockSurfaces.emplace_back(makeUnique<SSessionLockSurface>(SURFACE)).get();
|
2025-04-30 23:45:20 +02:00
|
|
|
NEWSURFACE->iMonitorID = PMONITOR->m_id;
|
|
|
|
|
PROTO::fractional->sendScale(SURFACE->surface(), PMONITOR->m_scale);
|
2024-04-30 16:32:05 +01:00
|
|
|
});
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
m_sessionLock->listeners.unlock = pLock->m_events.unlockAndDestroy.registerListener([this](std::any data) {
|
2025-05-02 17:07:20 +02:00
|
|
|
m_sessionLock.reset();
|
2024-04-30 16:32:05 +01:00
|
|
|
g_pInputManager->refocus();
|
2024-03-15 17:17:13 +01:00
|
|
|
|
2025-04-22 15:23:29 +02:00
|
|
|
for (auto const& m : g_pCompositor->m_monitors)
|
2024-10-19 23:03:29 +01:00
|
|
|
g_pHyprRenderer->damageMonitor(m);
|
2024-04-30 16:32:05 +01:00
|
|
|
});
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-05-04 19:21:36 +02:00
|
|
|
m_sessionLock->listeners.destroy = pLock->m_events.destroyed.registerListener([this](std::any data) {
|
2025-05-02 17:07:20 +02:00
|
|
|
m_sessionLock.reset();
|
2024-04-30 16:32:05 +01:00
|
|
|
g_pCompositor->focusSurface(nullptr);
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2025-04-22 15:23:29 +02:00
|
|
|
for (auto const& m : g_pCompositor->m_monitors)
|
2024-10-19 23:03:29 +01:00
|
|
|
g_pHyprRenderer->damageMonitor(m);
|
2024-04-30 16:32:05 +01:00
|
|
|
});
|
2023-02-03 11:58:55 +00:00
|
|
|
|
2024-06-25 14:22:38 -07:00
|
|
|
g_pCompositor->focusSurface(nullptr);
|
2024-10-17 20:05:55 +00:00
|
|
|
g_pSeatManager->setGrab(nullptr);
|
2025-02-13 11:06:36 +00:00
|
|
|
|
|
|
|
|
// Normally the locked event is sent after each output rendered a lock screen frame.
|
|
|
|
|
// When there are no outputs, send it right away.
|
2025-04-22 15:23:29 +02:00
|
|
|
if (g_pCompositor->m_unsafeState) {
|
2025-05-02 17:07:20 +02:00
|
|
|
m_sessionLock->lock->sendLocked();
|
|
|
|
|
m_sessionLock->hasSentLocked = true;
|
2025-02-13 11:06:36 +00:00
|
|
|
}
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CSessionLockManager::isSessionLocked() {
|
2024-04-30 16:32:05 +01:00
|
|
|
return PROTO::sessionLock->isLocked();
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
2025-01-25 12:44:13 -06:00
|
|
|
WP<SSessionLockSurface> CSessionLockManager::getSessionLockSurfaceForMonitor(uint64_t id) {
|
2025-05-02 17:07:20 +02:00
|
|
|
if (!m_sessionLock)
|
2025-01-25 12:44:13 -06:00
|
|
|
return {};
|
2024-04-30 16:32:05 +01:00
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
for (auto const& sls : m_sessionLock->vSessionLockSurfaces) {
|
2023-02-03 11:58:55 +00:00
|
|
|
if (sls->iMonitorID == id) {
|
|
|
|
|
if (sls->mapped)
|
2025-01-25 12:44:13 -06:00
|
|
|
return sls;
|
2023-02-03 11:58:55 +00:00
|
|
|
else
|
2025-01-25 12:44:13 -06:00
|
|
|
return {};
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-25 12:44:13 -06:00
|
|
|
return {};
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
2024-03-15 17:17:13 +01:00
|
|
|
// We don't want the red screen to flash.
|
|
|
|
|
float CSessionLockManager::getRedScreenAlphaForMonitor(uint64_t id) {
|
2025-05-02 17:07:20 +02:00
|
|
|
if (!m_sessionLock)
|
2024-08-02 15:25:51 +02:00
|
|
|
return 1.F;
|
2024-03-15 17:17:13 +01:00
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
const auto& NOMAPPEDSURFACETIMER = m_sessionLock->mMonitorsWithoutMappedSurfaceTimers.find(id);
|
2024-04-30 16:32:05 +01:00
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
if (NOMAPPEDSURFACETIMER == m_sessionLock->mMonitorsWithoutMappedSurfaceTimers.end()) {
|
|
|
|
|
m_sessionLock->mMonitorsWithoutMappedSurfaceTimers.emplace(id, CTimer());
|
|
|
|
|
m_sessionLock->mMonitorsWithoutMappedSurfaceTimers[id].reset();
|
2024-03-15 17:17:13 +01:00
|
|
|
return 0.f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::clamp(NOMAPPEDSURFACETIMER->second.getSeconds() - /* delay for screencopy */ 0.5f, 0.f, 1.f);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-13 18:32:08 +08:00
|
|
|
void CSessionLockManager::onLockscreenRenderedOnMonitor(uint64_t id) {
|
2025-05-02 17:07:20 +02:00
|
|
|
if (!m_sessionLock || m_sessionLock->hasSentLocked)
|
2024-07-13 18:32:08 +08:00
|
|
|
return;
|
2025-05-02 17:07:20 +02:00
|
|
|
m_sessionLock->lockedMonitors.emplace(id);
|
|
|
|
|
const bool LOCKED = std::ranges::all_of(g_pCompositor->m_monitors, [this](auto m) { return m_sessionLock->lockedMonitors.contains(m->m_id); });
|
|
|
|
|
if (LOCKED && m_sessionLock->lock->good()) {
|
|
|
|
|
m_sessionLock->lock->sendLocked();
|
|
|
|
|
m_sessionLock->hasSentLocked = true;
|
2024-07-13 18:32:08 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-08 10:07:59 +02:00
|
|
|
bool CSessionLockManager::isSurfaceSessionLock(SP<CWLSurfaceResource> pSurface) {
|
2024-04-30 16:32:05 +01:00
|
|
|
// TODO: this has some edge cases when it's wrong (e.g. destroyed lock but not yet surfaces)
|
|
|
|
|
// but can be easily fixed when I rewrite wlr_surface
|
|
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
if (!m_sessionLock)
|
2024-04-30 16:32:05 +01:00
|
|
|
return false;
|
|
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
for (auto const& sls : m_sessionLock->vSessionLockSurfaces) {
|
2024-05-05 17:16:00 +01:00
|
|
|
if (sls->surface->surface() == pSurface)
|
2023-02-03 11:58:55 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
|
2025-05-02 17:07:20 +02:00
|
|
|
if (!m_sessionLock)
|
2024-04-30 16:32:05 +01:00
|
|
|
return;
|
|
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
std::erase_if(m_sessionLock->vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
|
2024-03-15 19:44:17 +01:00
|
|
|
|
2025-04-22 15:23:29 +02:00
|
|
|
if (g_pCompositor->m_lastFocus)
|
2024-03-15 19:44:17 +01:00
|
|
|
return;
|
|
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
for (auto const& sls : m_sessionLock->vSessionLockSurfaces) {
|
2024-03-15 19:44:17 +01:00
|
|
|
if (!sls->mapped)
|
|
|
|
|
continue;
|
|
|
|
|
|
2024-05-05 17:16:00 +01:00
|
|
|
g_pCompositor->focusSurface(sls->surface->surface());
|
2024-03-15 19:44:17 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2023-02-03 11:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
2024-04-30 16:32:05 +01:00
|
|
|
bool CSessionLockManager::isSessionLockPresent() {
|
2025-05-02 17:07:20 +02:00
|
|
|
return m_sessionLock && !m_sessionLock->vSessionLockSurfaces.empty();
|
2024-04-30 16:32:05 +01:00
|
|
|
}
|
2024-08-29 23:30:12 +02:00
|
|
|
|
|
|
|
|
bool CSessionLockManager::anySessionLockSurfacesPresent() {
|
2025-05-02 17:07:20 +02:00
|
|
|
return m_sessionLock && std::ranges::any_of(m_sessionLock->vSessionLockSurfaces, [](const auto& surf) { return surf->mapped; });
|
2024-08-29 23:30:12 +02:00
|
|
|
}
|
2024-11-17 15:58:18 +00:00
|
|
|
|
|
|
|
|
bool CSessionLockManager::shallConsiderLockMissing() {
|
2025-05-02 17:07:20 +02:00
|
|
|
if (!m_sessionLock)
|
2024-11-17 15:58:18 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
static auto LOCKDEAD_SCREEN_DELAY = CConfigValue<Hyprlang::INT>("misc:lockdead_screen_delay");
|
|
|
|
|
|
2025-05-02 17:07:20 +02:00
|
|
|
return m_sessionLock->mLockTimer.getMillis() > *LOCKDEAD_SCREEN_DELAY;
|
2025-01-17 15:21:35 +00:00
|
|
|
}
|