From 5edc32930d85f5f481160b938965c8bc329487e7 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 30 Apr 2024 02:41:27 +0100 Subject: [PATCH] layerSurface: refactor/move to a memory-safe impl Makes all the pointers smart to avoid memory issues Refactors layerSurface code to live inside desktop/layersurface --- src/Compositor.cpp | 60 +-- src/Compositor.hpp | 164 ++++---- src/config/ConfigManager.cpp | 4 +- src/config/ConfigManager.hpp | 5 +- src/defines.hpp | 6 + src/desktop/LayerSurface.cpp | 589 ++++++++++++++++++++++++++++ src/desktop/LayerSurface.hpp | 85 ++++ src/desktop/Popup.cpp | 2 +- src/desktop/Popup.hpp | 8 +- src/desktop/WLSurface.cpp | 14 +- src/desktop/WLSurface.hpp | 24 +- src/events/Events.hpp | 4 - src/events/Layers.cpp | 364 ----------------- src/helpers/AnimatedVariable.cpp | 2 +- src/helpers/AnimatedVariable.hpp | 12 +- src/helpers/Monitor.hpp | 2 +- src/helpers/WLClasses.cpp | 211 ---------- src/helpers/WLClasses.hpp | 64 --- src/managers/AnimationManager.cpp | 5 +- src/managers/input/InputManager.cpp | 12 +- src/managers/input/InputManager.hpp | 16 +- src/managers/input/Touch.cpp | 10 +- src/render/OpenGL.cpp | 34 +- src/render/OpenGL.hpp | 12 +- src/render/Renderer.cpp | 25 +- src/render/Renderer.hpp | 4 +- 26 files changed, 874 insertions(+), 864 deletions(-) create mode 100644 src/desktop/LayerSurface.cpp create mode 100644 src/desktop/LayerSurface.hpp delete mode 100644 src/events/Layers.cpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index b8358cbe..e31fb9db 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -15,6 +15,7 @@ #include "helpers/VarList.hpp" #include "protocols/FractionalScale.hpp" #include "protocols/PointerConstraints.hpp" +#include "desktop/LayerSurface.hpp" #include #include @@ -1105,7 +1106,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) { SURF->constraint()->activate(); } -wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) { +wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { for (auto& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) { for (auto& ls : lsl | std::views::reverse) { if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f) @@ -1117,7 +1118,7 @@ wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonito if (!pixman_region32_not_empty(&SURFACEAT->input_region)) continue; - *ppLayerSurfaceFound = ls.get(); + *ppLayerSurfaceFound = ls; return SURFACEAT; } } @@ -1126,8 +1127,7 @@ wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonito return nullptr; } -wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector>* layerSurfaces, Vector2D* sCoords, - SLayerSurface** ppLayerSurfaceFound) { +wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { for (auto& ls : *layerSurfaces | std::views::reverse) { if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f) continue; @@ -1138,7 +1138,7 @@ wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector< if (!pixman_region32_not_empty(&SURFACEAT->input_region)) continue; - *ppLayerSurfaceFound = ls.get(); + *ppLayerSurfaceFound = ls; return SURFACEAT; } } @@ -1395,34 +1395,12 @@ void CCompositor::cleanupFadingOut(const int& monid) { } } - for (auto& ls : m_vSurfacesFadingOut) { + for (auto& lsr : m_vSurfacesFadingOut) { - // sometimes somehow fucking happens wtf - bool exists = false; - for (auto& m : m_vMonitors) { - for (auto& lsl : m->m_aLayerSurfaceLayers) { - for (auto& lsp : lsl) { - if (lsp.get() == ls) { - exists = true; - break; - } - } + auto ls = lsr.lock(); - if (exists) - break; - } - - if (exists) - break; - } - - if (!exists) { - std::erase(m_vSurfacesFadingOut, ls); - - Debug::log(LOG, "Fading out a non-existent LS??"); - - return; - } + if (!ls) + continue; if (ls->monitorID != monid) continue; @@ -1434,13 +1412,13 @@ void CCompositor::cleanupFadingOut(const int& monid) { if (ls->fadingOut && ls->readyToDelete && ls->isFadedOut()) { for (auto& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLayers) { - if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](std::unique_ptr& other) { return other.get() == ls; }) != lsl.end()) { - std::erase_if(lsl, [&](std::unique_ptr& other) { return other.get() == ls; }); + if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](auto& other) { return other == ls; }) != lsl.end()) { + std::erase_if(lsl, [&](auto& other) { return other == ls; }); } } } - std::erase(m_vSurfacesFadingOut, ls); + std::erase_if(m_vSurfacesFadingOut, [ls](const auto& el) { return el.lock() == ls; }); Debug::log(LOG, "Cleanup: destroyed a layersurface"); @@ -1450,8 +1428,8 @@ 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; }); +void CCompositor::addToFadingOutSafe(PHLLS pLS) { + const auto FOUND = std::find_if(m_vSurfacesFadingOut.begin(), m_vSurfacesFadingOut.end(), [&](auto& other) { return other.lock() == pLS; }); if (FOUND != m_vSurfacesFadingOut.end()) return; // if it's already added, don't add it. @@ -2460,12 +2438,12 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) { setActiveMonitor(PMONITORNEW); } -SLayerSurface* CCompositor::getLayerSurfaceFromWlr(wlr_layer_surface_v1* pLS) { +PHLLS CCompositor::getLayerSurfaceFromWlr(wlr_layer_surface_v1* pLS) { for (auto& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLayers) { for (auto& ls : lsl) { if (ls->layerSurface == pLS) - return ls.get(); + return ls; } } } @@ -2479,14 +2457,14 @@ void CCompositor::closeWindow(PHLWINDOW pWindow) { } } -SLayerSurface* CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) { +PHLLS CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) { std::pair result = {pSurface, false}; for (auto& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLayers) { for (auto& ls : lsl) { if (ls->layerSurface && ls->layerSurface->surface == pSurface) - return ls.get(); + return ls; static auto iter = [](wlr_surface* surf, int x, int y, void* data) -> void { if (surf == ((std::pair*)data)->first) { @@ -2501,7 +2479,7 @@ SLayerSurface* CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) { wlr_surface_for_each_surface(ls->layerSurface->surface, iter, &result); if (result.second) - return ls.get(); + return ls; } } } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index d0acad4d..5e9d0e9f 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -82,7 +82,7 @@ class CCompositor { std::vector m_vWindows; std::vector m_vWorkspaces; std::vector m_vWindowsFadingOut; - std::vector m_vSurfacesFadingOut; + std::vector m_vSurfacesFadingOut; std::unordered_map m_mMonitorIDMap; @@ -111,88 +111,88 @@ class CCompositor { // ------------------------------------------------- // - CMonitor* getMonitorFromID(const int&); - CMonitor* getMonitorFromName(const std::string&); - CMonitor* getMonitorFromDesc(const std::string&); - CMonitor* getMonitorFromCursor(); - CMonitor* getMonitorFromVector(const Vector2D&); - void removeWindowFromVectorSafe(PHLWINDOW); - void focusWindow(PHLWINDOW, wlr_surface* pSurface = nullptr); - void focusSurface(wlr_surface*, PHLWINDOW pWindowOwner = nullptr); - bool monitorExists(CMonitor*); - PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr); - wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector>*, Vector2D*, SLayerSurface**); - wlr_surface* vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, SLayerSurface**); - wlr_surface* vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl); - Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, wlr_surface*); - CMonitor* getMonitorFromOutput(wlr_output*); - CMonitor* getRealMonitorFromOutput(wlr_output*); - PHLWINDOW getWindowFromSurface(wlr_surface*); - PHLWINDOW getWindowFromHandle(uint32_t); - bool isWorkspaceVisible(PHLWORKSPACE); - PHLWORKSPACE getWorkspaceByID(const int&); - PHLWORKSPACE getWorkspaceByName(const std::string&); - PHLWORKSPACE getWorkspaceByString(const std::string&); - void sanityCheckWorkspaces(); - void updateWorkspaceWindowDecos(const int&); - void updateWorkspaceSpecialRenderData(const int&); - int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); - int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); - PHLWINDOW getUrgentWindow(); - bool hasUrgentWindowOnWorkspace(const int&); - PHLWINDOW getFirstWindowOnWorkspace(const int&); - PHLWINDOW getTopLeftWindowOnWorkspace(const int&); - PHLWINDOW getFullscreenWindowOnWorkspace(const int&); - bool doesSeatAcceptInput(wlr_surface*); - bool isWindowActive(PHLWINDOW); - void changeWindowZOrder(PHLWINDOW, bool); - void cleanupFadingOut(const int& monid); - PHLWINDOW getWindowInDirection(PHLWINDOW, char); - PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); - PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); - int getNextAvailableNamedWorkspace(); - bool isPointOnAnyMonitor(const Vector2D&); - bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr); - CMonitor* getMonitorInDirection(const char&); - CMonitor* getMonitorInDirection(CMonitor*, const char&); - void updateAllWindowsAnimatedDecorationValues(); - void updateWorkspaceWindows(const int64_t& id); - void updateWindowAnimatedDecorationValues(PHLWINDOW); - int getNextAvailableMonitorID(std::string const& name); - void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false); - void swapActiveWorkspaces(CMonitor*, CMonitor*); - CMonitor* getMonitorFromString(const std::string&); - bool workspaceIDOutOfBounds(const int64_t&); - void setWindowFullscreen(PHLWINDOW, bool, eFullscreenMode mode = FULLSCREEN_INVALID); - void updateFullscreenFadeOnWorkspace(PHLWORKSPACE); - PHLWINDOW getX11Parent(PHLWINDOW); - void scheduleFrameForMonitor(CMonitor*); - void addToFadingOutSafe(SLayerSurface*); - void addToFadingOutSafe(PHLWINDOW); - PHLWINDOW getWindowByRegex(const std::string&); - void warpCursorTo(const Vector2D&, bool force = false); - SLayerSurface* getLayerSurfaceFromWlr(wlr_layer_surface_v1*); - SLayerSurface* getLayerSurfaceFromSurface(wlr_surface*); - void closeWindow(PHLWINDOW); - Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); - void forceReportSizesToWindowsOnWorkspace(const int&); - PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused! - void renameWorkspace(const int&, const std::string& name = ""); - void setActiveMonitor(CMonitor*); - bool isWorkspaceSpecial(const int&); - int getNewSpecialID(); - void performUserChecks(); - void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace); - PHLWINDOW getForceFocus(); - void arrangeMonitors(); - void enterUnsafeState(); - void leaveUnsafeState(); - void setPreferredScaleForSurface(wlr_surface* pSurface, double scale); - void setPreferredTransformForSurface(wlr_surface* pSurface, wl_output_transform transform); - void updateSuspendedStates(); - PHLWINDOW windowForCPointer(CWindow*); + CMonitor* getMonitorFromID(const int&); + CMonitor* getMonitorFromName(const std::string&); + CMonitor* getMonitorFromDesc(const std::string&); + CMonitor* getMonitorFromCursor(); + CMonitor* getMonitorFromVector(const Vector2D&); + void removeWindowFromVectorSafe(PHLWINDOW); + void focusWindow(PHLWINDOW, wlr_surface* pSurface = nullptr); + void focusSurface(wlr_surface*, PHLWINDOW pWindowOwner = nullptr); + bool monitorExists(CMonitor*); + PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr); + wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector*, Vector2D*, PHLLS*); + wlr_surface* vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*); + wlr_surface* vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl); + Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, wlr_surface*); + CMonitor* getMonitorFromOutput(wlr_output*); + CMonitor* getRealMonitorFromOutput(wlr_output*); + PHLWINDOW getWindowFromSurface(wlr_surface*); + PHLWINDOW getWindowFromHandle(uint32_t); + bool isWorkspaceVisible(PHLWORKSPACE); + PHLWORKSPACE getWorkspaceByID(const int&); + PHLWORKSPACE getWorkspaceByName(const std::string&); + PHLWORKSPACE getWorkspaceByString(const std::string&); + void sanityCheckWorkspaces(); + void updateWorkspaceWindowDecos(const int&); + void updateWorkspaceSpecialRenderData(const int&); + int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); + int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); + PHLWINDOW getUrgentWindow(); + bool hasUrgentWindowOnWorkspace(const int&); + PHLWINDOW getFirstWindowOnWorkspace(const int&); + PHLWINDOW getTopLeftWindowOnWorkspace(const int&); + PHLWINDOW getFullscreenWindowOnWorkspace(const int&); + bool doesSeatAcceptInput(wlr_surface*); + bool isWindowActive(PHLWINDOW); + void changeWindowZOrder(PHLWINDOW, bool); + void cleanupFadingOut(const int& monid); + PHLWINDOW getWindowInDirection(PHLWINDOW, char); + PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); + PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); + int getNextAvailableNamedWorkspace(); + bool isPointOnAnyMonitor(const Vector2D&); + bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr); + CMonitor* getMonitorInDirection(const char&); + CMonitor* getMonitorInDirection(CMonitor*, const char&); + void updateAllWindowsAnimatedDecorationValues(); + void updateWorkspaceWindows(const int64_t& id); + void updateWindowAnimatedDecorationValues(PHLWINDOW); + int getNextAvailableMonitorID(std::string const& name); + void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false); + void swapActiveWorkspaces(CMonitor*, CMonitor*); + CMonitor* getMonitorFromString(const std::string&); + bool workspaceIDOutOfBounds(const int64_t&); + void setWindowFullscreen(PHLWINDOW, bool, eFullscreenMode mode = FULLSCREEN_INVALID); + void updateFullscreenFadeOnWorkspace(PHLWORKSPACE); + PHLWINDOW getX11Parent(PHLWINDOW); + void scheduleFrameForMonitor(CMonitor*); + void addToFadingOutSafe(PHLLS); + void addToFadingOutSafe(PHLWINDOW); + PHLWINDOW getWindowByRegex(const std::string&); + void warpCursorTo(const Vector2D&, bool force = false); + PHLLS getLayerSurfaceFromWlr(wlr_layer_surface_v1*); + PHLLS getLayerSurfaceFromSurface(wlr_surface*); + void closeWindow(PHLWINDOW); + Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); + void forceReportSizesToWindowsOnWorkspace(const int&); + PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused! + void renameWorkspace(const int&, const std::string& name = ""); + void setActiveMonitor(CMonitor*); + bool isWorkspaceSpecial(const int&); + int getNewSpecialID(); + void performUserChecks(); + void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace); + PHLWINDOW getForceFocus(); + void arrangeMonitors(); + void enterUnsafeState(); + void leaveUnsafeState(); + void setPreferredScaleForSurface(wlr_surface* pSurface, double scale); + void setPreferredTransformForSurface(wlr_surface* pSurface, wl_output_transform transform); + void updateSuspendedStates(); + PHLWINDOW windowForCPointer(CWindow*); - std::string explicitConfigPath; + std::string explicitConfigPath; private: void initAllSignals(); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 4a03b180..e73f6284 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1177,7 +1177,7 @@ std::vector CConfigManager::getMatchingRules(PHLWINDOW pWindow, boo return returns; } -std::vector CConfigManager::getMatchingRules(SLayerSurface* pLS) { +std::vector CConfigManager::getMatchingRules(PHLLS pLS) { std::vector returns; if (!pLS->layerSurface || pLS->fadingOut) @@ -1185,7 +1185,7 @@ std::vector CConfigManager::getMatchingRules(SLayerSurface* pLS) { for (auto& lr : m_dLayerRules) { if (lr.targetNamespace.starts_with("address:0x")) { - if (std::format("address:0x{:x}", (uintptr_t)pLS) != lr.targetNamespace) + if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr.targetNamespace) continue; } else { std::regex NSCHECK(lr.targetNamespace); diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index aa34cf3b..2e723656 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -17,6 +17,7 @@ #include "../helpers/Monitor.hpp" #include "../helpers/VarList.hpp" #include "../desktop/Window.hpp" +#include "../desktop/LayerSurface.hpp" #include "defaultConfig.hpp" #include "ConfigDataValues.hpp" @@ -28,8 +29,6 @@ #define HANDLE void* -class CWindow; - struct SWorkspaceRule { std::string monitor = ""; std::string workspaceString = ""; @@ -114,7 +113,7 @@ class CConfigManager { const std::deque& getAllWorkspaceRules(); std::vector getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false); - std::vector getMatchingRules(SLayerSurface*); + std::vector getMatchingRules(PHLLS); std::unordered_map m_mAdditionalReservedAreas; diff --git a/src/defines.hpp b/src/defines.hpp index 809a6fc5..a563bc36 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -5,8 +5,14 @@ #include "macros.hpp" class CWindow; +class CLayerSurface; /* Shared pointer to a window */ typedef SP PHLWINDOW; /* Weak pointer to a window */ typedef WP PHLWINDOWREF; + +/* Shared pointer to a layer surface */ +typedef SP PHLLS; +/* Weak pointer to a layer surface */ +typedef WP PHLLSREF; diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp new file mode 100644 index 00000000..ec899dd1 --- /dev/null +++ b/src/desktop/LayerSurface.cpp @@ -0,0 +1,589 @@ +#include "LayerSurface.hpp" +#include "../Compositor.hpp" +#include "../events/Events.hpp" + +void Events::listener_newLayerSurface(wl_listener* listener, void* data) { + const auto WLRLAYERSURFACE = (wlr_layer_surface_v1*)data; + + if (!WLRLAYERSURFACE->output) { + const auto PMONITOR = g_pCompositor->getMonitorFromCursor(); + + if (!PMONITOR) { + Debug::log(ERR, "No monitor at cursor on new layer without a monitor. Ignoring."); + wlr_layer_surface_v1_destroy(WLRLAYERSURFACE); + return; + } + + Debug::log(LOG, "New LayerSurface has no preferred monitor. Assigning Monitor {}", PMONITOR->szName); + + WLRLAYERSURFACE->output = PMONITOR->output; + } + + auto PMONITOR = g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output); + + if (!WLRLAYERSURFACE->output || !PMONITOR || PMONITOR->pMirrorOf) { + PMONITOR = g_pCompositor->m_vMonitors.front().get(); + WLRLAYERSURFACE->output = PMONITOR->output; // TODO: current mon + } + + const auto PLS = PMONITOR->m_aLayerSurfaceLayers[WLRLAYERSURFACE->pending.layer].emplace_back(CLayerSurface::create(WLRLAYERSURFACE)); + + Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)WLRLAYERSURFACE, WLRLAYERSURFACE->_namespace, (int)PLS->layer, PMONITOR->szName); +} + +static void onCommit(void* owner, void* data) { + const auto LS = ((CLayerSurface*)owner)->self.lock(); + + LS->onCommit(); +} + +static void onMap(void* owner, void* data) { + const auto LS = ((CLayerSurface*)owner)->self.lock(); + + LS->onMap(); +} + +static void onUnmap(void* owner, void* data) { + const auto LS = ((CLayerSurface*)owner)->self.lock(); + + LS->onUnmap(); +} + +static void onDestroy(void* owner, void* data) { + const auto LS = ((CLayerSurface*)owner)->self.lock(); + + LS->onDestroy(); +} + +// IMPL + +PHLLS CLayerSurface::create(wlr_layer_surface_v1* pWLRLS) { + PHLLS pLS = std::shared_ptr(new CLayerSurface); + + auto PMONITOR = g_pCompositor->getMonitorFromOutput(pWLRLS->output); + + pLS->self = pLS; + + pLS->szNamespace = pWLRLS->_namespace; + + pLS->hyprListener_commitLayerSurface.initCallback(&pWLRLS->surface->events.commit, ::onCommit, pLS.get(), "layerSurface"); + pLS->hyprListener_destroyLayerSurface.initCallback(&pWLRLS->events.destroy, ::onDestroy, pLS.get(), "layerSurface"); + pLS->hyprListener_mapLayerSurface.initCallback(&pWLRLS->surface->events.map, ::onMap, pLS.get(), "layerSurface"); + pLS->hyprListener_unmapLayerSurface.initCallback(&pWLRLS->surface->events.unmap, ::onUnmap, pLS.get(), "layerSurface"); + + pLS->layerSurface = pWLRLS; + pLS->layer = pWLRLS->current.layer; + pWLRLS->data = pLS.get(); + pLS->monitorID = PMONITOR->ID; + pLS->popupHead = std::make_unique(pLS); + + pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace); + + pLS->alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE); + pLS->realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE); + pLS->realSize.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE); + pLS->alpha.registerVar(); + pLS->realPosition.registerVar(); + pLS->realSize.registerVar(); + + pLS->registerCallbacks(); + + pLS->alpha.setValueAndWarp(0.f); + + pLS->surface.assign(pWLRLS->surface); + + return pLS; +} + +void CLayerSurface::registerCallbacks() { + alpha.setUpdateCallback([this](void*) { + if (dimAround) + g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(monitorID)); + }); +} + +CLayerSurface::CLayerSurface() { + ; +} + +CLayerSurface::~CLayerSurface() { + if (!g_pHyprOpenGL) + return; + + surface.unassign(); + g_pHyprRenderer->makeEGLCurrent(); + std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); }); +} + +void CLayerSurface::onDestroy() { + Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layerSurface); + + const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); + + popupHead.reset(); + + if (!g_pCompositor->getMonitorFromID(monitorID)) + Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)"); + + if (!fadingOut) { + if (mapped) { + Debug::log(LOG, "Forcing an unmap of a LS that did a straight destroy!"); + onUnmap(); + } else { + Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); + alpha.setValueAndWarp(0.f); + fadingOut = true; + g_pCompositor->addToFadingOutSafe(self.lock()); + } + } + + noProcess = true; + + hyprListener_commitLayerSurface.removeCallback(); + hyprListener_destroyLayerSurface.removeCallback(); + hyprListener_mapLayerSurface.removeCallback(); + hyprListener_unmapLayerSurface.removeCallback(); + + // rearrange to fix the reserved areas + if (PMONITOR) { + g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); + PMONITOR->scheduledRecalc = true; + + // and damage + CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; + g_pHyprRenderer->damageBox(&geomFixed); + } + + readyToDelete = true; + layerSurface = nullptr; + surface.unassign(); +} + +void CLayerSurface::onMap() { + Debug::log(LOG, "LayerSurface {:x} mapped", (uintptr_t)layerSurface); + + mapped = true; + keyboardExclusive = layerSurface->current.keyboard_interactive; + + // fix if it changed its mon + const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); + + if (!PMONITOR) + return; + + applyRules(); + + if ((uint64_t)monitorID != PMONITOR->ID) { + const auto POLDMON = g_pCompositor->getMonitorFromID(monitorID); + for (auto it = POLDMON->m_aLayerSurfaceLayers[layer].begin(); it != POLDMON->m_aLayerSurfaceLayers[layer].end(); it++) { + if (*it == self.lock()) { + PMONITOR->m_aLayerSurfaceLayers[layer].emplace_back(std::move(*it)); + POLDMON->m_aLayerSurfaceLayers[layer].erase(it); + break; + } + } + monitorID = PMONITOR->ID; + PMONITOR->scheduledRecalc = true; + g_pHyprRenderer->arrangeLayersForMonitor(POLDMON->ID); + } + + g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); + + wlr_surface_send_enter(surface.wlr(), PMONITOR->output); + + if (layerSurface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) + g_pInputManager->m_dExclusiveLSes.push_back(self); + + const bool GRABSFOCUS = layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && + // don't focus if constrained + (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()); + + if (GRABSFOCUS) { + g_pInputManager->releaseAllMouseButtons(); + g_pCompositor->focusSurface(surface.wlr()); + + const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y); + wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, surface.wlr(), LOCAL.x, LOCAL.y); + wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y); + g_pInputManager->m_bEmptyFocusCursorSet = false; + } + + position = Vector2D(geometry.x, geometry.y); + + CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; + g_pHyprRenderer->damageBox(&geomFixed); + const auto WORKSPACE = PMONITOR->activeWorkspace; + const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL; + + startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS)); + readyToDelete = false; + fadingOut = false; + + g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", szNamespace}); + EMIT_HOOK_EVENT("openLayer", self.lock()); + + g_pCompositor->setPreferredScaleForSurface(surface.wlr(), PMONITOR->scale); + g_pCompositor->setPreferredTransformForSurface(surface.wlr(), PMONITOR->transform); +} + +void CLayerSurface::onUnmap() { + Debug::log(LOG, "LayerSurface {:x} unmapped", (uintptr_t)layerSurface); + + g_pEventManager->postEvent(SHyprIPCEvent{"closelayer", std::string(layerSurface->_namespace ? layerSurface->_namespace : "")}); + EMIT_HOOK_EVENT("closeLayer", self.lock()); + + std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); + + if (!g_pInputManager->m_dExclusiveLSes.empty()) + g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0].lock()->layerSurface->surface); + + if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) { + Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring."); + + g_pCompositor->addToFadingOutSafe(self.lock()); + + mapped = false; + + startAnimation(false); + return; + } + + // make a snapshot and start fade + g_pHyprOpenGL->makeLayerSnapshot(self.lock()); + + startAnimation(false); + + mapped = false; + + g_pCompositor->addToFadingOutSafe(self.lock()); + + const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layerSurface->output); + + const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == layerSurface->surface; + + surface = nullptr; + + if (!PMONITOR) + return; + + // refocus if needed + if (WASLASTFOCUS) { + g_pInputManager->releaseAllMouseButtons(); + + Vector2D surfaceCoords; + PHLLS pFoundLayerSurface; + wlr_surface* foundSurface = nullptr; + + g_pCompositor->m_pLastFocus = nullptr; + + // find LS-es to focus + foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], + &surfaceCoords, &pFoundLayerSurface); + + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], + &surfaceCoords, &pFoundLayerSurface); + + if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow.lock()->m_pWorkspace)) { + // if there isn't any, focus the last window + const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); + g_pCompositor->focusWindow(nullptr); + g_pCompositor->focusWindow(PLASTWINDOW); + } else { + // otherwise, full refocus + g_pInputManager->refocus(); + } + } + + CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; + g_pHyprRenderer->damageBox(&geomFixed); + + geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.width, + (int)layerSurface->surface->current.height}; + g_pHyprRenderer->damageBox(&geomFixed); + + g_pInputManager->sendMotionEventsToFocused(); +} + +void CLayerSurface::onCommit() { + if (!layerSurface || !layerSurface->output) + return; + + const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layerSurface->output); + + if (!PMONITOR) + return; + + if (layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) + g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd + + CBox geomFixed = {geometry.x, geometry.y, geometry.width, geometry.height}; + g_pHyprRenderer->damageBox(&geomFixed); + + // fix if it changed its mon + if ((uint64_t)monitorID != PMONITOR->ID) { + const auto POLDMON = g_pCompositor->getMonitorFromID(monitorID); + + for (auto it = POLDMON->m_aLayerSurfaceLayers[layer].begin(); it != POLDMON->m_aLayerSurfaceLayers[layer].end(); it++) { + if (*it == self.lock()) { + PMONITOR->m_aLayerSurfaceLayers[layer].emplace_back(std::move(*it)); + POLDMON->m_aLayerSurfaceLayers[layer].erase(it); + break; + } + } + + monitorID = PMONITOR->ID; + PMONITOR->scheduledRecalc = true; + g_pHyprRenderer->arrangeLayersForMonitor(POLDMON->ID); + } + + if (layerSurface->current.committed != 0) { + if (layer != layerSurface->current.layer) { + + for (auto it = PMONITOR->m_aLayerSurfaceLayers[layer].begin(); it != PMONITOR->m_aLayerSurfaceLayers[layer].end(); it++) { + if (*it == self.lock()) { + PMONITOR->m_aLayerSurfaceLayers[layerSurface->current.layer].emplace_back(std::move(*it)); + PMONITOR->m_aLayerSurfaceLayers[layer].erase(it); + break; + } + } + + layer = layerSurface->current.layer; + + if (layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) + g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd + } + + g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); + + PMONITOR->scheduledRecalc = true; + } else { + position = Vector2D(geometry.x, geometry.y); + + // update geom if it changed + if (layerSurface->surface->current.scale == 1 && PMONITOR->scale != 1.f && layerSurface->surface->current.viewport.has_dst) { + // fractional scaling. Dirty hack. + geometry = {geometry.x, geometry.y, (int)(layerSurface->surface->current.viewport.dst_width), (int)(layerSurface->surface->current.viewport.dst_height)}; + } else { + // this is because some apps like e.g. rofi-lbonn can't fucking use the protocol correctly. + geometry = {geometry.x, geometry.y, (int)layerSurface->surface->current.width, (int)layerSurface->surface->current.height}; + } + } + + if (realPosition.goal() != geometry.pos()) { + if (realPosition.isBeingAnimated()) + realPosition = geometry.pos(); + else + realPosition.setValueAndWarp(geometry.pos()); + } + if (realSize.goal() != geometry.size()) { + if (realSize.isBeingAnimated()) + realSize = geometry.size(); + else + realSize.setValueAndWarp(geometry.size()); + } + + if (layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) // don't focus if constrained + && !keyboardExclusive && mapped) { + g_pCompositor->focusSurface(layerSurface->surface); + + const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y); + wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layerSurface->surface, LOCAL.x, LOCAL.y); + wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y); + g_pInputManager->m_bEmptyFocusCursorSet = false; + } else if (!layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) && keyboardExclusive) { + g_pInputManager->refocus(); + } + + keyboardExclusive = layerSurface->current.keyboard_interactive; + + g_pHyprRenderer->damageSurface(layerSurface->surface, position.x, position.y); + + g_pCompositor->setPreferredScaleForSurface(layerSurface->surface, PMONITOR->scale); + g_pCompositor->setPreferredTransformForSurface(layerSurface->surface, PMONITOR->transform); +} + +void CLayerSurface::applyRules() { + noAnimations = false; + forceBlur = false; + ignoreAlpha = false; + ignoreAlphaValue = 0.f; + dimAround = false; + xray = -1; + animationStyle.reset(); + + for (auto& rule : g_pConfigManager->getMatchingRules(self.lock())) { + if (rule.rule == "noanim") + noAnimations = true; + else if (rule.rule == "blur") + forceBlur = true; + else if (rule.rule == "blurpopups") + forceBlurPopups = true; + else if (rule.rule.starts_with("ignorealpha") || rule.rule.starts_with("ignorezero")) { + const auto FIRST_SPACE_POS = rule.rule.find_first_of(' '); + std::string alphaValue = ""; + if (FIRST_SPACE_POS != std::string::npos) + alphaValue = rule.rule.substr(FIRST_SPACE_POS + 1); + + try { + ignoreAlpha = true; + if (!alphaValue.empty()) + ignoreAlphaValue = std::stof(alphaValue); + } catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); } + } else if (rule.rule == "dimaround") { + dimAround = true; + } else if (rule.rule.starts_with("xray")) { + CVarList vars{rule.rule, 0, ' '}; + try { + xray = configStringToInt(vars[1]); + } catch (...) {} + } else if (rule.rule.starts_with("animation")) { + CVarList vars{rule.rule, 2, 's'}; + animationStyle = vars[1]; + } + } +} + +void CLayerSurface::startAnimation(bool in, bool instant) { + const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle); + if (in) { + realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn"); + realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn"); + alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"); + } else { + realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut"); + realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut"); + alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"); + } + + if (ANIMSTYLE.starts_with("slide")) { + // get closest edge + const auto MIDDLE = geometry.middle(); + + const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE); + + int force = -1; + + CVarList args(ANIMSTYLE, 0, 's'); + if (args.size() > 1) { + const auto ARG2 = args[1]; + if (ARG2 == "top") + force = 0; + else if (ARG2 == "bottom") + force = 1; + else if (ARG2 == "left") + force = 2; + else if (ARG2 == "right") + force = 3; + } + + const std::array edgePoints = { + PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, 0}, + PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, PMONITOR->vecSize.y}, + PMONITOR->vecPosition + Vector2D{0, PMONITOR->vecSize.y}, + PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2}, + }; + + float closest = std::numeric_limits::max(); + int leader = force; + if (leader == -1) { + for (size_t i = 0; i < 4; ++i) { + float dist = MIDDLE.distance(edgePoints[i]); + if (dist < closest) { + leader = i; + closest = dist; + } + } + } + + realSize.setValueAndWarp(geometry.size()); + alpha.setValueAndWarp(in ? 0.f : 1.f); + alpha = in ? 1.f : 0.f; + + Vector2D prePos; + + switch (leader) { + case 0: + // TOP + prePos = {geometry.x, PMONITOR->vecPosition.y - geometry.h}; + break; + case 1: + // BOTTOM + prePos = {geometry.x, PMONITOR->vecPosition.y + PMONITOR->vecSize.y}; + break; + case 2: + // LEFT + prePos = {PMONITOR->vecPosition.x - geometry.w, geometry.y}; + break; + case 3: + // RIGHT + prePos = {PMONITOR->vecPosition.x + PMONITOR->vecSize.x, geometry.y}; + break; + default: UNREACHABLE(); + } + + if (in) { + realPosition.setValueAndWarp(prePos); + realPosition = geometry.pos(); + } else { + realPosition.setValueAndWarp(geometry.pos()); + realPosition = prePos; + } + + } else if (ANIMSTYLE.starts_with("popin")) { + float minPerc = 0.f; + if (ANIMSTYLE.find("%") != std::string::npos) { + try { + auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' ')); + minPerc = std::stoi(percstr.substr(0, percstr.length() - 1)); + } catch (std::exception& e) { + ; // oops + } + } + + minPerc *= 0.01; + + const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5}); + const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f; + + alpha.setValueAndWarp(in ? 0.f : 1.f); + alpha = in ? 1.f : 0.f; + + if (in) { + realSize.setValueAndWarp(GOALSIZE); + realPosition.setValueAndWarp(GOALPOS); + realSize = geometry.size(); + realPosition = geometry.pos(); + } else { + realSize.setValueAndWarp(geometry.size()); + realPosition.setValueAndWarp(geometry.pos()); + realSize = GOALSIZE; + realPosition = GOALPOS; + } + } else { + // fade + realPosition.setValueAndWarp(geometry.pos()); + realSize.setValueAndWarp(geometry.size()); + alpha = in ? 1.f : 0.f; + } + + if (!in) + fadingOut = true; +} + +bool CLayerSurface::isFadedOut() { + if (!fadingOut) + return false; + + return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated(); +} + +int CLayerSurface::popupsCount() { + if (!layerSurface || !mapped || fadingOut) + return 0; + + int no = 0; + wlr_layer_surface_v1_for_each_popup_surface( + layerSurface, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no); + return no; +} \ No newline at end of file diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp new file mode 100644 index 00000000..f1540be5 --- /dev/null +++ b/src/desktop/LayerSurface.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include +#include "../defines.hpp" +#include "WLSurface.hpp" +#include "../helpers/AnimatedVariable.hpp" +#include "wlr-layer-shell-unstable-v1-protocol.h" + +struct SLayerRule { + std::string targetNamespace = ""; + std::string rule = ""; +}; + +class CLayerSurface { + public: + static PHLLS create(wlr_layer_surface_v1*); + + private: + CLayerSurface(); + + public: + ~CLayerSurface(); + + void applyRules(); + void startAnimation(bool in, bool instant = false); + bool isFadedOut(); + int popupsCount(); + + CAnimatedVariable realPosition; + CAnimatedVariable realSize; + CAnimatedVariable alpha; + + wlr_layer_surface_v1* layerSurface; + wl_list link; + + bool keyboardExclusive = false; + + CWLSurface surface; + + bool mapped = false; + + int monitorID = -1; + + bool fadingOut = false; + bool readyToDelete = false; + bool noProcess = false; + bool noAnimations = false; + + bool forceBlur = false; + bool forceBlurPopups = false; + int xray = -1; + bool ignoreAlpha = false; + float ignoreAlphaValue = 0.f; + bool dimAround = false; + + std::optional animationStyle; + + zwlr_layer_shell_v1_layer layer; + + PHLLSREF self; + + CBox geometry = {0, 0, 0, 0}; + Vector2D position; + std::string szNamespace = ""; + + void onDestroy(); + void onMap(); + void onUnmap(); + void onCommit(); + + private: + std::unique_ptr popupHead; + + DYNLISTENER(destroyLayerSurface); + DYNLISTENER(mapLayerSurface); + DYNLISTENER(unmapLayerSurface); + DYNLISTENER(commitLayerSurface); + + void registerCallbacks(); + + // For the list lookup + bool operator==(const CLayerSurface& rhs) const { + return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID; + } +}; \ No newline at end of file diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 527c0b38..3cfebe1b 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -6,7 +6,7 @@ CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) { initAllSignals(); } -CPopup::CPopup(SLayerSurface* pOwner) : m_pLayerOwner(pOwner) { +CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) { initAllSignals(); } diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 26e4bda5..16f011eb 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -4,13 +4,11 @@ #include #include "Subsurface.hpp" -struct SLayerSurface; - class CPopup { public: // dummy head nodes CPopup(PHLWINDOW pOwner); - CPopup(SLayerSurface* pOwner); + CPopup(PHLLS pOwner); // real nodes CPopup(wlr_xdg_popup* popup, CPopup* pOwner); @@ -35,8 +33,8 @@ class CPopup { private: // T1 owners, each popup has to have one of these - PHLWINDOWREF m_pWindowOwner; - SLayerSurface* m_pLayerOwner = nullptr; + PHLWINDOWREF m_pWindowOwner; + PHLLS m_pLayerOwner; // T2 owners CPopup* m_pParent = nullptr; diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 55601a99..41c357e0 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -14,7 +14,7 @@ void CWLSurface::assign(wlr_surface* pSurface, PHLWINDOW pOwner) { m_bInert = false; } -void CWLSurface::assign(wlr_surface* pSurface, SLayerSurface* pOwner) { +void CWLSurface::assign(wlr_surface* pSurface, PHLLS pOwner) { m_pLayerOwner = pOwner; m_pWLRSurface = pSurface; init(); @@ -113,7 +113,7 @@ void CWLSurface::destroy() { hyprListener_commit.removeCallback(); m_pWLRSurface->data = nullptr; m_pWindowOwner.reset(); - m_pLayerOwner = nullptr; + m_pLayerOwner.reset(); m_pPopupOwner = nullptr; m_pSubsurfaceOwner = nullptr; m_bInert = true; @@ -154,8 +154,8 @@ PHLWINDOW CWLSurface::getWindow() { return m_pWindowOwner.lock(); } -SLayerSurface* CWLSurface::getLayer() { - return m_pLayerOwner; +PHLLS CWLSurface::getLayer() { + return m_pLayerOwner.lock(); } CPopup* CWLSurface::getPopup() { @@ -167,7 +167,7 @@ CSubsurface* CWLSurface::getSubsurface() { } bool CWLSurface::desktopComponent() { - return m_pLayerOwner || !m_pWindowOwner.expired() || m_pSubsurfaceOwner || m_pPopupOwner; + return !m_pLayerOwner.expired() || !m_pWindowOwner.expired() || m_pSubsurfaceOwner || m_pPopupOwner; } std::optional CWLSurface::getSurfaceBoxGlobal() { @@ -176,8 +176,8 @@ std::optional CWLSurface::getSurfaceBoxGlobal() { if (!m_pWindowOwner.expired()) return m_pWindowOwner.lock()->getWindowMainSurfaceBox(); - if (m_pLayerOwner) - return m_pLayerOwner->geometry; + if (!m_pLayerOwner.expired()) + return m_pLayerOwner.lock()->geometry; if (m_pPopupOwner) return CBox{m_pPopupOwner->coordsGlobal(), m_pPopupOwner->size()}; if (m_pSubsurfaceOwner) diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index ffb81cc0..752f4d11 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -4,8 +4,6 @@ #include "../helpers/Region.hpp" #include "../helpers/signal/Signal.hpp" -class CWindow; -struct SLayerSurface; class CSubsurface; class CPopup; class CPointerConstraint; @@ -18,7 +16,7 @@ class CWLSurface { // anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD void assign(wlr_surface* pSurface); void assign(wlr_surface* pSurface, PHLWINDOW pOwner); - void assign(wlr_surface* pSurface, SLayerSurface* pOwner); + void assign(wlr_surface* pSurface, PHLLS pOwner); void assign(wlr_surface* pSurface, CSubsurface* pOwner); void assign(wlr_surface* pSurface, CPopup* pOwner); void unassign(); @@ -37,10 +35,10 @@ class CWLSurface { void onCommit(); // getters for owners. - PHLWINDOW getWindow(); - SLayerSurface* getLayer(); - CPopup* getPopup(); - CSubsurface* getSubsurface(); + PHLWINDOW getWindow(); + PHLLS getLayer(); + CPopup* getPopup(); + CSubsurface* getSubsurface(); // desktop components misc utils std::optional getSurfaceBoxGlobal(); @@ -90,14 +88,14 @@ class CWLSurface { } events; private: - bool m_bInert = true; + bool m_bInert = true; - wlr_surface* m_pWLRSurface = nullptr; + wlr_surface* m_pWLRSurface = nullptr; - PHLWINDOWREF m_pWindowOwner; - SLayerSurface* m_pLayerOwner = nullptr; - CPopup* m_pPopupOwner = nullptr; - CSubsurface* m_pSubsurfaceOwner = nullptr; + PHLWINDOWREF m_pWindowOwner; + PHLLSREF m_pLayerOwner; + CPopup* m_pPopupOwner = nullptr; + CSubsurface* m_pSubsurfaceOwner = nullptr; // std::weak_ptr m_pConstraint; diff --git a/src/events/Events.hpp b/src/events/Events.hpp index 63eab66d..f147c6bf 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -17,10 +17,6 @@ namespace Events { // Layer events LISTENER(newLayerSurface); - DYNLISTENFUNC(destroyLayerSurface); - DYNLISTENFUNC(mapLayerSurface); - DYNLISTENFUNC(unmapLayerSurface); - DYNLISTENFUNC(commitLayerSurface); // Surface XDG (window) LISTENER(newXDGToplevel); diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp deleted file mode 100644 index 1877822a..00000000 --- a/src/events/Layers.cpp +++ /dev/null @@ -1,364 +0,0 @@ -#include "../Compositor.hpp" -#include "../helpers/WLClasses.hpp" -#include "../managers/input/InputManager.hpp" -#include "../render/Renderer.hpp" -#include "Events.hpp" - -// --------------------------------------------- // -// _ __ ________ _____ _____ // -// | | /\\ \ / / ____| __ \ / ____| // -// | | / \\ \_/ /| |__ | |__) | (___ // -// | | / /\ \\ / | __| | _ / \___ \ // -// | |____ / ____ \| | | |____| | \ \ ____) | // -// |______/_/ \_\_| |______|_| \_\_____/ // -// // -// --------------------------------------------- // - -void Events::listener_newLayerSurface(wl_listener* listener, void* data) { - const auto WLRLAYERSURFACE = (wlr_layer_surface_v1*)data; - - if (!WLRLAYERSURFACE->output) { - const auto PMONITOR = g_pCompositor->getMonitorFromCursor(); - - if (!PMONITOR) { - Debug::log(ERR, "No monitor at cursor on new layer without a monitor. Ignoring."); - wlr_layer_surface_v1_destroy(WLRLAYERSURFACE); - return; - } - - Debug::log(LOG, "New LayerSurface has no preferred monitor. Assigning Monitor {}", PMONITOR->szName); - - WLRLAYERSURFACE->output = PMONITOR->output; - } - - auto PMONITOR = (CMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output); - - if (!WLRLAYERSURFACE->output || !PMONITOR || PMONITOR->pMirrorOf) { - PMONITOR = g_pCompositor->m_vMonitors.front().get(); - WLRLAYERSURFACE->output = PMONITOR->output; // TODO: current mon - } - - SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLayers[WLRLAYERSURFACE->pending.layer].emplace_back(std::make_unique()).get(); - - layerSurface->szNamespace = WLRLAYERSURFACE->_namespace; - - layerSurface->hyprListener_commitLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.commit, &Events::listener_commitLayerSurface, layerSurface, "layerSurface"); - layerSurface->hyprListener_destroyLayerSurface.initCallback(&WLRLAYERSURFACE->events.destroy, &Events::listener_destroyLayerSurface, layerSurface, "layerSurface"); - layerSurface->hyprListener_mapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.map, &Events::listener_mapLayerSurface, layerSurface, "layerSurface"); - layerSurface->hyprListener_unmapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.unmap, &Events::listener_unmapLayerSurface, layerSurface, "layerSurface"); - - layerSurface->layerSurface = WLRLAYERSURFACE; - layerSurface->layer = WLRLAYERSURFACE->current.layer; - WLRLAYERSURFACE->data = layerSurface; - layerSurface->monitorID = PMONITOR->ID; - layerSurface->popupHead = std::make_unique(layerSurface); - - layerSurface->forceBlur = g_pConfigManager->shouldBlurLS(layerSurface->szNamespace); - - Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)layerSurface->layerSurface, layerSurface->layerSurface->_namespace, - (int)layerSurface->layer, PMONITOR->szName); -} - -void Events::listener_destroyLayerSurface(void* owner, void* data) { - SLayerSurface* layersurface = (SLayerSurface*)owner; - - Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layersurface->layerSurface); - - const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID); - - layersurface->popupHead.reset(); - - if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) - Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)"); - - if (!layersurface->fadingOut) { - if (layersurface->mapped) { - Debug::log(LOG, "Forcing an unmap of a LS that did a straight destroy!"); - listener_unmapLayerSurface(layersurface, nullptr); - } else { - Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); - layersurface->alpha.setValueAndWarp(0.f); - layersurface->fadingOut = true; - g_pCompositor->addToFadingOutSafe(layersurface); - } - } - - layersurface->noProcess = true; - - layersurface->hyprListener_commitLayerSurface.removeCallback(); - layersurface->hyprListener_destroyLayerSurface.removeCallback(); - layersurface->hyprListener_mapLayerSurface.removeCallback(); - layersurface->hyprListener_unmapLayerSurface.removeCallback(); - - // rearrange to fix the reserved areas - if (PMONITOR) { - g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); - PMONITOR->scheduledRecalc = true; - - // and damage - CBox geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, - layersurface->geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); - } - - layersurface->readyToDelete = true; - layersurface->layerSurface = nullptr; -} - -void Events::listener_mapLayerSurface(void* owner, void* data) { - SLayerSurface* layersurface = (SLayerSurface*)owner; - - Debug::log(LOG, "LayerSurface {:x} mapped", (uintptr_t)layersurface->layerSurface); - - layersurface->mapped = true; - layersurface->keyboardExclusive = layersurface->layerSurface->current.keyboard_interactive; - layersurface->surface = layersurface->layerSurface->surface; - - // fix if it changed its mon - const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output); - - if (!PMONITOR) - return; - - layersurface->applyRules(); - - if ((uint64_t)layersurface->monitorID != PMONITOR->ID) { - const auto POLDMON = g_pCompositor->getMonitorFromID(layersurface->monitorID); - for (auto it = POLDMON->m_aLayerSurfaceLayers[layersurface->layer].begin(); it != POLDMON->m_aLayerSurfaceLayers[layersurface->layer].end(); it++) { - if (it->get() == layersurface) { - PMONITOR->m_aLayerSurfaceLayers[layersurface->layer].emplace_back(std::move(*it)); - POLDMON->m_aLayerSurfaceLayers[layersurface->layer].erase(it); - break; - } - } - layersurface->monitorID = PMONITOR->ID; - PMONITOR->scheduledRecalc = true; - g_pHyprRenderer->arrangeLayersForMonitor(POLDMON->ID); - } - - g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); - - wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output); - - if (layersurface->layerSurface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) - g_pInputManager->m_dExclusiveLSes.push_back(layersurface); - - const bool GRABSFOCUS = layersurface->layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && - // don't focus if constrained - (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()); - - if (GRABSFOCUS) { - g_pInputManager->releaseAllMouseButtons(); - g_pCompositor->focusSurface(layersurface->layerSurface->surface); - - const auto LOCAL = - g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y); - wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y); - wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y); - g_pInputManager->m_bEmptyFocusCursorSet = false; - } - - layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y); - - CBox geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, - layersurface->geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); - const auto WORKSPACE = PMONITOR->activeWorkspace; - const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL; - - layersurface->startAnimation(!(layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS)); - layersurface->readyToDelete = false; - layersurface->fadingOut = false; - - g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", std::string(layersurface->layerSurface->_namespace ? layersurface->layerSurface->_namespace : "")}); - EMIT_HOOK_EVENT("openLayer", layersurface); - - g_pCompositor->setPreferredScaleForSurface(layersurface->layerSurface->surface, PMONITOR->scale); - g_pCompositor->setPreferredTransformForSurface(layersurface->layerSurface->surface, PMONITOR->transform); -} - -void Events::listener_unmapLayerSurface(void* owner, void* data) { - SLayerSurface* layersurface = (SLayerSurface*)owner; - - Debug::log(LOG, "LayerSurface {:x} unmapped", (uintptr_t)layersurface->layerSurface); - - g_pEventManager->postEvent(SHyprIPCEvent{"closelayer", std::string(layersurface->layerSurface->_namespace ? layersurface->layerSurface->_namespace : "")}); - EMIT_HOOK_EVENT("closeLayer", layersurface); - - std::erase(g_pInputManager->m_dExclusiveLSes, layersurface); - - if (!g_pInputManager->m_dExclusiveLSes.empty()) - g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->layerSurface->surface); - - if (!g_pCompositor->getMonitorFromID(layersurface->monitorID) || g_pCompositor->m_bUnsafeState) { - Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring."); - - g_pCompositor->addToFadingOutSafe(layersurface); - - layersurface->mapped = false; - - layersurface->startAnimation(false); - return; - } - - // make a snapshot and start fade - g_pHyprOpenGL->makeLayerSnapshot(layersurface); - - layersurface->startAnimation(false); - - layersurface->mapped = false; - - g_pCompositor->addToFadingOutSafe(layersurface); - - const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output); - - const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == layersurface->layerSurface->surface; - - layersurface->surface = nullptr; - - if (!PMONITOR) - return; - - // refocus if needed - if (WASLASTFOCUS) { - g_pInputManager->releaseAllMouseButtons(); - - Vector2D surfaceCoords; - SLayerSurface* pFoundLayerSurface = nullptr; - wlr_surface* foundSurface = nullptr; - - g_pCompositor->m_pLastFocus = nullptr; - - // find LS-es to focus - foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], - &surfaceCoords, &pFoundLayerSurface); - - if (!foundSurface) - foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], - &surfaceCoords, &pFoundLayerSurface); - - if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow.lock()->m_pWorkspace)) { - // if there isn't any, focus the last window - const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); - g_pCompositor->focusWindow(nullptr); - g_pCompositor->focusWindow(PLASTWINDOW); - } else { - // otherwise, full refocus - g_pInputManager->refocus(); - } - } - - CBox geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, - layersurface->geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); - - geomFixed = {layersurface->geometry.x + (int)PMONITOR->vecPosition.x, layersurface->geometry.y + (int)PMONITOR->vecPosition.y, - (int)layersurface->layerSurface->surface->current.width, (int)layersurface->layerSurface->surface->current.height}; - g_pHyprRenderer->damageBox(&geomFixed); - - g_pInputManager->sendMotionEventsToFocused(); -} - -void Events::listener_commitLayerSurface(void* owner, void* data) { - SLayerSurface* layersurface = (SLayerSurface*)owner; - - if (!layersurface->layerSurface || !layersurface->layerSurface->output) - return; - - const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output); - - if (!PMONITOR) - return; - - if (layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) - g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd - - CBox geomFixed = {layersurface->geometry.x, layersurface->geometry.y, layersurface->geometry.width, layersurface->geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); - - // fix if it changed its mon - if ((uint64_t)layersurface->monitorID != PMONITOR->ID) { - const auto POLDMON = g_pCompositor->getMonitorFromID(layersurface->monitorID); - - for (auto it = POLDMON->m_aLayerSurfaceLayers[layersurface->layer].begin(); it != POLDMON->m_aLayerSurfaceLayers[layersurface->layer].end(); it++) { - if (it->get() == layersurface) { - PMONITOR->m_aLayerSurfaceLayers[layersurface->layer].emplace_back(std::move(*it)); - POLDMON->m_aLayerSurfaceLayers[layersurface->layer].erase(it); - break; - } - } - - layersurface->monitorID = PMONITOR->ID; - PMONITOR->scheduledRecalc = true; - g_pHyprRenderer->arrangeLayersForMonitor(POLDMON->ID); - } - - if (layersurface->layerSurface->current.committed != 0) { - if (layersurface->layer != layersurface->layerSurface->current.layer) { - - for (auto it = PMONITOR->m_aLayerSurfaceLayers[layersurface->layer].begin(); it != PMONITOR->m_aLayerSurfaceLayers[layersurface->layer].end(); it++) { - if (it->get() == layersurface) { - PMONITOR->m_aLayerSurfaceLayers[layersurface->layerSurface->current.layer].emplace_back(std::move(*it)); - PMONITOR->m_aLayerSurfaceLayers[layersurface->layer].erase(it); - break; - } - } - - layersurface->layer = layersurface->layerSurface->current.layer; - - if (layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) - g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd - } - - g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); - - PMONITOR->scheduledRecalc = true; - } else { - layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y); - - // update geom if it changed - if (layersurface->layerSurface->surface->current.scale == 1 && PMONITOR->scale != 1.f && layersurface->layerSurface->surface->current.viewport.has_dst) { - // fractional scaling. Dirty hack. - layersurface->geometry = {layersurface->geometry.x, layersurface->geometry.y, (int)(layersurface->layerSurface->surface->current.viewport.dst_width), - (int)(layersurface->layerSurface->surface->current.viewport.dst_height)}; - } else { - // this is because some apps like e.g. rofi-lbonn can't fucking use the protocol correctly. - layersurface->geometry = {layersurface->geometry.x, layersurface->geometry.y, (int)layersurface->layerSurface->surface->current.width, - (int)layersurface->layerSurface->surface->current.height}; - } - } - - if (layersurface->realPosition.goal() != layersurface->geometry.pos()) { - if (layersurface->realPosition.isBeingAnimated()) - layersurface->realPosition = layersurface->geometry.pos(); - else - layersurface->realPosition.setValueAndWarp(layersurface->geometry.pos()); - } - if (layersurface->realSize.goal() != layersurface->geometry.size()) { - if (layersurface->realSize.isBeingAnimated()) - layersurface->realSize = layersurface->geometry.size(); - else - layersurface->realSize.setValueAndWarp(layersurface->geometry.size()); - } - - if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) // don't focus if constrained - && !layersurface->keyboardExclusive && layersurface->mapped) { - g_pCompositor->focusSurface(layersurface->layerSurface->surface); - - const auto LOCAL = - g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y); - wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y); - wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y); - g_pInputManager->m_bEmptyFocusCursorSet = false; - } else if (!layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) && - layersurface->keyboardExclusive) { - g_pInputManager->refocus(); - } - - layersurface->keyboardExclusive = layersurface->layerSurface->current.keyboard_interactive; - - g_pHyprRenderer->damageSurface(layersurface->layerSurface->surface, layersurface->position.x, layersurface->position.y); - - g_pCompositor->setPreferredScaleForSurface(layersurface->layerSurface->surface, PMONITOR->scale); - g_pCompositor->setPreferredTransformForSurface(layersurface->layerSurface->surface, PMONITOR->transform); -} diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp index 0d6f15aa..bdfb4b77 100644 --- a/src/helpers/AnimatedVariable.cpp +++ b/src/helpers/AnimatedVariable.cpp @@ -14,7 +14,7 @@ void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWIN m_bDummy = false; } -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy) { +void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, AVARDAMAGEPOLICY policy) { m_eDamagePolicy = policy; m_pConfig = pAnimConfig; m_pLayer = pLayer; diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 02849306..be54392a 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -49,11 +49,11 @@ enum AVARDAMAGEPOLICY { }; class CAnimationManager; -struct SLayerSurface; struct SAnimationPropertyConfig; class CHyprRenderer; class CWindow; class CWorkspace; +class CLayerSurface; // Utility to define a concept as a list of possible type template @@ -69,7 +69,7 @@ class CBaseAnimatedVariable { public: CBaseAnimatedVariable(ANIMATEDVARTYPE type); void create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, AVARDAMAGEPOLICY policy); - void create(SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy); + void create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, AVARDAMAGEPOLICY policy); void create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, AVARDAMAGEPOLICY policy); void create(SAnimationPropertyConfig* pAnimConfig, AVARDAMAGEPOLICY policy); @@ -147,7 +147,7 @@ class CBaseAnimatedVariable { protected: PHLWINDOWREF m_pWindow; std::weak_ptr m_pWorkspace; - void* m_pLayer = nullptr; + PHLLSREF m_pLayer; SAnimationPropertyConfig* m_pConfig = nullptr; @@ -199,7 +199,7 @@ class CBaseAnimatedVariable { friend class CAnimationManager; friend class CWorkspace; - friend struct SLayerSurface; + friend class CLayerSurface; friend class CHyprRenderer; }; @@ -213,7 +213,7 @@ class CAnimatedVariable : public CBaseAnimatedVariable { m_Value = value; m_Goal = value; } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy) { + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, AVARDAMAGEPOLICY policy) { create(pAnimConfig, pLayer, policy); m_Value = value; m_Goal = value; @@ -304,6 +304,6 @@ class CAnimatedVariable : public CBaseAnimatedVariable { friend class CAnimationManager; friend class CWorkspace; - friend struct SLayerSurface; + friend class CLayerSurface; friend class CHyprRenderer; }; diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 9fd9ee2f..81997514 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -137,7 +137,7 @@ class CMonitor { CSignal modeChanged; } events; - std::array>, 4> m_aLayerSurfaceLayers; + std::array, 4> m_aLayerSurfaceLayers; DYNLISTENER(monitorFrame); DYNLISTENER(monitorDestroy); diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 2e669e4f..4cdde4a0 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -1,215 +1,4 @@ #include "WLClasses.hpp" -#include "../config/ConfigManager.hpp" -#include "../Compositor.hpp" - -SLayerSurface::SLayerSurface() { - alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), this, AVARDAMAGE_ENTIRE); - realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), this, AVARDAMAGE_ENTIRE); - realSize.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), this, AVARDAMAGE_ENTIRE); - alpha.registerVar(); - realPosition.registerVar(); - realSize.registerVar(); - - alpha.setUpdateCallback([this](void*) { - if (dimAround) - g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(monitorID)); - }); - - alpha.setValueAndWarp(0.f); -} - -SLayerSurface::~SLayerSurface() { - if (!g_pHyprOpenGL) - return; - - g_pHyprRenderer->makeEGLCurrent(); - std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first == this; }); -} - -void SLayerSurface::applyRules() { - noAnimations = false; - forceBlur = false; - ignoreAlpha = false; - ignoreAlphaValue = 0.f; - dimAround = false; - xray = -1; - animationStyle.reset(); - - for (auto& rule : g_pConfigManager->getMatchingRules(this)) { - if (rule.rule == "noanim") - noAnimations = true; - else if (rule.rule == "blur") - forceBlur = true; - else if (rule.rule == "blurpopups") - forceBlurPopups = true; - else if (rule.rule.starts_with("ignorealpha") || rule.rule.starts_with("ignorezero")) { - const auto FIRST_SPACE_POS = rule.rule.find_first_of(' '); - std::string alphaValue = ""; - if (FIRST_SPACE_POS != std::string::npos) - alphaValue = rule.rule.substr(FIRST_SPACE_POS + 1); - - try { - ignoreAlpha = true; - if (!alphaValue.empty()) - ignoreAlphaValue = std::stof(alphaValue); - } catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); } - } else if (rule.rule == "dimaround") { - dimAround = true; - } else if (rule.rule.starts_with("xray")) { - CVarList vars{rule.rule, 0, ' '}; - try { - xray = configStringToInt(vars[1]); - } catch (...) {} - } else if (rule.rule.starts_with("animation")) { - CVarList vars{rule.rule, 2, 's'}; - animationStyle = vars[1]; - } - } -} - -void SLayerSurface::startAnimation(bool in, bool instant) { - const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle); - if (in) { - realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn"); - realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn"); - alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"); - } else { - realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut"); - realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut"); - alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"); - } - - if (ANIMSTYLE.starts_with("slide")) { - // get closest edge - const auto MIDDLE = geometry.middle(); - - const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE); - - int force = -1; - - CVarList args(ANIMSTYLE, 0, 's'); - if (args.size() > 1) { - const auto ARG2 = args[1]; - if (ARG2 == "top") - force = 0; - else if (ARG2 == "bottom") - force = 1; - else if (ARG2 == "left") - force = 2; - else if (ARG2 == "right") - force = 3; - } - - const std::array edgePoints = { - PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, 0}, - PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, PMONITOR->vecSize.y}, - PMONITOR->vecPosition + Vector2D{0, PMONITOR->vecSize.y}, - PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2}, - }; - - float closest = std::numeric_limits::max(); - int leader = force; - if (leader == -1) { - for (size_t i = 0; i < 4; ++i) { - float dist = MIDDLE.distance(edgePoints[i]); - if (dist < closest) { - leader = i; - closest = dist; - } - } - } - - realSize.setValueAndWarp(geometry.size()); - alpha.setValueAndWarp(in ? 0.f : 1.f); - alpha = in ? 1.f : 0.f; - - Vector2D prePos; - - switch (leader) { - case 0: - // TOP - prePos = {geometry.x, PMONITOR->vecPosition.y - geometry.h}; - break; - case 1: - // BOTTOM - prePos = {geometry.x, PMONITOR->vecPosition.y + PMONITOR->vecSize.y}; - break; - case 2: - // LEFT - prePos = {PMONITOR->vecPosition.x - geometry.w, geometry.y}; - break; - case 3: - // RIGHT - prePos = {PMONITOR->vecPosition.x + PMONITOR->vecSize.x, geometry.y}; - break; - default: UNREACHABLE(); - } - - if (in) { - realPosition.setValueAndWarp(prePos); - realPosition = geometry.pos(); - } else { - realPosition.setValueAndWarp(geometry.pos()); - realPosition = prePos; - } - - } else if (ANIMSTYLE.starts_with("popin")) { - float minPerc = 0.f; - if (ANIMSTYLE.find("%") != std::string::npos) { - try { - auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' ')); - minPerc = std::stoi(percstr.substr(0, percstr.length() - 1)); - } catch (std::exception& e) { - ; // oops - } - } - - minPerc *= 0.01; - - const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5}); - const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f; - - alpha.setValueAndWarp(in ? 0.f : 1.f); - alpha = in ? 1.f : 0.f; - - if (in) { - realSize.setValueAndWarp(GOALSIZE); - realPosition.setValueAndWarp(GOALPOS); - realSize = geometry.size(); - realPosition = geometry.pos(); - } else { - realSize.setValueAndWarp(geometry.size()); - realPosition.setValueAndWarp(geometry.pos()); - realSize = GOALSIZE; - realPosition = GOALPOS; - } - } else { - // fade - realPosition.setValueAndWarp(geometry.pos()); - realSize.setValueAndWarp(geometry.size()); - alpha = in ? 1.f : 0.f; - } - - if (!in) - fadingOut = true; -} - -bool SLayerSurface::isFadedOut() { - if (!fadingOut) - return false; - - return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated(); -} - -int SLayerSurface::popupsCount() { - if (!layerSurface || !mapped || fadingOut) - return 0; - - int no = 0; - wlr_layer_surface_v1_for_each_popup_surface( - layerSurface, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no); - return no; -} void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { xkb_state_unref(xkbTranslationState); diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 8066baf9..024ac38d 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -2,7 +2,6 @@ #include "../events/Events.hpp" #include "../defines.hpp" -#include "wlr-layer-shell-unstable-v1-protocol.h" #include "../desktop/Window.hpp" #include "../desktop/Subsurface.hpp" #include "../desktop/Popup.hpp" @@ -10,69 +9,6 @@ #include "../desktop/WLSurface.hpp" #include "Region.hpp" -struct SLayerRule { - std::string targetNamespace = ""; - std::string rule = ""; -}; - -struct SLayerSurface { - SLayerSurface(); - ~SLayerSurface(); - - void applyRules(); - void startAnimation(bool in, bool instant = false); - bool isFadedOut(); - int popupsCount(); - - CAnimatedVariable realPosition; - CAnimatedVariable realSize; - - wlr_layer_surface_v1* layerSurface; - wl_list link; - - bool keyboardExclusive = false; - - CWLSurface surface; - - // desktop components - std::unique_ptr popupHead; - - DYNLISTENER(destroyLayerSurface); - DYNLISTENER(mapLayerSurface); - DYNLISTENER(unmapLayerSurface); - DYNLISTENER(commitLayerSurface); - - CBox geometry = {0, 0, 0, 0}; - Vector2D position; - zwlr_layer_shell_v1_layer layer; - - bool mapped = false; - - int monitorID = -1; - - std::string szNamespace = ""; - - CAnimatedVariable alpha; - bool fadingOut = false; - bool readyToDelete = false; - bool noProcess = false; - bool noAnimations = false; - - bool forceBlur = false; - bool forceBlurPopups = false; - int xray = -1; - bool ignoreAlpha = false; - float ignoreAlphaValue = 0.f; - bool dimAround = false; - - std::optional animationStyle; - - // For the list lookup - bool operator==(const SLayerSurface& rhs) const { - return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID; - } -}; - class CMonitor; struct SRenderData { diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 54bdc524..c39df580 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -4,6 +4,7 @@ #include "macros.hpp" #include "../config/ConfigValue.hpp" #include "../desktop/Window.hpp" +#include "../desktop/LayerSurface.hpp" #include "eventLoop/EventLoopManager.hpp" int wlTick(std::shared_ptr self, void* data) { @@ -82,7 +83,7 @@ void CAnimationManager::tick() { // window stuff PHLWINDOW PWINDOW = av->m_pWindow.lock(); PHLWORKSPACE PWORKSPACE = av->m_pWorkspace.lock(); - const auto PLAYER = (SLayerSurface*)av->m_pLayer; + PHLLS PLAYER = av->m_pLayer.lock(); CMonitor* PMONITOR = nullptr; bool animationsDisabled = animGlobalDisabled; @@ -141,7 +142,7 @@ void CAnimationManager::tick() { expandBox.expand(5); g_pHyprRenderer->damageBox(&expandBox); - PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f); + PMONITOR = g_pCompositor->getMonitorFromVector(PLAYER->realPosition.goal() + PLAYER->realSize.goal() / 2.F); if (!PMONITOR) continue; animationsDisabled = animationsDisabled || PLAYER->noAnimations; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 47dc2bf6..72c1772c 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -120,13 +120,13 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { const auto FOLLOWMOUSE = *PFOLLOWONDND && m_sDrag.drag ? 1 : *PFOLLOWMOUSE; m_pFoundSurfaceToFocus = nullptr; - m_pFoundLSToFocus = nullptr; + m_pFoundLSToFocus.reset(); m_pFoundWindowToFocus.reset(); - wlr_surface* foundSurface = nullptr; - Vector2D surfaceCoords; - Vector2D surfacePos = Vector2D(-1337, -1337); - PHLWINDOW pFoundWindow; - SLayerSurface* pFoundLayerSurface = nullptr; + wlr_surface* foundSurface = nullptr; + Vector2D surfaceCoords; + Vector2D surfacePos = Vector2D(-1337, -1337); + PHLWINDOW pFoundWindow; + PHLLS pFoundLayerSurface; if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState) return; diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index e20bca2a..08e9e831 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -38,10 +38,10 @@ enum eBorderIconDirection { }; struct STouchData { - PHLWINDOWREF touchFocusWindow; - SLayerSurface* touchFocusLS = nullptr; - wlr_surface* touchFocusSurface = nullptr; - Vector2D touchSurfaceOrigin; + PHLWINDOWREF touchFocusWindow; + PHLLSREF touchFocusLS; + wlr_surface* touchFocusSurface = nullptr; + Vector2D touchSurfaceOrigin; }; // The third row is always 0 0 1 and is not expected by `libinput_device_config_calibration_set_matrix` @@ -138,7 +138,7 @@ class CInputManager { std::list m_lSwitches; // Exclusive layer surfaces - std::deque m_dExclusiveLSes; + std::deque m_dExclusiveLSes; // constraints std::vector> m_vConstraints; @@ -224,9 +224,9 @@ class CInputManager { void applyConfigToKeyboard(SKeyboard*); // this will be set after a refocus() - wlr_surface* m_pFoundSurfaceToFocus = nullptr; - SLayerSurface* m_pFoundLSToFocus = nullptr; - PHLWINDOWREF m_pFoundWindowToFocus; + wlr_surface* m_pFoundSurfaceToFocus = nullptr; + PHLLSREF m_pFoundLSToFocus; + PHLWINDOWREF m_pFoundWindowToFocus; // for holding focus on buttons held bool m_bFocusHeldByButtons = false; diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index a3f28ac0..91f4ada6 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -37,7 +37,7 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { if (m_sActiveSwipe.pWorkspaceBegin) { return; // TODO: Don't swipe if you touched a floating window. - } else if (*PSWIPETOUCH && (!m_pFoundLSToFocus || m_pFoundLSToFocus->layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)) { + } else if (*PSWIPETOUCH && (m_pFoundLSToFocus.expired() || m_pFoundLSToFocus.lock()->layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)) { const auto PWORKSPACE = PMONITOR->activeWorkspace; const bool VERTANIMS = PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); @@ -74,8 +74,8 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), m_sTouchData.touchFocusWindow.lock(), local); m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local; } - } else if (m_sTouchData.touchFocusLS) { - local = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_sTouchData.touchFocusLS->geometry.x, m_sTouchData.touchFocusLS->geometry.y); + } else if (!m_sTouchData.touchFocusLS.expired()) { + local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusLS.lock()->geometry.pos(); m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local; } else { @@ -139,8 +139,8 @@ void CInputManager::onTouchMove(wlr_touch_motion_event* e) { wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y); // wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, local.x, local.y); - } else if (m_sTouchData.touchFocusLS) { - const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS->monitorID); + } else if (!m_sTouchData.touchFocusLS.expired()) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS.lock()->monitorID); wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PMONITOR->vecPosition.x + e->x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e->y * PMONITOR->vecSize.y); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 78698505..31625b3b 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -5,6 +5,7 @@ #include "Shaders.hpp" #include #include "../config/ConfigValue.hpp" +#include "../desktop/LayerSurface.hpp" inline void loadGLProc(void* pProc, const char* name) { void* proc = (void*)eglGetProcAddress(name); @@ -1453,7 +1454,7 @@ bool CHyprOpenGLImpl::preBlurQueued() { return !(!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE || !*PBLUR || !m_RenderData.pCurrentMonData->blurFBShouldRender); } -bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, PHLWINDOW pWindow) { +bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow) { static auto PBLURNEWOPTIMIZE = CConfigValue("decoration:blur:new_optimizations"); static auto PBLURXRAY = CConfigValue("decoration:blur:xray"); @@ -1781,7 +1782,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(PHLWINDOW pWindow) { g_pHyprRenderer->m_bRenderingSnapshot = false; } -void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) { +void CHyprOpenGLImpl::makeLayerSnapshot(PHLLS pLayer) { // we trust the window is valid. const auto PMONITOR = g_pCompositor->getMonitorFromID(pLayer->monitorID); @@ -1864,38 +1865,35 @@ void CHyprOpenGLImpl::renderSnapshot(PHLWINDOW pWindow) { m_bEndFrame = false; } -void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) { +void CHyprOpenGLImpl::renderSnapshot(PHLLS pLayer) { RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!"); - const auto PLAYER = *pLayer; - auto it = m_mLayerFramebuffers.begin(); - for (; it != m_mLayerFramebuffers.end(); it++) { - if (it->first == PLAYER) { - break; - } - } - - if (it == m_mLayerFramebuffers.end() || !it->second.m_cTex.m_iTexID) + if (!m_mLayerFramebuffers.contains(pLayer)) return; - const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID); + const auto FBDATA = &m_mLayerFramebuffers.at(pLayer); + + if (!FBDATA->m_cTex.m_iTexID) + return; + + const auto PMONITOR = g_pCompositor->getMonitorFromID(pLayer->monitorID); CBox layerBox; // some mafs to figure out the correct box // the originalClosedPos is relative to the monitor's pos - Vector2D scaleXY = Vector2D((PMONITOR->scale * PLAYER->realSize.value().x / (PLAYER->geometry.w * PMONITOR->scale)), - (PMONITOR->scale * PLAYER->realSize.value().y / (PLAYER->geometry.h * PMONITOR->scale))); + Vector2D scaleXY = Vector2D((PMONITOR->scale * pLayer->realSize.value().x / (pLayer->geometry.w * PMONITOR->scale)), + (PMONITOR->scale * pLayer->realSize.value().y / (pLayer->geometry.h * PMONITOR->scale))); layerBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; layerBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; - layerBox.x = ((PLAYER->realPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((PLAYER->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x); - layerBox.y = ((PLAYER->realPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((PLAYER->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y); + layerBox.x = ((pLayer->realPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((pLayer->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x); + layerBox.y = ((pLayer->realPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((pLayer->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y); CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; m_bEndFrame = true; - renderTextureInternalWithDamage(it->second.m_cTex, &layerBox, PLAYER->alpha.value(), &fakeDamage, 0); + renderTextureInternalWithDamage(FBDATA->m_cTex, &layerBox, pLayer->alpha.value(), &fakeDamage, 0); m_bEndFrame = false; } diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index bbd022e7..f13d506b 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -154,10 +154,10 @@ class CHyprOpenGLImpl { void makeWindowSnapshot(PHLWINDOW); void makeRawWindowSnapshot(PHLWINDOW, CFramebuffer*); - void makeLayerSnapshot(SLayerSurface*); + void makeLayerSnapshot(PHLLS); void renderSnapshot(PHLWINDOW); - void renderSnapshot(SLayerSurface**); - bool shouldUseNewBlurOptimizations(SLayerSurface* pLayer, PHLWINDOW pWindow); + void renderSnapshot(PHLLS); + bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); void clear(const CColor&); void clearWithTex(); @@ -193,11 +193,11 @@ class CHyprOpenGLImpl { bool m_bReloadScreenShader = true; // at launch it can be set - PHLWINDOWREF m_pCurrentWindow; // hack to get the current rendered window - SLayerSurface* m_pCurrentLayer = nullptr; // hack to get the current rendered layer + PHLWINDOWREF m_pCurrentWindow; // hack to get the current rendered window + PHLLS m_pCurrentLayer; // hack to get the current rendered layer std::map> m_mWindowFramebuffers; - std::unordered_map m_mLayerFramebuffers; + std::map> m_mLayerFramebuffers; std::unordered_map m_mMonitorRenderResources; std::unordered_map m_mMonitorBGFBs; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index e34e6a72..6b1545b1 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -6,6 +6,7 @@ #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" #include "../desktop/Window.hpp" +#include "../desktop/LayerSurface.hpp" extern "C" { #include @@ -662,7 +663,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, CMonitor* pMonitor, timespec g_pHyprOpenGL->m_RenderData.clipBox = CBox(); } -void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time, bool popups) { +void CHyprRenderer::renderLayer(PHLLS pLayer, CMonitor* pMonitor, timespec* time, bool popups) { static auto PDIMAROUND = CConfigValue("decoration:dim_around"); if (*PDIMAROUND && pLayer->dimAround && !m_bRenderingSnapshot && !popups) { @@ -672,7 +673,7 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times if (pLayer->fadingOut) { if (!popups) - g_pHyprOpenGL->renderSnapshot(&pLayer); + g_pHyprOpenGL->renderSnapshot(pLayer); return; } @@ -786,16 +787,16 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC g_pHyprOpenGL->blend(true); for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } g_pHyprOpenGL->m_RenderData.renderModif = {}; @@ -826,10 +827,10 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC g_pHyprOpenGL->blend(true); for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } g_pHyprOpenGL->m_RenderData.damage = preOccludedDamage; @@ -896,7 +897,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC // Render surfaces above windows for monitor for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } // Render IME popups @@ -905,12 +906,12 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) { - renderLayer(ls.get(), pMonitor, time); + renderLayer(ls, pMonitor, time); } for (auto& lsl : pMonitor->m_aLayerSurfaceLayers) { for (auto& ls : lsl) { - renderLayer(ls.get(), pMonitor, time, true); + renderLayer(ls, pMonitor, time, true); } } @@ -1595,7 +1596,7 @@ static void applyExclusive(wlr_box& usableArea, uint32_t anchor, int32_t exclusi } } -void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vector>& layerSurfaces, bool exclusiveZone, CBox* usableArea) { +void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vector& layerSurfaces, bool exclusiveZone, CBox* usableArea) { CBox full_area = {pMonitor->vecPosition.x, pMonitor->vecPosition.y, pMonitor->vecSize.x, pMonitor->vecSize.y}; for (auto& ls : layerSurfaces) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 08b04dd2..fcf3f20b 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -108,11 +108,11 @@ class CHyprRenderer { } m_sLastCursorData; private: - void arrangeLayerArray(CMonitor*, const std::vector>&, bool, CBox*); + void arrangeLayerArray(CMonitor*, const std::vector&, bool, CBox*); void renderWorkspaceWindowsFullscreen(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) void renderWorkspaceWindows(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) void renderWindow(PHLWINDOW, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); - void renderLayer(SLayerSurface*, CMonitor*, timespec*, bool popups = false); + void renderLayer(PHLLS, CMonitor*, timespec*, bool popups = false); void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); void renderDragIcon(CMonitor*, timespec*); void renderIMEPopup(CInputPopup*, CMonitor*, timespec*);