From 412c7dc7f79cb6b04af41692504e82d4417e6e13 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 11 Jun 2025 17:52:16 +0200 Subject: [PATCH] renderer: fixup some missing fadeout cases with special fixes some fadeout missing cases: - closing last window - closing above fs - closing in general fixes #10283 --- src/desktop/Window.cpp | 6 +++++ src/helpers/Monitor.cpp | 7 ++++- src/helpers/Monitor.hpp | 4 +++ src/render/Renderer.cpp | 59 ++++++++++++++++++++++------------------- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 555b99f0..93395780 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -510,6 +510,12 @@ void CWindow::onUnmap() { m_lastWorkspace = m_workspace->m_id; + // if the special workspace now has 0 windows, it will be closed, and this + // window will no longer pass render checks, cuz the workspace will be nuked. + // throw it into the main one for the fadeout. + if (m_workspace->m_isSpecialWorkspace && m_workspace->getWindows() == 0) + m_lastWorkspace = m_monitor->activeWorkspaceID(); + std::erase_if(g_pCompositor->m_windowFocusHistory, [this](const auto& other) { return other.expired() || other == m_self; }); if (*PCLOSEONLASTSPECIAL && m_workspace && m_workspace->getWindows() == 0 && onSpecialWorkspace()) { diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index f2dc2e8c..44ac1dcf 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -21,6 +21,7 @@ #include "../render/Renderer.hpp" #include "../managers/EventManager.hpp" #include "../managers/LayoutManager.hpp" +#include "../managers/AnimationManager.hpp" #include "../managers/input/InputManager.hpp" #include "sync/SyncTimeline.hpp" #include "time/Time.hpp" @@ -47,7 +48,8 @@ static int ratHandler(void* data) { } CMonitor::CMonitor(SP output_) : m_state(this), m_output(output_) { - ; + g_pAnimationManager->createAnimation(0.f, m_specialFade, g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn"), AVARDAMAGE_NONE); + m_specialFade->setUpdateCallback([this](auto) { g_pHyprRenderer->damageMonitor(m_self.lock()); }); } CMonitor::~CMonitor() { @@ -1222,6 +1224,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { if (m_activeSpecialWorkspace == pWorkspace) return; + m_specialFade->setConfig(g_pConfigManager->getAnimationPropertyConfig(pWorkspace ? "specialWorkspaceIn" : "specialWorkspaceOut")); + *m_specialFade = pWorkspace ? 1.F : 0.F; + g_pHyprRenderer->damageMonitor(m_self.lock()); if (!pWorkspace) { diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index e495cf04..4dc4ad88 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -7,6 +7,7 @@ #include "MiscFunctions.hpp" #include "WLClasses.hpp" #include +#include "AnimatedVariable.hpp" #include #include "time/Timer.hpp" @@ -161,6 +162,9 @@ class CMonitor { PHLWINDOWREF m_lastScanout; bool m_scanoutNeedsCursorUpdate = false; + // for special fade/blur + PHLANIMVAR m_specialFade; + struct { bool canTear = false; bool nextRenderTorn = false; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f33e6012..67832df1 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -850,9 +850,8 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA if (scale != 1.f) RENDERMODIFDATA.modifs.emplace_back(std::make_pair<>(SRenderModifData::eRenderModifType::RMOD_TYPE_SCALE, scale)); - if (!RENDERMODIFDATA.modifs.empty()) { + if (!RENDERMODIFDATA.modifs.empty()) g_pHyprRenderer->m_renderPass.add(makeShared(CRendererHintsPassElement::SData{RENDERMODIFDATA})); - } CScopeGuard x([&RENDERMODIFDATA] { if (!RENDERMODIFDATA.modifs.empty()) { @@ -911,41 +910,38 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA renderWorkspaceWindows(pMonitor, pWorkspace, time); // and then special - for (auto const& ws : g_pCompositor->m_workspaces) { - if (ws->m_monitor == pMonitor && ws->m_alpha->value() > 0.f && ws->m_isSpecialWorkspace) { - const auto SPECIALANIMPROGRS = ws->m_renderOffset->isBeingAnimated() ? ws->m_renderOffset->getCurveValue() : ws->m_alpha->getCurveValue(); - const bool ANIMOUT = !pMonitor->m_activeSpecialWorkspace; + if (pMonitor->m_specialFade->value() != 0.F) { + const auto SPECIALANIMPROGRS = pMonitor->m_specialFade->getCurveValue(); + const bool ANIMOUT = !pMonitor->m_activeSpecialWorkspace; - if (*PDIMSPECIAL != 0.f) { - CRectPassElement::SRectData data; - data.box = {translate.x, translate.y, pMonitor->m_transformedSize.x * scale, pMonitor->m_transformedSize.y * scale}; - data.color = CHyprColor(0, 0, 0, *PDIMSPECIAL * (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS)); + if (*PDIMSPECIAL != 0.f) { + CRectPassElement::SRectData data; + data.box = {translate.x, translate.y, pMonitor->m_transformedSize.x * scale, pMonitor->m_transformedSize.y * scale}; + data.color = CHyprColor(0, 0, 0, *PDIMSPECIAL * (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS)); - g_pHyprRenderer->m_renderPass.add(makeShared(data)); - } + g_pHyprRenderer->m_renderPass.add(makeShared(data)); + } - if (*PBLURSPECIAL && *PBLUR) { - CRectPassElement::SRectData data; - data.box = {translate.x, translate.y, pMonitor->m_transformedSize.x * scale, pMonitor->m_transformedSize.y * scale}; - data.color = CHyprColor(0, 0, 0, 0); - data.blur = true; - data.blurA = (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS); + if (*PBLURSPECIAL && *PBLUR) { + CRectPassElement::SRectData data; + data.box = {translate.x, translate.y, pMonitor->m_transformedSize.x * scale, pMonitor->m_transformedSize.y * scale}; + data.color = CHyprColor(0, 0, 0, 0); + data.blur = true; + data.blurA = (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS); - g_pHyprRenderer->m_renderPass.add(makeShared(data)); - } - - break; + g_pHyprRenderer->m_renderPass.add(makeShared(data)); } } // special for (auto const& ws : g_pCompositor->m_workspaces) { - if (ws->m_alpha->value() > 0.f && ws->m_isSpecialWorkspace) { - if (ws->m_hasFullscreenWindow) { - renderWorkspaceWindowsFullscreen(pMonitor, ws, time); - } else - renderWorkspaceWindows(pMonitor, ws, time); - } + if (ws->m_alpha->value() <= 0.F || !ws->m_isSpecialWorkspace) + continue; + + if (ws->m_hasFullscreenWindow) + renderWorkspaceWindowsFullscreen(pMonitor, ws, time); + else + renderWorkspaceWindows(pMonitor, ws, time); } // pinned always above @@ -2161,6 +2157,13 @@ void CHyprRenderer::recheckSolitaryForMonitor(PHLMONITOR pMonitor) { if (pMonitor->m_activeSpecialWorkspace) return; + for (auto const& ws : g_pCompositor->m_workspaces) { + if (ws->m_alpha->value() <= 0.F || !ws->m_isSpecialWorkspace || ws->m_monitor != pMonitor) + continue; + + return; + } + // check if it did not open any subsurfaces or shit int surfaceCount = 0; if (PCANDIDATE->m_isX11)