From bea828ea4585bab206b8772b838f496e0eada12e Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 11 Nov 2023 15:18:04 +0000 Subject: [PATCH] decoration-positioner: improve extent handling --- src/SharedDefs.hpp | 4 ++ src/events/Windows.cpp | 14 +++---- .../decorations/CHyprDropShadowDecoration.cpp | 17 ++++++--- .../decorations/CHyprDropShadowDecoration.hpp | 1 + .../decorations/DecorationPositioner.cpp | 38 +++++++++++++++++-- .../decorations/DecorationPositioner.hpp | 3 +- 6 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/SharedDefs.hpp b/src/SharedDefs.hpp index 4e4217d2..19d26b61 100644 --- a/src/SharedDefs.hpp +++ b/src/SharedDefs.hpp @@ -42,4 +42,8 @@ struct SWindowDecorationExtents { SWindowDecorationExtents round() { return {topLeft.round(), bottomRight.round()}; } + + bool operator==(const SWindowDecorationExtents& other) const { + return topLeft == other.topLeft && bottomRight == other.bottomRight; + } }; \ No newline at end of file diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index c6c9024e..00d78f4c 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -668,6 +668,13 @@ void Events::listener_unmapWindow(void* owner, void* data) { return; } + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); + if (PMONITOR) { + PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec() - PMONITOR->vecPosition; + PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec(); + PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents(); + } + g_pEventManager->postEvent(SHyprIPCEvent{"closewindow", std::format("{:x}", PWINDOW)}); EMIT_HOOK_EVENT("closeWindow", PWINDOW); @@ -697,13 +704,6 @@ void Events::listener_unmapWindow(void* owner, void* data) { if (PWINDOW->m_bIsFullscreen) g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL); - const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); - if (PMONITOR) { - PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec() - PMONITOR->vecPosition; - PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec(); - PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents(); - } - // Allow the renderer to catch the last frame. g_pHyprOpenGL->makeWindowSnapshot(PWINDOW); diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 9f051ad3..1990d37d 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -6,16 +6,20 @@ CHyprDropShadowDecoration::CHyprDropShadowDecoration(CWindow* pWindow) : IHyprWi m_pWindow = pWindow; } -CHyprDropShadowDecoration::~CHyprDropShadowDecoration() { - updateWindow(m_pWindow); -} +CHyprDropShadowDecoration::~CHyprDropShadowDecoration() {} eDecorationType CHyprDropShadowDecoration::getDecorationType() { return DECORATION_SHADOW; } SDecorationPositioningInfo CHyprDropShadowDecoration::getPositioningInfo() { - return {DECORATION_POSITION_ABSOLUTE}; + SDecorationPositioningInfo info; + info.policy = DECORATION_POSITION_ABSOLUTE; + info.desiredExtents = m_seExtents; + info.edges = DECORATION_EDGE_BOTTOM | DECORATION_EDGE_LEFT | DECORATION_EDGE_RIGHT | DECORATION_EDGE_TOP; + + m_seReportedExtents = m_seExtents; + return info; } void CHyprDropShadowDecoration::onPositioningReply(const SDecorationPositioningReply& reply) { @@ -148,8 +152,11 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D } else { g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a); } + + if (m_seExtents != m_seReportedExtents) + g_pDecorationPositioner->repositionDeco(this); } eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() { return DECORATION_LAYER_BOTTOM; -} \ No newline at end of file +} diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index 9f0f58a0..c3e362c7 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -23,6 +23,7 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { private: SWindowDecorationExtents m_seExtents; + SWindowDecorationExtents m_seReportedExtents; CWindow* m_pWindow = nullptr; diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index 98627d4c..55e5470d 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -226,11 +226,41 @@ SWindowDecorationExtents CDecorationPositioner::getWindowDecorationReserved(CWin } SWindowDecorationExtents CDecorationPositioner::getWindowDecorationExtents(CWindow* pWindow, bool inputOnly) { - if (!inputOnly) - return m_mWindowDatas[pWindow].extents; + CBox accum = pWindow->getWindowMainSurfaceBox().expand(pWindow->getRealBorderSize()); - // TODO: - return m_mWindowDatas[pWindow].extents; + for (auto& data : m_vWindowPositioningDatas) { + if (data->pWindow != pWindow) + continue; + + if (!(data->pDecoration->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT) && inputOnly) + continue; + + CBox decoBox; + + if (data->positioningInfo.policy == DECORATION_POSITION_ABSOLUTE) { + decoBox = data->pWindow->getWindowMainSurfaceBox(); + decoBox.addExtents(data->positioningInfo.desiredExtents); + } else { + decoBox = data->lastReply.assignedGeometry; + const auto EDGEPOINT = getEdgeDefinedPoint(data->positioningInfo.edges, pWindow); + decoBox.translate(EDGEPOINT); + } + + SWindowDecorationExtents extentsToAdd; + + if (decoBox.x < accum.x) + extentsToAdd.topLeft.x = accum.x - decoBox.x; + if (decoBox.y < accum.y) + extentsToAdd.topLeft.y = accum.y - decoBox.y; + if (decoBox.x + decoBox.w > accum.x + accum.w) + extentsToAdd.bottomRight.x = (decoBox.x + decoBox.w) - (accum.x + accum.w); + if (decoBox.y + decoBox.h > accum.y + accum.h) + extentsToAdd.bottomRight.y = (decoBox.y + decoBox.h) - (accum.y + accum.h); + + accum.addExtents(extentsToAdd); + } + + return accum.extentsFrom(pWindow->getWindowMainSurfaceBox()); } CBox CDecorationPositioner::getBoxWithIncludedDecos(CWindow* pWindow) { diff --git a/src/render/decorations/DecorationPositioner.hpp b/src/render/decorations/DecorationPositioner.hpp index 9fc45ba3..ebb9f480 100644 --- a/src/render/decorations/DecorationPositioner.hpp +++ b/src/render/decorations/DecorationPositioner.hpp @@ -27,7 +27,8 @@ enum eDecorationEdges Request the positioner to position a decoration DECORATION_POSITION_ABSOLUTE: - - desiredExtents may contain the extents to be used when reserved is set. Edges has to have the edges used. + - desiredExtents has to contain the extents. Edges has to have the edges used. + - reserved allowed DECORATION_POSITION_STICKY: - one edge allowed - priority allowed