From ae17e900e720430c7848faf1b6e21b5f352c26ca Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 25 Mar 2024 16:20:30 +0000 Subject: [PATCH] layer-shell: render popups above everything --- src/Compositor.cpp | 23 ++++++++++++++++++++++- src/Compositor.hpp | 3 ++- src/helpers/WLClasses.cpp | 3 +++ src/managers/input/InputManager.cpp | 3 +++ src/render/Renderer.cpp | 14 +++++++++++--- src/render/Renderer.hpp | 2 +- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index bf6c4200..2d6e7856 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1143,13 +1143,34 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) { return true; } +wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, SLayerSurface** 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) + continue; + + auto SURFACEAT = wlr_layer_surface_v1_popup_surface_at(ls->layerSurface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); + + if (SURFACEAT) { + if (!pixman_region32_not_empty(&SURFACEAT->input_region)) + continue; + + *ppLayerSurfaceFound = ls.get(); + return SURFACEAT; + } + } + } + + return nullptr; +} + wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector>* layerSurfaces, Vector2D* sCoords, SLayerSurface** 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; - auto SURFACEAT = wlr_layer_surface_v1_surface_at(ls->layerSurface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); + auto SURFACEAT = wlr_surface_surface_at(ls->layerSurface->surface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); if (SURFACEAT) { if (!pixman_region32_not_empty(&SURFACEAT->input_region)) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 64cd6e43..ace2a388 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -118,7 +118,7 @@ class CCompositor { bool m_bUnsafeState = false; // unsafe state is when there is no monitors. bool m_bNextIsUnsafe = false; // because wlroots CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state - bool m_bExitTriggered = false; // For exit dispatcher + bool m_bExitTriggered = false; // For exit dispatcher bool m_bIsShuttingDown = false; // ------------------------------------------------- // @@ -136,6 +136,7 @@ class CCompositor { bool monitorExists(CMonitor*); CWindow* vectorToWindowUnified(const Vector2D&, uint8_t properties, CWindow* 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&, CWindow*, Vector2D& sl); Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*); CMonitor* getMonitorFromOutput(wlr_output*); diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index e7ae69c0..5e18c274 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -171,6 +171,9 @@ bool SLayerSurface::isFadedOut() { } 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); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 94245587..690463fa 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -209,6 +209,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { surfacePos = PMONITOR->vecPosition; } + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerPopupSurface(mouseCoords, PMONITOR, &surfaceCoords, &pFoundLayerSurface); + // overlays are above fullscreen if (!foundSurface) foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 3e8b277f..4680568c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -646,7 +646,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* g_pHyprOpenGL->m_RenderData.clipBox = CBox(); } -void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time) { +void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time, bool popups) { if (pLayer->fadingOut) { g_pHyprOpenGL->renderSnapshot(&pLayer); return; @@ -678,13 +678,15 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times g_pHyprOpenGL->m_RenderData.discardOpacity = pLayer->ignoreAlphaValue; } - wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); + if (!popups) + wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); renderdata.squishOversized = false; // don't squish popups renderdata.dontRound = true; renderdata.popup = true; renderdata.blur = pLayer->forceBlurPopups; - wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata); + if (popups) + wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata); g_pHyprOpenGL->m_pCurrentLayer = nullptr; g_pHyprOpenGL->m_RenderData.clipBox = {}; @@ -855,6 +857,12 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* renderLayer(ls.get(), pMonitor, time); } + for (auto& lsl : pMonitor->m_aLayerSurfaceLayers) { + for (auto& ls : lsl) { + renderLayer(ls.get(), pMonitor, time, true); + } + } + renderDragIcon(pMonitor, time); //g_pHyprOpenGL->restoreMatrix(); diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 011b17b9..d73b4c5f 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -113,7 +113,7 @@ class CHyprRenderer { void renderWorkspaceWindowsFullscreen(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) void renderWorkspaceWindows(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); - void renderLayer(SLayerSurface*, CMonitor*, timespec*); + void renderLayer(SLayerSurface*, CMonitor*, timespec*, bool popups = false); void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); void renderDragIcon(CMonitor*, timespec*); void renderIMEPopup(CInputPopup*, CMonitor*, timespec*);