summaryrefslogtreecommitdiff
path: root/src/managers/SessionLockManager.cpp
diff options
context:
space:
mode:
authorvaxerski <43317083+vaxerski@users.noreply.github.com>2023-02-03 11:58:55 +0000
committervaxerski <43317083+vaxerski@users.noreply.github.com>2023-02-03 11:58:55 +0000
commit129e99a6f60eac7ece31a1ccd1e781075fd53050 (patch)
tree013b31817af992a52d733369a7227a237e8c0d26 /src/managers/SessionLockManager.cpp
parent32d56fec977b109aeecb06288a1b45cfe6b83117 (diff)
Implement ext-session-lock-v1
Diffstat (limited to 'src/managers/SessionLockManager.cpp')
-rw-r--r--src/managers/SessionLockManager.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp
new file mode 100644
index 00000000..64380cc4
--- /dev/null
+++ b/src/managers/SessionLockManager.cpp
@@ -0,0 +1,153 @@
+#include "SessionLockManager.hpp"
+#include "../Compositor.hpp"
+
+static void handleSurfaceMap(void* owner, void* data) {
+ const auto PSURFACE = (SSessionLockSurface*)owner;
+
+ Debug::log(LOG, "SessionLockSurface %lx mapped", PSURFACE);
+
+ PSURFACE->mapped = true;
+
+ g_pCompositor->focusSurface(PSURFACE->pWlrLockSurface->surface);
+
+ const auto PMONITOR = g_pCompositor->getMonitorFromID(PSURFACE->iMonitorID);
+
+ if (PMONITOR)
+ g_pHyprRenderer->damageMonitor(PMONITOR);
+
+ g_pSessionLockManager->activateLock(); // activate lock here to prevent the red screen from flashing before that
+}
+
+static void handleSurfaceCommit(void* owner, void* data) {
+ const auto PSURFACE = (SSessionLockSurface*)owner;
+
+ const auto PMONITOR = g_pCompositor->getMonitorFromID(PSURFACE->iMonitorID);
+
+ if (PMONITOR)
+ g_pHyprRenderer->damageMonitor(PMONITOR);
+}
+
+static void handleSurfaceDestroy(void* owner, void* data) {
+ const auto PSURFACE = (SSessionLockSurface*)owner;
+
+ Debug::log(LOG, "SessionLockSurface %lx destroyed", PSURFACE);
+
+ PSURFACE->hyprListener_commit.removeCallback();
+ PSURFACE->hyprListener_destroy.removeCallback();
+ PSURFACE->hyprListener_map.removeCallback();
+
+ g_pSessionLockManager->removeSessionLockSurface(PSURFACE);
+}
+
+void CSessionLockManager::onNewSessionLock(wlr_session_lock_v1* pWlrLock) {
+
+ if (m_sSessionLock.active) {
+ Debug::log(LOG, "Attempted to lock a locked session!");
+ wlr_session_lock_v1_destroy(pWlrLock);
+ return;
+ }
+
+ Debug::log(LOG, "Session got locked by %lx", pWlrLock);
+
+ m_sSessionLock.pWlrLock = pWlrLock;
+
+ g_pCompositor->m_sSeat.exclusiveClient = wl_resource_get_client(pWlrLock->resource);
+
+ m_sSessionLock.hyprListener_newSurface.initCallback(
+ &pWlrLock->events.new_surface,
+ [&](void* owner, void* data) {
+ const auto PSURFACE = &*m_sSessionLock.vSessionLockSurfaces.emplace_back(std::make_unique<SSessionLockSurface>());
+
+ const auto PWLRSURFACE = (wlr_session_lock_surface_v1*)data;
+
+ const auto PMONITOR = g_pCompositor->getMonitorFromOutput(PWLRSURFACE->output);
+
+ if (!PMONITOR) {
+ m_sSessionLock.vSessionLockSurfaces.pop_back();
+ return;
+ }
+
+ PSURFACE->pWlrLockSurface = PWLRSURFACE;
+ PSURFACE->iMonitorID = PMONITOR->ID;
+
+ wlr_session_lock_surface_v1_configure(PWLRSURFACE, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
+
+ PSURFACE->hyprListener_map.initCallback(&PWLRSURFACE->events.map, &handleSurfaceMap, PSURFACE, "SSessionLockSurface");
+ PSURFACE->hyprListener_destroy.initCallback(&PWLRSURFACE->events.destroy, &handleSurfaceDestroy, PSURFACE, "SSessionLockSurface");
+ PSURFACE->hyprListener_commit.initCallback(&PWLRSURFACE->surface->events.commit, &handleSurfaceCommit, PSURFACE, "SSessionLockSurface");
+ },
+ pWlrLock, "wlr_session_lock_v1");
+
+ m_sSessionLock.hyprListener_unlock.initCallback(
+ &pWlrLock->events.unlock,
+ [&](void* owner, void* data) {
+ Debug::log(LOG, "Session Unlocked");
+
+ m_sSessionLock.hyprListener_destroy.removeCallback();
+ m_sSessionLock.hyprListener_newSurface.removeCallback();
+ m_sSessionLock.hyprListener_unlock.removeCallback();
+
+ m_sSessionLock.active = false;
+
+ g_pCompositor->m_sSeat.exclusiveClient = nullptr;
+ g_pInputManager->refocus();
+
+ for (auto& m : g_pCompositor->m_vMonitors)
+ g_pHyprRenderer->damageMonitor(m.get());
+ },
+ pWlrLock, "wlr_session_lock_v1");
+
+ m_sSessionLock.hyprListener_destroy.initCallback(
+ &pWlrLock->events.destroy,
+ [&](void* owner, void* data) {
+ Debug::log(LOG, "Session Lock Abandoned");
+
+ m_sSessionLock.hyprListener_destroy.removeCallback();
+ m_sSessionLock.hyprListener_newSurface.removeCallback();
+ m_sSessionLock.hyprListener_unlock.removeCallback();
+
+ g_pCompositor->m_sSeat.exclusiveClient = nullptr;
+
+ g_pInputManager->refocus();
+
+ for (auto& m : g_pCompositor->m_vMonitors)
+ g_pHyprRenderer->damageMonitor(m.get());
+ },
+ pWlrLock, "wlr_session_lock_v1");
+
+ wlr_session_lock_v1_send_locked(pWlrLock);
+}
+
+bool CSessionLockManager::isSessionLocked() {
+ return m_sSessionLock.active;
+}
+
+SSessionLockSurface* CSessionLockManager::getSessionLockSurfaceForMonitor(const int& id) {
+ for (auto& sls : m_sSessionLock.vSessionLockSurfaces) {
+ if (sls->iMonitorID == id) {
+ if (sls->mapped)
+ return sls.get();
+ else
+ return nullptr;
+ }
+ }
+
+ return nullptr;
+}
+
+bool CSessionLockManager::isSurfaceSessionLock(wlr_surface* pSurface) {
+ for (auto& sls : m_sSessionLock.vSessionLockSurfaces) {
+ if (sls->pWlrLockSurface->surface == pSurface)
+ return true;
+ }
+
+ return false;
+}
+
+void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
+ std::erase_if(m_sSessionLock.vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
+}
+
+void CSessionLockManager::activateLock() {
+ m_sSessionLock.active = true;
+} \ No newline at end of file