diff options
| author | xDarksome <dev@darkso.me> | 2022-07-02 19:43:52 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-02 19:43:52 +0300 |
| commit | 185c4d6ea13ad5f4483aa2e389e43bd09106002f (patch) | |
| tree | a7bc4a9510c39e367317b5ce64d2ee0e0a72d4f0 /src/render/decorations/CHyprDropShadowDecoration.cpp | |
| parent | fc4b10d13c14c4eb08febb0637f27177cb6a1940 (diff) | |
| parent | b7b3344188e3ebd2baed14bc288ee42a1ae8d6f2 (diff) | |
Merge branch 'hyprwm:main' into main
Diffstat (limited to 'src/render/decorations/CHyprDropShadowDecoration.cpp')
| -rw-r--r-- | src/render/decorations/CHyprDropShadowDecoration.cpp | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 6933e687..40051942 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -35,6 +35,17 @@ void CHyprDropShadowDecoration::damageEntire() { void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) { damageEntire(); + + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + + const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D(); + + if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) { + m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET; + m_vLastWindowSize = pWindow->m_vRealSize.vec(); + + damageEntire(); + } } void CHyprDropShadowDecoration::draw(SMonitor* pMonitor, float a) { @@ -45,22 +56,70 @@ void CHyprDropShadowDecoration::draw(SMonitor* pMonitor, float a) { static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue; static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue; static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue; + static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue; + static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->strValue; if (*PSHADOWS != 1) return; // disabled - // update the extents if needed - if (*PSHADOWSIZE != m_seExtents.topLeft.x) - m_seExtents = {{*PSHADOWSIZE + 2, *PSHADOWSIZE + 2}, {*PSHADOWSIZE + 2, *PSHADOWSIZE + 2}}; + // get the real offset + Vector2D offset; + try { + if (const auto SPACEPOS = PSHADOWOFFSET->find(' '); SPACEPOS != std::string::npos) { + const auto X = PSHADOWOFFSET->substr(0, SPACEPOS); + const auto Y = PSHADOWOFFSET->substr(SPACEPOS + 1); - m_vLastWindowPos = m_pWindow->m_vRealPosition.vec(); - m_vLastWindowSize = m_pWindow->m_vRealSize.vec(); + if (isNumber(X, true) && isNumber(Y, true)) { + offset = Vector2D(std::stof(X), std::stof(Y)); + } + } + } catch (std::exception& e) { + return; // cannot parse + } + + // update the extents + m_seExtents = {{*PSHADOWSIZE + 2 - offset.x, *PSHADOWSIZE + 2 - offset.y}, {*PSHADOWSIZE + 2 + offset.x, *PSHADOWSIZE + 2 + offset.y}}; // draw the shadow wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4}; fullBox.x -= pMonitor->vecPosition.x; fullBox.y -= pMonitor->vecPosition.y; - + + if (fullBox.width < 1 || fullBox.height < 1) + return; // don't draw invisible shadows + + if (*PSHADOWIGNOREWINDOW) { + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + + glEnable(GL_STENCIL_TEST); + + glStencilFunc(GL_ALWAYS, 1, -1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + wlr_box windowBox = {m_vLastWindowPos.x - pMonitor->vecPosition.x, m_vLastWindowPos.y - pMonitor->vecPosition.y, m_vLastWindowSize.x, m_vLastWindowSize.y}; + + scaleBox(&windowBox, pMonitor->scale); + + if (windowBox.width < 1 || windowBox.height < 1) { + glDisable(GL_STENCIL_TEST); + return; // prevent assert failed + } + + g_pHyprOpenGL->renderRect(&windowBox, CColor(0,0,0,0), *PROUNDING); + + glStencilFunc(GL_NOTEQUAL, 1, -1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } + + scaleBox(&fullBox, pMonitor->scale); g_pHyprOpenGL->renderRoundedShadow(&fullBox, *PROUNDING, *PSHADOWSIZE, a); + + if (*PSHADOWIGNOREWINDOW) { + // cleanup + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + glDisable(GL_STENCIL_TEST); + } } |
