diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 14cbf28b..b99a3ae9 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -160,6 +160,7 @@ void CConfigManager::setDefaultVars() { configValues["dwindle:use_active_for_splits"].intValue = 1; configValues["dwindle:default_split_ratio"].floatValue = 1.f; configValues["dwindle:smart_split"].intValue = 0; + configValues["dwindle:smart_resizing"].intValue = 1; configValues["master:special_scale_factor"].floatValue = 0.8f; configValues["master:mfact"].floatValue = 0.55f; diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index d0d4dd23..bd131b16 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -318,7 +318,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { // if it's a group, add the window if (OPENINGON->pWindow->m_sGroupData.pNextWindow && !OPENINGON->pWindow->getGroupHead()->m_sGroupData.locked && - !g_pKeybindManager->m_bGroupsLocked) { // target is an unlocked group + !g_pKeybindManager->m_bGroupsLocked) { // target is an unlocked group if (!pWindow->m_sGroupData.pNextWindow) { // source is not a group m_lDwindleNodesData.remove(*PNODE); @@ -606,7 +606,8 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn return; } - const auto PANIMATE = &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + const auto PANIMATE = &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + const auto PSMARTRESIZING = &g_pConfigManager->getConfigValuePtr("dwindle:smart_resizing")->intValue; // get some data about our window const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); @@ -661,63 +662,121 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn if (DISPLAYBOTTOM && DISPLAYTOP) allowedMovement.y = 0; - // Identify inner and outer nodes for both directions. + if (*PSMARTRESIZING == 1) { + // Identify inner and outer nodes for both directions + SDwindleNodeData* PVOUTER = nullptr; + SDwindleNodeData* PVINNER = nullptr; + SDwindleNodeData* PHOUTER = nullptr; + SDwindleNodeData* PHINNER = nullptr; - SDwindleNodeData* PVOUTER = nullptr; - SDwindleNodeData* PVINNER = nullptr; - SDwindleNodeData* PHOUTER = nullptr; - SDwindleNodeData* PHINNER = nullptr; + 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; - 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; + for (auto PCURRENT = PNODE; PCURRENT && PCURRENT->pParent; PCURRENT = PCURRENT->pParent) { + const auto PPARENT = PCURRENT->pParent; - for (auto PCURRENT = PNODE; PCURRENT && PCURRENT->pParent; PCURRENT = PCURRENT->pParent) { - const auto PPARENT = PCURRENT->pParent; + 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; - 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; + if (PVOUTER && PHOUTER) + break; + } - if (PVOUTER && PHOUTER) - break; - } + if (PHOUTER) { + PHOUTER->pParent->splitRatio = std::clamp(PHOUTER->pParent->splitRatio + allowedMovement.x * 2.f / PHOUTER->pParent->size.x, 0.1, 1.9); - if (PHOUTER) { - PHOUTER->pParent->splitRatio = std::clamp(PHOUTER->pParent->splitRatio + allowedMovement.x * 2.f / PHOUTER->pParent->size.x, 0.1, 1.9); + 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); + } - 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); - } + if (PVOUTER) { + PVOUTER->pParent->splitRatio = std::clamp(PVOUTER->pParent->splitRatio + allowedMovement.y * 2.f / PVOUTER->pParent->size.y, 0.1, 1.9); - if (PVOUTER) { - PVOUTER->pParent->splitRatio = std::clamp(PVOUTER->pParent->splitRatio + allowedMovement.y * 2.f / PVOUTER->pParent->size.y, 0.1, 1.9); + 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); + } + } else { + // get the correct containers to apply splitratio to + const auto PPARENT = PNODE->pParent; - 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); + if (!PPARENT) + return; // the only window on a workspace, ignore + + const bool PARENTSIDEBYSIDE = !PPARENT->splitTop; + + // Get the parent's parent + auto PPARENT2 = PPARENT->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); + } + + return; + } + + // Get first parent with other split + while (PPARENT2 && PPARENT2->splitTop == !PARENTSIDEBYSIDE) + PPARENT2 = PPARENT2->pParent; + + // 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; + } + + // 2 axes of freedom + const auto SIDECONTAINER = PARENTSIDEBYSIDE ? PPARENT : PPARENT2; + const auto TOPCONTAINER = PARENTSIDEBYSIDE ? PPARENT2 : PPARENT; + + 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); } }