Skip to content

Commit

Permalink
Dwindle: Make resize more intuitive (#2681)
Browse files Browse the repository at this point in the history
* improved resize

* clang-format

* rewrite

* almost legacy behavior when using CORNER_NONE
  • Loading branch information
DanielAdolfsson committed Jul 13, 2023
1 parent 70dae78 commit d3a644d
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 59 deletions.
94 changes: 48 additions & 46 deletions src/layout/DwindleLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

// 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);
}
if (PHOUTER) {
PHOUTER->pParent->splitRatio = std::clamp(PHOUTER->pParent->splitRatio + allowedMovement.x * 2.f / PHOUTER->pParent->size.x, 0.1, 1.9);

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) {
Expand Down
2 changes: 1 addition & 1 deletion src/layout/DwindleLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down
2 changes: 1 addition & 1 deletion src/layout/IHyprLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/layout/IHyprLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/layout/MasterLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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))
Expand Down
5 changes: 2 additions & 3 deletions src/layout/MasterLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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*);
Expand Down
2 changes: 1 addition & 1 deletion src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit d3a644d

Please sign in to comment.