diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index adf597ff..604758bc 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -586,7 +586,7 @@ void CHyprDwindleLayout::onBeginDragWindow() { IHyprLayout::onBeginDragWindow(); } -void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* pWindow) { +void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorner corner, CWindow* pWindow) { const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow; @@ -656,62 +656,64 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* if (DISPLAYBOTTOM && DISPLAYTOP) allowedMovement.y = 0; - // get the correct containers to apply splitratio to - const auto PPARENT = PNODE->pParent; + // Identify inner and outer nodes for both directions. - if (!PPARENT) - return; // the only window on a workspace, ignore + SDwindleNodeData* PVOUTER = nullptr; + SDwindleNodeData* PVINNER = nullptr; + SDwindleNodeData* PHOUTER = nullptr; + SDwindleNodeData* PHINNER = nullptr; - const bool PARENTSIDEBYSIDE = !PPARENT->splitTop; + const auto LEFT = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT; + const auto TOP = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT; + const auto RIGHT = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT; + const auto BOTTOM = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT; + const auto NONE = corner == CORNER_NONE; - // Get the parent's parent - auto PPARENT2 = PPARENT->pParent; + for (auto PCURRENT = PNODE; PCURRENT && PCURRENT->pParent; PCURRENT = PCURRENT->pParent) { + const auto PPARENT = PCURRENT->pParent; - // No parent means we have only 2 windows, and thus one axis of freedom - if (!PPARENT2) { - if (PARENTSIDEBYSIDE) { - allowedMovement.x *= 2.f / PPARENT->size.x; - PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9); - PPARENT->recalcSizePosRecursive(*PANIMATE == 0); - } else { - allowedMovement.y *= 2.f / PPARENT->size.y; - PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9); - PPARENT->recalcSizePosRecursive(*PANIMATE == 0); - } + if (!PVOUTER && PPARENT->splitTop && (NONE || (TOP && PPARENT->children[1] == PCURRENT) || (BOTTOM && PPARENT->children[0] == PCURRENT))) + PVOUTER = PCURRENT; + else if (!PVOUTER && !PVINNER && PPARENT->splitTop) + PVINNER = PCURRENT; + else if (!PHOUTER && !PPARENT->splitTop && (NONE || (LEFT && PPARENT->children[1] == PCURRENT) || (RIGHT && PPARENT->children[0] == PCURRENT))) + PHOUTER = PCURRENT; + else if (!PHOUTER && !PHINNER && !PPARENT->splitTop) + PHINNER = PCURRENT; - return; + if (PVOUTER && PHOUTER) + break; } - // Get first parent with other split - while (PPARENT2 && PPARENT2->splitTop == !PARENTSIDEBYSIDE) - PPARENT2 = PPARENT2->pParent; + if (PHOUTER) { + PHOUTER->pParent->splitRatio = std::clamp(PHOUTER->pParent->splitRatio + allowedMovement.x * 2.f / PHOUTER->pParent->size.x, 0.1, 1.9); - // no parent, one axis of freedom - if (!PPARENT2) { - if (PARENTSIDEBYSIDE) { - allowedMovement.x *= 2.f / PPARENT->size.x; - PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9); - PPARENT->recalcSizePosRecursive(*PANIMATE == 0); - } else { - allowedMovement.y *= 2.f / PPARENT->size.y; - PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9); - PPARENT->recalcSizePosRecursive(*PANIMATE == 0); - } - - return; + if (PHINNER) { + const auto ORIGINAL = PHINNER->size.x; + PHOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0); + if (PHINNER->pParent->children[0] == PHINNER) + PHINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.x) / PHINNER->pParent->size.x * 2.f, 0.1, 1.9); + else + PHINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.x) / PHINNER->pParent->size.x * 2.f, 0.1, 1.9); + PHINNER->pParent->recalcSizePosRecursive(*PANIMATE == 0); + } else + PHOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0); } - // 2 axes of freedom - const auto SIDECONTAINER = PARENTSIDEBYSIDE ? PPARENT : PPARENT2; - const auto TOPCONTAINER = PARENTSIDEBYSIDE ? PPARENT2 : PPARENT; + if (PVOUTER) { + PVOUTER->pParent->splitRatio = std::clamp(PVOUTER->pParent->splitRatio + allowedMovement.y * 2.f / PVOUTER->pParent->size.y, 0.1, 1.9); - allowedMovement.x *= 2.f / SIDECONTAINER->size.x; - allowedMovement.y *= 2.f / TOPCONTAINER->size.y; - - SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, 0.1, 1.9); - TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, 0.1, 1.9); - SIDECONTAINER->recalcSizePosRecursive(*PANIMATE == 0); - TOPCONTAINER->recalcSizePosRecursive(*PANIMATE == 0); + if (PVINNER) { + const auto ORIGINAL = PVINNER->size.y; + PVOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0); + if (PVINNER->pParent->children[0] == PVINNER) + PVINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.y) / PVINNER->pParent->size.y * 2.f, 0.1, 1.9); + else + PVINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.y) / PVINNER->pParent->size.y * 2.f, 0.1, 1.9); + PVINNER->pParent->recalcSizePosRecursive(*PANIMATE == 0); + } else + PVOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0); + } } void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode fullscreenMode, bool on) { diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index ed7ddf86..efb3fc5d 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -55,7 +55,7 @@ class CHyprDwindleLayout : public IHyprLayout { virtual void recalculateMonitor(const int&); virtual void recalculateWindow(CWindow*); virtual void onBeginDragWindow(); - virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr); + virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, CWindow* pWindow = nullptr); virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool); virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 582b719a..a9317d4b 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -344,7 +344,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); } else { - resizeActiveWindow(TICKDELTA, DRAGGINGWINDOW); + resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW); } } diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index fe1f8b5b..a6bd1829 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -15,9 +15,9 @@ struct SLayoutMessageHeader { enum eFullscreenMode : uint8_t; -enum eRectCorner -{ - CORNER_TOPLEFT = 0, +enum eRectCorner { + CORNER_NONE = 0, + CORNER_TOPLEFT, CORNER_TOPRIGHT, CORNER_BOTTOMRIGHT, CORNER_BOTTOMLEFT @@ -76,7 +76,7 @@ interface IHyprLayout { Vector2D holds pixel values Optional pWindow for a specific window */ - virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr) = 0; + virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, CWindow* pWindow = nullptr) = 0; /* Called when a user requests a move of the current window by a vec Vector2D holds pixel values @@ -146,7 +146,7 @@ interface IHyprLayout { /* Called for replacing any data a layout has for a new window */ - virtual void replaceWindowDataWith(CWindow * from, CWindow * to) = 0; + virtual void replaceWindowDataWith(CWindow* from, CWindow* to) = 0; private: Vector2D m_vBeginDragXY; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index b7e5a1bf..e0000914 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -294,7 +294,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { if ((WINDOWS < 2) && !centerMasterWindow) { PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition; PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, - PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); applyNodeDataToWindow(PMASTERNODE); return; } else if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT || (orientation == ORIENTATION_CENTER && STACKWINDOWS <= 1)) { @@ -590,7 +590,7 @@ bool CHyprMasterLayout::isWindowTiled(CWindow* pWindow) { return getNodeFromWindow(pWindow) != nullptr; } -void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* pWindow) { +void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorner corner, CWindow* pWindow) { const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow; if (!g_pCompositor->windowValidMapped(PWINDOW)) diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 315b82a2..251e95f5 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -9,8 +9,7 @@ enum eFullscreenMode : uint8_t; //orientation determines which side of the screen the master area resides -enum eOrientation : uint8_t -{ +enum eOrientation : uint8_t { ORIENTATION_LEFT = 0, ORIENTATION_TOP, ORIENTATION_RIGHT, @@ -52,7 +51,7 @@ class CHyprMasterLayout : public IHyprLayout { virtual bool isWindowTiled(CWindow*); virtual void recalculateMonitor(const int&); virtual void recalculateWindow(CWindow*); - virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr); + virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, CWindow* pWindow = nullptr); virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool); virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index a89f1d5e..246472dc 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1638,7 +1638,7 @@ void CKeybindManager::resizeWindow(std::string args) { if (SIZ.x < 1 || SIZ.y < 1) return; - g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW); + g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), CORNER_NONE, PWINDOW); if (PWINDOW->m_vRealSize.goalv().x > 1 && PWINDOW->m_vRealSize.goalv().y > 1) PWINDOW->setHidden(false);