From f39a6ca17c3abd9ce472e4cf5fd96df462969c4f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 11 Nov 2023 18:07:56 +0000 Subject: [PATCH] decoration-positioner: improve stability --- .../decorations/DecorationPositioner.cpp | 44 +++++++++++++++++-- .../decorations/DecorationPositioner.hpp | 8 ++-- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index 55e5470d..62279ca5 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -6,6 +6,11 @@ CDecorationPositioner::CDecorationPositioner() { auto* const PWINDOW = std::any_cast(data); this->onWindowUnmap(PWINDOW); }); + + g_pHookSystem->hookDynamic("openWindow", [this](void* call, SCallbackInfo& info, std::any data) { + auto* const PWINDOW = std::any_cast(data); + this->onWindowMap(PWINDOW); + }); } Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, CWindow* pWindow) { @@ -52,7 +57,12 @@ Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, CWindow* pWi void CDecorationPositioner::uncacheDecoration(IHyprWindowDecoration* deco) { std::erase_if(m_vWindowPositioningDatas, [&](const auto& data) { return data->pDecoration == deco; }); - m_mWindowDatas[deco->m_pWindow].needsRecalc = true; + + const auto WIT = std::find_if(m_mWindowDatas.begin(), m_mWindowDatas.end(), [&](const auto& other) { return other.first == deco->m_pWindow; }); + if (WIT == m_mWindowDatas.end()) + return; + + WIT->second.needsRecalc = true; } void CDecorationPositioner::repositionDeco(IHyprWindowDecoration* deco) { @@ -73,11 +83,29 @@ CDecorationPositioner::SWindowPositioningData* CDecorationPositioner::getDataFor return DATA; } +void CDecorationPositioner::sanitizeDatas() { + std::erase_if(m_mWindowDatas, [](const auto& other) { return !g_pCompositor->windowValidMapped(other.first); }); + std::erase_if(m_vWindowPositioningDatas, [](const auto& other) { + if (!g_pCompositor->windowValidMapped(other->pWindow)) + return true; + if (std::find_if(other->pWindow->m_dWindowDecorations.begin(), other->pWindow->m_dWindowDecorations.end(), + [&](const auto& el) { return el.get() == other->pDecoration; }) == other->pWindow->m_dWindowDecorations.end()) + return true; + return false; + }); +} + void CDecorationPositioner::onWindowUpdate(CWindow* pWindow) { if (!g_pCompositor->windowValidMapped(pWindow)) return; - auto* const WINDOWDATA = &m_mWindowDatas[pWindow]; + const auto WIT = std::find_if(m_mWindowDatas.begin(), m_mWindowDatas.end(), [&](const auto& other) { return other.first == pWindow; }); + if (WIT == m_mWindowDatas.end()) + return; + + const auto WINDOWDATA = &WIT->second; + + sanitizeDatas(); // std::vector datas; @@ -221,8 +249,15 @@ void CDecorationPositioner::onWindowUnmap(CWindow* pWindow) { m_mWindowDatas.erase(pWindow); } +void CDecorationPositioner::onWindowMap(CWindow* pWindow) { + m_mWindowDatas[pWindow] = {}; +} + SWindowDecorationExtents CDecorationPositioner::getWindowDecorationReserved(CWindow* pWindow) { - return m_mWindowDatas[pWindow].reserved; + try { + const auto E = m_mWindowDatas.at(pWindow); + return E.reserved; + } catch (std::out_of_range& e) { return {}; } } SWindowDecorationExtents CDecorationPositioner::getWindowDecorationExtents(CWindow* pWindow, bool inputOnly) { @@ -232,6 +267,9 @@ SWindowDecorationExtents CDecorationPositioner::getWindowDecorationExtents(CWind if (data->pWindow != pWindow) continue; + if (!data->pWindow || !data->pDecoration) + continue; + if (!(data->pDecoration->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT) && inputOnly) continue; diff --git a/src/render/decorations/DecorationPositioner.hpp b/src/render/decorations/DecorationPositioner.hpp index ebb9f480..fca8eec2 100644 --- a/src/render/decorations/DecorationPositioner.hpp +++ b/src/render/decorations/DecorationPositioner.hpp @@ -9,14 +9,12 @@ class CWindow; class IHyprWindowDecoration; -enum eDecorationPositioningPolicy -{ +enum eDecorationPositioningPolicy { DECORATION_POSITION_ABSOLUTE = 0, /* Decoration does not interfere with anything else */ DECORATION_POSITION_STICKY, /* Decoration is stuck to some edge of a window */ }; -enum eDecorationEdges -{ +enum eDecorationEdges { DECORATION_EDGE_TOP = 1 << 0, DECORATION_EDGE_BOTTOM = 1 << 1, DECORATION_EDGE_LEFT = 1 << 2, @@ -93,6 +91,8 @@ class CDecorationPositioner { SWindowPositioningData* getDataFor(IHyprWindowDecoration* pDecoration, CWindow* pWindow); void onWindowUnmap(CWindow* pWindow); + void onWindowMap(CWindow* pWindow); + void sanitizeDatas(); }; inline std::unique_ptr g_pDecorationPositioner; \ No newline at end of file