diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 437e6d4d..b208bac6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -57,6 +57,9 @@ void CConfigManager::setDefaultVars() { configValues["animations:fadein_curve"].strValue = "[[f]]"; configValues["animations:fadein_speed"].floatValue = 0.f; configValues["animations:fadein"].intValue = 1; + configValues["animations:workspaces_curve"].strValue = "[[f]]"; + configValues["animations:workspaces_speed"].floatValue = 0.f; + configValues["animations:workspaces"].intValue = 1; configValues["input:kb_layout"].strValue = "en"; configValues["input:kb_variant"].strValue = STRVAL_EMPTY; diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 6d0e57d2..a08bbfda 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -108,7 +108,6 @@ void Events::listener_newOutput(wl_listener* listener, void* data) { wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, std::to_string(WORKSPACEID).c_str()); PNEWWORKSPACE->m_iID = WORKSPACEID; - PNEWWORKSPACE->m_iMonitorID = newMonitor.ID; PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID; diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp index 9e93ba3c..1e9dd74e 100644 --- a/src/helpers/AnimatedVariable.cpp +++ b/src/helpers/AnimatedVariable.cpp @@ -52,5 +52,9 @@ void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, float* speed, } CAnimatedVariable::~CAnimatedVariable() { + unregister(); +} + +void CAnimatedVariable::unregister() { g_pAnimationManager->m_lAnimatedVariables.remove(this); } \ No newline at end of file diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 008d0b84..a484958b 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -17,6 +17,7 @@ enum AVARDAMAGEPOLICY { }; class CAnimationManager; +class CWorkspace; class CAnimatedVariable { public: @@ -27,6 +28,8 @@ public: ~CAnimatedVariable(); + void unregister(); + // gets the current vector value (real time) const Vector2D& vec() const { RASSERT(m_eVarType == AVARTYPE_VECTOR, "Tried to access vec() of AVARTYPE %i!", m_eVarType); @@ -129,6 +132,22 @@ public: warp(); } + // checks if an animation is in progress + bool isBeingAnimated() { + switch (m_eVarType) { + case AVARTYPE_FLOAT: + return m_fValue != m_fGoal; + case AVARTYPE_VECTOR: + return m_vValue != m_vGoal; + case AVARTYPE_COLOR: + return m_cValue != m_cGoal; + default: + return false; + } + + return false; // unreachable + } + private: void warp() { @@ -165,6 +184,7 @@ private: float* m_pSpeed = nullptr; int64_t* m_pEnabled = nullptr; void* m_pWindow = nullptr; + void* m_pWorkspace = nullptr; std::string* m_pBezier = nullptr; bool m_bDummy = true; @@ -175,4 +195,5 @@ private: AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_INVALID; friend class CAnimationManager; + friend class CWorkspace; }; \ No newline at end of file diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp index c34dc787..8d4557ba 100644 --- a/src/helpers/Color.hpp +++ b/src/helpers/Color.hpp @@ -24,4 +24,7 @@ public: return CColor(r * v, g * v, b * v, a * v); } + bool operator==(const CColor& c2) const { + return r == c2.r && g == c2.g && b == c2.b && a == c2.a; + } }; \ No newline at end of file diff --git a/src/helpers/Workspace.cpp b/src/helpers/Workspace.cpp index 0d5f77e1..e4065907 100644 --- a/src/helpers/Workspace.cpp +++ b/src/helpers/Workspace.cpp @@ -20,9 +20,14 @@ CWorkspace::CWorkspace(int monitorID) { wlr_ext_workspace_handle_v1_set_coordinates(m_pWlrHandle, &m_wlrCoordinateArr); wlr_ext_workspace_handle_v1_set_hidden(m_pWlrHandle, false); wlr_ext_workspace_handle_v1_set_urgent(m_pWlrHandle, false); + + m_vRenderOffset.m_pWorkspace = this; + m_vRenderOffset.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:workspaces_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces")->intValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE); } CWorkspace::~CWorkspace() { + m_vRenderOffset.unregister(); + if (m_pWlrHandle) { wlr_ext_workspace_handle_v1_set_active(m_pWlrHandle, false); wlr_ext_workspace_handle_v1_destroy(m_pWlrHandle); diff --git a/src/helpers/Workspace.hpp b/src/helpers/Workspace.hpp index 7988faf2..3a9abf72 100644 --- a/src/helpers/Workspace.hpp +++ b/src/helpers/Workspace.hpp @@ -1,6 +1,7 @@ #pragma once #include "../defines.hpp" +#include "AnimatedVariable.hpp" class CWorkspace { public: @@ -17,4 +18,7 @@ public: wlr_ext_workspace_handle_v1* m_pWlrHandle = nullptr; wl_array m_wlrCoordinateArr; + + // for animations + CAnimatedVariable m_vRenderOffset; }; \ No newline at end of file diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 4052c7e2..639be55e 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -40,17 +40,27 @@ void CAnimationManager::tick() { // window stuff const auto PWINDOW = (CWindow*)av->m_pWindow; - wlr_box WLRBOXPREV = {PWINDOW->m_vRealPosition.vec().x - BORDERSIZE - 1, PWINDOW->m_vRealPosition.vec().y - BORDERSIZE - 1, PWINDOW->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, PWINDOW->m_vRealSize.vec().y + 2 * BORDERSIZE + 2}; - + const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace; + wlr_box WLRBOXPREV = {0,0,0,0}; + if (PWINDOW) { + WLRBOXPREV = {(int)PWINDOW->m_vRealPosition.vec().x - BORDERSIZE - 1, (int)PWINDOW->m_vRealPosition.vec().y - BORDERSIZE - 1, (int)PWINDOW->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, (int)PWINDOW->m_vRealSize.vec().y + 2 * BORDERSIZE + 2}; + } else if (PWORKSPACE) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); + WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y}; + } + // check if it's disabled, if so, warp if (av->m_pEnabled == 0 || animationsDisabled) { av->warp(); g_pHyprRenderer->damageBox(&WLRBOXPREV); - g_pHyprRenderer->damageWindow(PWINDOW); - // set size and pos if valid - if (g_pCompositor->windowValidMapped(PWINDOW)) - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); + if (PWINDOW) { + g_pHyprRenderer->damageWindow(PWINDOW); + // set size and pos if valid + if (g_pCompositor->windowValidMapped(PWINDOW)) + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); + } + continue; } @@ -125,10 +135,14 @@ void CAnimationManager::tick() { switch (av->m_eDamagePolicy) { case AVARDAMAGE_ENTIRE: { g_pHyprRenderer->damageBox(&WLRBOXPREV); - g_pHyprRenderer->damageWindow(PWINDOW); + + if (PWINDOW) + g_pHyprRenderer->damageWindow(PWINDOW); break; } case AVARDAMAGE_BORDER: { + RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!"); + // damage only the border. const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size") + 1; // +1 for padding and shit const auto ROUNDINGSIZE = g_pConfigManager->getInt("decoration:rounding") + 1; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 900e1e00..3a354f23 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -202,6 +202,14 @@ void CKeybindManager::changeworkspace(std::string args) { // and fix on the new workspace g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace); + + // here and only here begin anim. we don't want to anim visible workspaces on other monitors. + // start anim on old workspace + g_pCompositor->getWorkspaceByID(OLDWORKSPACEID)->m_vRenderOffset = Vector2D(-PMONITOR->vecSize.x, 0); + + // start anim on new workspace + g_pCompositor->getWorkspaceByID(workspaceToChangeTo)->m_vRenderOffset.setValueAndWarp(Vector2D(PMONITOR->vecSize.x, 0)); + g_pCompositor->getWorkspaceByID(workspaceToChangeTo)->m_vRenderOffset = Vector2D(0, 0); } @@ -234,9 +242,16 @@ void CKeybindManager::changeworkspace(std::string args) { const auto OLDWORKSPACE = PMONITOR->activeWorkspace; + // start anim on old workspace + g_pCompositor->getWorkspaceByID(OLDWORKSPACE)->m_vRenderOffset = Vector2D(-PMONITOR->vecSize.x, 0); + g_pCompositor->m_lWorkspaces.emplace_back(PMONITOR->ID); const auto PWORKSPACE = &g_pCompositor->m_lWorkspaces.back(); + // start anim on new workspace + PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(PMONITOR->vecSize.x, 0)); + PWORKSPACE->m_vRenderOffset = Vector2D(0, 0); + // We are required to set the name here immediately wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, workspaceName.c_str()); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 2d5ba2bf..be51336c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -39,8 +39,9 @@ bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) { if (pWindow->m_iWorkspaceID == pMonitor->activeWorkspace) return true; - // if not, check if it maybe is active on a different monitor. - if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID)) + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + // if not, check if it maybe is active on a different monitor. vvv might be animation in progress + if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_vRenderOffset.isBeingAnimated())) return true; return false; @@ -88,8 +89,9 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* g_pHyprOpenGL->renderSnapshot(&pWindow); return; } - - const auto REALPOS = pWindow->m_vRealPosition.vec(); + + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto REALPOS = pWindow->m_vRealPosition.vec() + PWORKSPACE->m_vRenderOffset.vec(); SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y}; renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow); renderdata.w = pWindow->m_vRealSize.vec().x; @@ -105,7 +107,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* // border if (decorate && !pWindow->m_bX11DoesntWantBorders) - drawBorderForWindow(pWindow, pMonitor, pWindow->m_fAlpha.fl() * renderdata.alpha); + drawBorderForWindow(pWindow, pMonitor, pWindow->m_fAlpha.fl() * renderdata.alpha, PWORKSPACE->m_vRenderOffset.vec()); if (pWindow->m_bIsX11) { if (pWindow->m_uSurface.xwayland->surface) { @@ -426,7 +428,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) { Debug::log(LOG, "Monitor %s layers arranged: reserved: %f %f %f %f", PMONITOR->szName.c_str(), PMONITOR->vecReservedTopLeft.x, PMONITOR->vecReservedTopLeft.y, PMONITOR->vecReservedBottomRight.x, PMONITOR->vecReservedBottomRight.y); } -void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor, float alpha) { +void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor, float alpha, const Vector2D& offset) { const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); if (BORDERSIZE < 1) @@ -439,7 +441,7 @@ void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor, fl Vector2D correctSize = pWindow->m_vRealSize.vec(); // top - wlr_box border = {correctPos.x - BORDERSIZE / 2.f, correctPos.y - BORDERSIZE / 2.f, pWindow->m_vRealSize.vec().x + BORDERSIZE, pWindow->m_vRealSize.vec().y + BORDERSIZE}; + wlr_box border = {correctPos.x - BORDERSIZE / 2.f + offset.x, correctPos.y - BORDERSIZE / 2.f + offset.y, pWindow->m_vRealSize.vec().x + BORDERSIZE, pWindow->m_vRealSize.vec().y + BORDERSIZE}; g_pHyprOpenGL->renderBorder(&border, BORDERCOL, BORDERSIZE, g_pConfigManager->getInt("decoration:rounding")); } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 70bdd4ea..b445c176 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -34,7 +34,7 @@ public: private: void arrangeLayerArray(SMonitor*, const std::list&, bool, wlr_box*); - void drawBorderForWindow(CWindow*, SMonitor*, float a = 255.f); + void drawBorderForWindow(CWindow*, SMonitor*, float a = 255.f, const Vector2D& offset = Vector2D(0,0)); void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*); void renderWindow(CWindow*, SMonitor*, timespec*, bool); void renderDragIcon(SMonitor*, timespec*);