diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index dd2cfb7d048..d472b906cc3 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -90,7 +90,7 @@ PHLLS CLayerSurface::create(wlr_layer_surface_v1* pWLRLS) { pLS->alpha.setValueAndWarp(0.f); - pLS->surface.assign(pWLRLS->surface); + pLS->surface.assign(pWLRLS->surface, pLS); return pLS; } diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 3cfebe1bf99..b4de8dda1d6 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -71,8 +71,8 @@ void CPopup::initAllSignals() { if (!m_pWLR) { if (!m_pWindowOwner.expired()) hyprListener_newPopup.initCallback(&m_pWindowOwner.lock()->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head"); - else if (m_pLayerOwner) - hyprListener_newPopup.initCallback(&m_pLayerOwner->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head"); + else if (!m_pLayerOwner.expired()) + hyprListener_newPopup.initCallback(&m_pLayerOwner.lock()->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head"); else ASSERT(false); @@ -119,8 +119,8 @@ void CPopup::onMap() { unconstrain(); sendScale(); - if (m_pLayerOwner && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) - g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); + if (!m_pLayerOwner.expired() && m_pLayerOwner.lock()->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner.lock()->layer)); } void CPopup::onUnmap() { @@ -136,8 +136,8 @@ void CPopup::onUnmap() { g_pInputManager->simulateMouseMovement(); - if (m_pLayerOwner && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) - g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); + if (!m_pLayerOwner.expired() && m_pLayerOwner.lock()->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner.lock()->layer)); } void CPopup::onCommit(bool ignoreSiblings) { @@ -178,8 +178,8 @@ void CPopup::onCommit(bool ignoreSiblings) { m_bRequestedReposition = false; - if (m_pLayerOwner && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) - g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); + if (!m_pLayerOwner.expired() && m_pLayerOwner.lock()->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner.lock()->layer)); } void CPopup::onReposition() { @@ -232,8 +232,8 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) { Vector2D CPopup::t1ParentCoords() { if (!m_pWindowOwner.expired()) return m_pWindowOwner.lock()->m_vRealPosition.value(); - if (m_pLayerOwner) - return m_pLayerOwner->realPosition.value(); + if (!m_pLayerOwner.expired()) + return m_pLayerOwner.lock()->realPosition.value(); ASSERT(false); return {}; @@ -262,8 +262,19 @@ Vector2D CPopup::size() { void CPopup::sendScale() { if (!m_pWindowOwner.expired()) g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner.lock()->m_pWLSurface.m_fLastScale); - else if (m_pLayerOwner) - g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale); + else if (!m_pLayerOwner.expired()) + g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner.lock()->surface.m_fLastScale); else UNREACHABLE(); } + +bool CPopup::visible() { + if (!m_pWindowOwner.expired()) + return g_pHyprRenderer->shouldRenderWindow(m_pWindowOwner.lock()); + if (!m_pLayerOwner.expired()) + return true; + if (m_pParent) + return m_pParent->visible(); + + return false; +} diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 16f011ebebc..cadbf244331 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -29,12 +29,14 @@ class CPopup { void recheckTree(); + bool visible(); + CWLSurface m_sWLSurface; private: // T1 owners, each popup has to have one of these PHLWINDOWREF m_pWindowOwner; - PHLLS m_pLayerOwner; + PHLLSREF m_pLayerOwner; // T2 owners CPopup* m_pParent = nullptr; diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index b2c9f8bda18..1809efe5c6f 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -227,3 +227,14 @@ void CSubsurface::initExistingSubsurfaces(wlr_surface* pSurface) { Vector2D CSubsurface::size() { return {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}; } + +bool CSubsurface::visible() { + if (!m_pWindowParent.expired()) + return g_pHyprRenderer->shouldRenderWindow(m_pWindowParent.lock()); + if (m_pPopupParent) + return m_pPopupParent->visible(); + if (m_pParent) + return m_pParent->visible(); + + return false; +} diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index e50940411bc..f3a5ea4b8e4 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -29,6 +29,8 @@ class CSubsurface { void onMap(); void onUnmap(); + bool visible(); + void recheckDamageForSubsurfaces(); private: diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 41c357e0704..fd6c28b3933 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -197,3 +197,15 @@ void CWLSurface::onCommit() { std::shared_ptr CWLSurface::constraint() { return m_pConstraint.lock(); } + +bool CWLSurface::visible() { + if (!m_pWindowOwner.expired()) + return g_pHyprRenderer->shouldRenderWindow(m_pWindowOwner.lock()); + if (!m_pLayerOwner.expired()) + return true; + if (m_pPopupOwner) + return m_pPopupOwner->visible(); + if (m_pSubsurfaceOwner) + return m_pSubsurfaceOwner->visible(); + return true; // non-desktop, we don't know much. +} diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 752f4d11127..8fb69937c2d 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -33,6 +33,7 @@ class CWLSurface { Vector2D getViewporterCorrectedSize() const; CRegion logicalDamage() const; void onCommit(); + bool visible(); // getters for owners. PHLWINDOW getWindow(); diff --git a/src/managers/input/IdleInhibitor.cpp b/src/managers/input/IdleInhibitor.cpp index 40c8c637e27..dc7c61c3d72 100644 --- a/src/managers/input/IdleInhibitor.cpp +++ b/src/managers/input/IdleInhibitor.cpp @@ -14,26 +14,33 @@ void CInputManager::newIdleInhibitor(std::any inhibitor) { recheckIdleInhibitorStatus(); }); - const auto PWINDOW = g_pCompositor->getWindowFromSurface(PINHIBIT->inhibitor->surface); - - if (PWINDOW) { - PINHIBIT->pWindow = PWINDOW; - PINHIBIT->windowDestroyListener = PWINDOW->events.destroy.registerListener([PINHIBIT](std::any data) { - Debug::log(WARN, "Inhibitor got its window destroyed before its inhibitor resource."); - PINHIBIT->pWindow.reset(); - }); - } else - Debug::log(WARN, "Inhibitor is for no window?"); + auto WLSurface = CWLSurface::surfaceFromWlr(PINHIBIT->inhibitor->surface); + + if (!WLSurface) { + Debug::log(LOG, "Inhibitor has no HL Surface attached to it, likely meaning it's a non-desktop element. Ignoring."); + PINHIBIT->inert = true; + recheckIdleInhibitorStatus(); + return; + } + + PINHIBIT->surfaceDestroyListener = WLSurface->events.destroy.registerListener( + [this, PINHIBIT](std::any data) { std::erase_if(m_vIdleInhibitors, [PINHIBIT](const auto& other) { return other.get() == PINHIBIT; }); }); + recheckIdleInhibitorStatus(); } void CInputManager::recheckIdleInhibitorStatus() { for (auto& ii : m_vIdleInhibitors) { - if (ii->pWindow.expired()) + if (ii->inert) + continue; + + auto WLSurface = CWLSurface::surfaceFromWlr(ii->inhibitor->surface); + + if (!WLSurface) continue; - if (g_pHyprRenderer->shouldRenderWindow(ii->pWindow.lock())) { + if (WLSurface->visible()) { PROTO::idle->setInhibit(true); return; } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 98032dd4f57..719e19c6a60 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -242,8 +242,8 @@ class CInputManager { // idle inhibitors struct SIdleInhibitor { std::shared_ptr inhibitor; - PHLWINDOWREF pWindow; - CHyprSignalListener windowDestroyListener; + bool inert = false; + CHyprSignalListener surfaceDestroyListener; }; std::vector> m_vIdleInhibitors;