From c998e946aae7e4633def6e3c7a925d828fbc7fea Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Mon, 25 Jul 2022 21:08:54 +0200 Subject: [PATCH] Wrap adding to fading out needed to avoid memory safety issues, because sometimes there would be duplicates. --- src/Compositor.cpp | 22 +++++++++++++++++++++- src/Compositor.hpp | 2 ++ src/events/Layers.cpp | 6 +++--- src/events/Windows.cpp | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 175cb66d..34955eca 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -901,8 +901,10 @@ void CCompositor::cleanupFadingOut(const int& monid) { for (auto& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLists) { - if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](std::unique_ptr& other) { return other.get() == ls; }) != lsl.end()) + if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](std::unique_ptr& other) { return other.get() == ls; }) != lsl.end()) { lsl.erase(std::remove_if(lsl.begin(), lsl.end(), [&](std::unique_ptr& other) { return other.get() == ls; })); + return; + } } } @@ -914,6 +916,24 @@ void CCompositor::cleanupFadingOut(const int& monid) { } } +void CCompositor::addToFadingOutSafe(SLayerSurface* pLS) { + const auto FOUND = std::find_if(m_vSurfacesFadingOut.begin(), m_vSurfacesFadingOut.end(), [&](SLayerSurface* other) { return other == pLS; }); + + if (FOUND != m_vSurfacesFadingOut.end()) + return; // if it's already added, don't add it. + + m_vSurfacesFadingOut.emplace_back(pLS); +} + +void CCompositor::addToFadingOutSafe(CWindow* pWindow) { + const auto FOUND = std::find_if(m_vWindowsFadingOut.begin(), m_vWindowsFadingOut.end(), [&](CWindow* other) { return other == pWindow; }); + + if (FOUND != m_vWindowsFadingOut.end()) + return; // if it's already added, don't add it. + + m_vWindowsFadingOut.emplace_back(pWindow); +} + CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { const auto WINDOWIDEALBB = pWindow->getWindowIdealBoundingBoxIgnoreReserved(); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 9b80357f..17d076e5 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -146,6 +146,8 @@ public: void moveUnmanagedX11ToWindows(CWindow*); CWindow* getX11Parent(CWindow*); void scheduleFrameForMonitor(SMonitor*); + void addToFadingOutSafe(SLayerSurface*); + void addToFadingOutSafe(CWindow*); std::string explicitConfigPath; diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index b3463d98..92200d04 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -74,7 +74,7 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) { Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); layersurface->alpha.setValueAndWarp(0.f); layersurface->fadingOut = true; - g_pCompositor->m_vSurfacesFadingOut.push_back(layersurface); + g_pCompositor->addToFadingOutSafe(layersurface); } } @@ -158,7 +158,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) { Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring."); - g_pCompositor->m_vSurfacesFadingOut.push_back(layersurface); + g_pCompositor->addToFadingOutSafe(layersurface); layersurface->mapped = false; @@ -176,7 +176,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { layersurface->fadingOut = true; - g_pCompositor->m_vSurfacesFadingOut.push_back(layersurface); + g_pCompositor->addToFadingOutSafe(layersurface); if (layersurface->layerSurface->mapped) layersurface->layerSurface->mapped = false; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 3cd111ba..58c55be7 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -368,7 +368,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { PWINDOW->m_bFadingOut = true; - g_pCompositor->m_vWindowsFadingOut.emplace_back(PWINDOW); + g_pCompositor->addToFadingOutSafe(PWINDOW); g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID));