diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 7da616c1..a4ba366a 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -31,6 +31,7 @@ PHLWINDOW CWindow::create(SP surface) { pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(std::make_unique(pWindow)); pWindow->addWindowDeco(std::make_unique(pWindow)); @@ -52,6 +53,7 @@ PHLWINDOW CWindow::create(SP resource) { pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(std::make_unique(pWindow)); pWindow->addWindowDeco(std::make_unique(pWindow)); @@ -407,6 +409,11 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { const auto OLDWORKSPACE = m_pWorkspace; + m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->m_iMonitorID : -1; + m_fMovingToWorkspaceAlpha.setValueAndWarp(1.F); + m_fMovingToWorkspaceAlpha = 0.F; + m_fMovingToWorkspaceAlpha.setCallbackOnEnd([this](void* thisptr) { m_iMonitorMovedFrom = -1; }); + m_pWorkspace = pWorkspace; setAnimationsToMove(); @@ -502,6 +509,7 @@ void CWindow::onUnmap() { m_fAlpha.setCallbackOnEnd(unregisterVar); m_cRealShadowColor.setCallbackOnEnd(unregisterVar); m_fDimPercent.setCallbackOnEnd(unregisterVar); + m_fMovingToWorkspaceAlpha.setCallbackOnEnd(unregisterVar); m_vRealSize.setCallbackOnBegin(nullptr); @@ -542,6 +550,7 @@ void CWindow::onMap() { m_fAlpha.resetAllCallbacks(); m_cRealShadowColor.resetAllCallbacks(); m_fDimPercent.resetAllCallbacks(); + m_fMovingToWorkspaceAlpha.resetAllCallbacks(); m_vRealPosition.registerVar(); m_vRealSize.registerVar(); @@ -551,6 +560,7 @@ void CWindow::onMap() { m_fAlpha.registerVar(); m_cRealShadowColor.registerVar(); m_fDimPercent.registerVar(); + m_fMovingToWorkspaceAlpha.registerVar(); m_fBorderAngleAnimationProgress.setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false); diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index e1850fb3..bdc275bf 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -352,6 +352,10 @@ class CWindow { // animated tint CAnimatedVariable m_fDimPercent; + // animate moving to an invisible workspace + int m_iMonitorMovedFrom = -1; // -1 means not moving + CAnimatedVariable m_fMovingToWorkspaceAlpha; + // swallowing PHLWINDOWREF m_pSwallowed; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 7d63468e..33679731 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -266,6 +266,11 @@ bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow, CMonitor* pMonitor) { if (pWindow->m_bPinned) return true; + // if the window is being moved to a workspace that is not invisible, and the alpha is > 0.F, render it. + if (pWindow->m_iMonitorMovedFrom != -1 && pWindow->m_fMovingToWorkspaceAlpha.isBeingAnimated() && pWindow->m_fMovingToWorkspaceAlpha.value() > 0.F && + !g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace)) + return true; + const auto PWINDOWWORKSPACE = pWindow->m_pWorkspace; if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_iMonitorID == pMonitor->ID) { if (PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() || PWINDOWWORKSPACE->m_bForceRendering) @@ -540,14 +545,18 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, CMonitor* pMonitor, timespec if (ignoreAllGeometry) decorate = false; + // whether to use m_fMovingToWorkspaceAlpha, only if fading out into an invisible ws + const bool USE_WORKSPACE_FADE_ALPHA = pWindow->m_iMonitorMovedFrom != -1 && !g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace); + renderdata.surface = pWindow->m_pWLSurface->resource(); renderdata.dontRound = pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN) || pWindow->m_sWindowData.noRounding.valueOrDefault(); - renderdata.fadeAlpha = pWindow->m_fAlpha.value() * (pWindow->m_bPinned ? 1.f : PWORKSPACE->m_fAlpha.value()); - renderdata.alpha = pWindow->m_fActiveInactiveAlpha.value(); - renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); - renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; - renderdata.blur = !ignoreAllGeometry; // if it shouldn't, it will be ignored later - renderdata.pWindow = pWindow; + renderdata.fadeAlpha = pWindow->m_fAlpha.value() * (pWindow->m_bPinned || USE_WORKSPACE_FADE_ALPHA ? 1.f : PWORKSPACE->m_fAlpha.value()) * + (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha.value() : 1.F); + renderdata.alpha = pWindow->m_fActiveInactiveAlpha.value(); + renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); + renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; + renderdata.blur = !ignoreAllGeometry; // if it shouldn't, it will be ignored later + renderdata.pWindow = pWindow; if (ignoreAllGeometry) { renderdata.alpha = 1.f;