diff --git a/src/Window.cpp b/src/Window.cpp index 03ca39ad..21dac460 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -3,7 +3,7 @@ #include "render/decorations/CHyprDropShadowDecoration.hpp" CWindow::CWindow() { - m_vRealPosition.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*) this, AVARDAMAGE_ENTIRE); + m_vRealPosition.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); m_vRealSize.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); m_cRealBorderColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("border"), (void*)this, AVARDAMAGE_BORDER); m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE); @@ -245,9 +245,31 @@ void CWindow::removeDecorationByType(eDecorationType type) { updateWindowDecos(); } +void unregisterVar(void* ptr) { + ((CAnimatedVariable*)ptr)->unregister(); +} + void CWindow::onUnmap() { if (g_pCompositor->m_pLastWindow == this) g_pCompositor->m_pLastWindow = nullptr; + + m_vRealPosition.setCallbackOnEnd(unregisterVar); + m_vRealSize.setCallbackOnEnd(unregisterVar); + m_cRealBorderColor.setCallbackOnEnd(unregisterVar); + m_fActiveInactiveAlpha.setCallbackOnEnd(unregisterVar); + m_fAlpha.setCallbackOnEnd(unregisterVar); + m_cRealShadowColor.setCallbackOnEnd(unregisterVar); + m_fDimPercent.setCallbackOnEnd(unregisterVar); +} + +void CWindow::onMap() { + m_vRealPosition.registerVar(); + m_vRealSize.registerVar(); + m_cRealBorderColor.registerVar(); + m_fActiveInactiveAlpha.registerVar(); + m_fAlpha.registerVar(); + m_cRealShadowColor.registerVar(); + m_fDimPercent.registerVar(); } void CWindow::setHidden(bool hidden) { diff --git a/src/Window.hpp b/src/Window.hpp index bf77454c..0e3ce9a5 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -183,6 +183,7 @@ public: void moveToWorkspace(int); CWindow* X11TransientFor(); void onUnmap(); + void onMap(); void setHidden(bool hidden); bool isHidden(); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 435cffbe..2620e495 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -74,6 +74,9 @@ void Events::listener_mapWindow(void* owner, void* data) { // checks if the window wants borders and sets the appriopriate flag g_pXWaylandManager->checkBorders(PWINDOW); + // registers the animated vars and stuff + PWINDOW->onMap(); + const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(PWINDOW); if (!PWINDOWSURFACE) { @@ -110,7 +113,7 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW); std::string requestedWorkspace = ""; bool workspaceSilent = false; - bool requestsFullscreen = PWINDOW->m_bWantsInitialFullscreen || (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL && PWINDOW->m_uSurface.xdg->toplevel->requested.fullscreen); + bool requestsFullscreen = PWINDOW->m_bWantsInitialFullscreen || (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL && PWINDOW->m_uSurface.xdg->toplevel->requested.fullscreen) || (PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xwayland->fullscreen); bool shouldFocus = true; bool workspaceSpecial = false; @@ -622,9 +625,6 @@ void Events::listener_unmapWindow(void* owner, void* data) { Debug::log(LOG, "Unmapped was not focused, ignoring a refocus."); } - // update lastwindow after focus - PWINDOW->onUnmap(); - Debug::log(LOG, "Destroying the SubSurface tree of unmapped window %x", PWINDOW); SubsurfaceTree::destroySurfaceTree(PWINDOW->m_pSurfaceTree); @@ -657,6 +657,9 @@ void Events::listener_unmapWindow(void* owner, void* data) { // force report all sizes (QT sometimes has an issue with this) g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->m_iWorkspaceID); + + // update lastwindow after focus + PWINDOW->onUnmap(); } void Events::listener_commitWindow(void* owner, void* data) { @@ -789,7 +792,7 @@ void Events::listener_configureX11(void* owner, void* data) { g_pHyprRenderer->damageWindow(PWINDOW); if (!PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) { - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.vec()); + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv(), true); g_pInputManager->refocus(); g_pHyprRenderer->damageWindow(PWINDOW); return; @@ -840,6 +843,12 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { else PWINDOW->setHidden(true); + if (PWINDOW->m_bIsFullscreen || !PWINDOW->m_bIsFloating) { + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv(), true); + g_pHyprRenderer->damageWindow(PWINDOW); + return; + } + if (abs(std::floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(std::floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) { Debug::log(LOG, "Unmanaged window %x requests geometry update to %i %i %i %i", PWINDOW, (int)PWINDOW->m_uSurface.xwayland->x, (int)PWINDOW->m_uSurface.xwayland->y, (int)PWINDOW->m_uSurface.xwayland->width, (int)PWINDOW->m_uSurface.xwayland->height); @@ -923,14 +932,14 @@ void Events::listener_requestMinimize(void* owner, void* data) { Debug::log(LOG, "Minimize request for %x", PWINDOW); - // if (PWINDOW->m_bIsX11) { - // if (!PWINDOW->m_bMappedX11 || PWINDOW->m_iX11Type != 1) - // return; + if (PWINDOW->m_bIsX11) { + if (!PWINDOW->m_bMappedX11 || PWINDOW->m_iX11Type != 1) + return; - // const auto E = (wlr_xwayland_minimize_event*)data; + const auto E = (wlr_xwayland_minimize_event*)data; - // wlr_xwayland_surface_set_minimized(PWINDOW->m_uSurface.xwayland, E->minimize && g_pCompositor->m_pLastWindow != PWINDOW); // fucking DXVK - // } + wlr_xwayland_surface_set_minimized(PWINDOW->m_uSurface.xwayland, E->minimize && g_pCompositor->m_pLastWindow != PWINDOW); // fucking DXVK + } } void Events::listener_requestMove(void* owner, void* data) { diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp index 573844aa..c4a1713d 100644 --- a/src/helpers/AnimatedVariable.cpp +++ b/src/helpers/AnimatedVariable.cpp @@ -12,8 +12,6 @@ void CAnimatedVariable::create(ANIMATEDVARTYPE type, SAnimationPropertyConfig* p m_pConfig = pAnimConfig; m_pWindow = pWindow; - g_pAnimationManager->m_lAnimatedVariables.push_back(this); - m_bDummy = false; } @@ -58,6 +56,10 @@ void CAnimatedVariable::unregister() { g_pAnimationManager->m_lAnimatedVariables.remove(this); } +void CAnimatedVariable::registerVar() { + g_pAnimationManager->m_lAnimatedVariables.push_back(this); +} + int CAnimatedVariable::getDurationLeftMs() { return std::max((int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast(std::chrono::system_clock::now() - animationBegin).count(), 0); } diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index afde587b..22c5da84 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -32,6 +32,7 @@ public: ~CAnimatedVariable(); void unregister(); + void registerVar(); // gets the current vector value (real time) const Vector2D& vec() const { @@ -167,6 +168,16 @@ public: int getDurationLeftMs(); + /* sets a function to be ran when the animation finishes. + if an animation is not running, runs instantly. + will remove the callback when ran. */ + void setCallbackOnEnd(std::function func) { + m_fEndCallback = func; + + if (!isBeingAnimated()) + onAnimationEnd(); + } + private: Vector2D m_vValue = Vector2D(0,0); @@ -195,6 +206,16 @@ private: ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID; AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_INVALID; + std::function m_fEndCallback; + + // methods + void onAnimationEnd() { + if (m_fEndCallback) { + m_fEndCallback(this); + m_fEndCallback = nullptr; // reset + } + } + friend class CAnimationManager; friend class CWorkspace; friend struct SLayerSurface; diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 0bd09222..9b6926e2 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -4,4 +4,5 @@ SLayerSurface::SLayerSurface() { alpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_ENTIRE); alpha.m_pLayer = this; + alpha.registerVar(); } \ No newline at end of file diff --git a/src/helpers/Workspace.cpp b/src/helpers/Workspace.cpp index d1927817..94e726fd 100644 --- a/src/helpers/Workspace.cpp +++ b/src/helpers/Workspace.cpp @@ -31,6 +31,9 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) { m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE); m_fAlpha.setValueAndWarp(255.f); + m_vRenderOffset.registerVar(); + m_fAlpha.registerVar(); + g_pEventManager->postEvent({"createworkspace", m_szName}, true); } diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index e521a17d..ab37f5e2 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -178,6 +178,12 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for return; } + if (PWINDOW->m_bIsFullscreen) { + PWINDOW->m_vRealSize = PMONITOR->vecSize; + PWINDOW->m_vRealPosition = PMONITOR->vecPosition; + return; + } + PWINDOW->m_vSize = pNode->size; PWINDOW->m_vPosition = pNode->position; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index f8b8f9a2..a9ee7daa 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -236,6 +236,12 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { return; } + if (PWINDOW->m_bIsFullscreen) { + PWINDOW->m_vRealSize = PMONITOR->vecSize; + PWINDOW->m_vRealPosition = PMONITOR->vecPosition; + return; + } + static auto *const PNOGAPSWHENONLY = &g_pConfigManager->getConfigValuePtr("master:no_gaps_when_only")->intValue; PWINDOW->m_vSize = pNode->size; diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index b465a3b5..06fa60da 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -33,6 +33,8 @@ void CAnimationManager::tick() { const auto DEFAULTBEZIER = m_mBezierCurves.find("default"); + std::vector animationEndedVars; + for (auto& av : m_lAnimatedVariables) { // first of all, check if we need to update it at all @@ -225,13 +227,21 @@ void CAnimationManager::tick() { } } - // set size and pos if valid, but only if damage policy entire (dont if border for example) if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2) g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); // manually schedule a frame g_pCompositor->scheduleFrameForMonitor(PMONITOR); + + // check if we did not finish animating. If so, trigger onAnimationEnd. + if (!av->isBeingAnimated()) + animationEndedVars.push_back(av); + } + + // do it here, because if this alters the animation vars deque we would be in trouble above. + for (auto& ave : animationEndedVars) { + ave->onAnimationEnd(); } }