Dwindle: Make resize more intuitive (#2681)

* improved resize

* clang-format

* rewrite

* almost legacy behavior when using CORNER_NONE
This commit is contained in:
Daniel Adolfsson 2023-07-13 16:52:11 +02:00 committed by GitHub
parent 70dae78c1b
commit d3a644d81c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 59 deletions

View file

@ -586,7 +586,7 @@ void CHyprDwindleLayout::onBeginDragWindow() {
IHyprLayout::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; const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
@ -656,62 +656,64 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
if (DISPLAYBOTTOM && DISPLAYTOP) if (DISPLAYBOTTOM && DISPLAYTOP)
allowedMovement.y = 0; allowedMovement.y = 0;
// get the correct containers to apply splitratio to // Identify inner and outer nodes for both directions.
const auto PPARENT = PNODE->pParent;
if (!PPARENT) SDwindleNodeData* PVOUTER = nullptr;
return; // the only window on a workspace, ignore 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 for (auto PCURRENT = PNODE; PCURRENT && PCURRENT->pParent; PCURRENT = PCURRENT->pParent) {
auto PPARENT2 = PPARENT->pParent; const auto PPARENT = PCURRENT->pParent;
// No parent means we have only 2 windows, and thus one axis of freedom if (!PVOUTER && PPARENT->splitTop && (NONE || (TOP && PPARENT->children[1] == PCURRENT) || (BOTTOM && PPARENT->children[0] == PCURRENT)))
if (!PPARENT2) { PVOUTER = PCURRENT;
if (PARENTSIDEBYSIDE) { else if (!PVOUTER && !PVINNER && PPARENT->splitTop)
allowedMovement.x *= 2.f / PPARENT->size.x; PVINNER = PCURRENT;
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9); else if (!PHOUTER && !PPARENT->splitTop && (NONE || (LEFT && PPARENT->children[1] == PCURRENT) || (RIGHT && PPARENT->children[0] == PCURRENT)))
PPARENT->recalcSizePosRecursive(*PANIMATE == 0); PHOUTER = PCURRENT;
} else { else if (!PHOUTER && !PHINNER && !PPARENT->splitTop)
allowedMovement.y *= 2.f / PPARENT->size.y; PHINNER = PCURRENT;
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
}
return; if (PVOUTER && PHOUTER)
break;
} }
// Get first parent with other split if (PHOUTER) {
while (PPARENT2 && PPARENT2->splitTop == !PARENTSIDEBYSIDE) PHOUTER->pParent->splitRatio = std::clamp(PHOUTER->pParent->splitRatio + allowedMovement.x * 2.f / PHOUTER->pParent->size.x, 0.1, 1.9);
PPARENT2 = PPARENT2->pParent;
// no parent, one axis of freedom if (PHINNER) {
if (!PPARENT2) { const auto ORIGINAL = PHINNER->size.x;
if (PARENTSIDEBYSIDE) { PHOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
allowedMovement.x *= 2.f / PPARENT->size.x; if (PHINNER->pParent->children[0] == PHINNER)
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9); PHINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.x) / PHINNER->pParent->size.x * 2.f, 0.1, 1.9);
PPARENT->recalcSizePosRecursive(*PANIMATE == 0); else
} else { PHINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.x) / PHINNER->pParent->size.x * 2.f, 0.1, 1.9);
allowedMovement.y *= 2.f / PPARENT->size.y; PHINNER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9); } else
PPARENT->recalcSizePosRecursive(*PANIMATE == 0); PHOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
}
return;
} }
// 2 axes of freedom if (PVOUTER) {
const auto SIDECONTAINER = PARENTSIDEBYSIDE ? PPARENT : PPARENT2; PVOUTER->pParent->splitRatio = std::clamp(PVOUTER->pParent->splitRatio + allowedMovement.y * 2.f / PVOUTER->pParent->size.y, 0.1, 1.9);
const auto TOPCONTAINER = PARENTSIDEBYSIDE ? PPARENT2 : PPARENT;
allowedMovement.x *= 2.f / SIDECONTAINER->size.x; if (PVINNER) {
allowedMovement.y *= 2.f / TOPCONTAINER->size.y; const auto ORIGINAL = PVINNER->size.y;
PVOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, 0.1, 1.9); if (PVINNER->pParent->children[0] == PVINNER)
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, 0.1, 1.9); PVINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.y) / PVINNER->pParent->size.y * 2.f, 0.1, 1.9);
SIDECONTAINER->recalcSizePosRecursive(*PANIMATE == 0); else
TOPCONTAINER->recalcSizePosRecursive(*PANIMATE == 0); 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) { void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode fullscreenMode, bool on) {

View file

@ -55,7 +55,7 @@ class CHyprDwindleLayout : public IHyprLayout {
virtual void recalculateMonitor(const int&); virtual void recalculateMonitor(const int&);
virtual void recalculateWindow(CWindow*); virtual void recalculateWindow(CWindow*);
virtual void onBeginDragWindow(); 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 void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool);
virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);

View file

@ -344,7 +344,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
} else { } else {
resizeActiveWindow(TICKDELTA, DRAGGINGWINDOW); resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW);
} }
} }

View file

@ -15,9 +15,9 @@ struct SLayoutMessageHeader {
enum eFullscreenMode : uint8_t; enum eFullscreenMode : uint8_t;
enum eRectCorner enum eRectCorner {
{ CORNER_NONE = 0,
CORNER_TOPLEFT = 0, CORNER_TOPLEFT,
CORNER_TOPRIGHT, CORNER_TOPRIGHT,
CORNER_BOTTOMRIGHT, CORNER_BOTTOMRIGHT,
CORNER_BOTTOMLEFT CORNER_BOTTOMLEFT
@ -76,7 +76,7 @@ interface IHyprLayout {
Vector2D holds pixel values Vector2D holds pixel values
Optional pWindow for a specific window 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 Called when a user requests a move of the current window by a vec
Vector2D holds pixel values Vector2D holds pixel values
@ -146,7 +146,7 @@ interface IHyprLayout {
/* /*
Called for replacing any data a layout has for a new window 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: private:
Vector2D m_vBeginDragXY; Vector2D m_vBeginDragXY;

View file

@ -294,7 +294,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if ((WINDOWS < 2) && !centerMasterWindow) { if ((WINDOWS < 2) && !centerMasterWindow) {
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition; PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, 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); applyNodeDataToWindow(PMASTERNODE);
return; return;
} else if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT || (orientation == ORIENTATION_CENTER && STACKWINDOWS <= 1)) { } 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; 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; const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!g_pCompositor->windowValidMapped(PWINDOW))

View file

@ -9,8 +9,7 @@
enum eFullscreenMode : uint8_t; enum eFullscreenMode : uint8_t;
//orientation determines which side of the screen the master area resides //orientation determines which side of the screen the master area resides
enum eOrientation : uint8_t enum eOrientation : uint8_t {
{
ORIENTATION_LEFT = 0, ORIENTATION_LEFT = 0,
ORIENTATION_TOP, ORIENTATION_TOP,
ORIENTATION_RIGHT, ORIENTATION_RIGHT,
@ -52,7 +51,7 @@ class CHyprMasterLayout : public IHyprLayout {
virtual bool isWindowTiled(CWindow*); virtual bool isWindowTiled(CWindow*);
virtual void recalculateMonitor(const int&); virtual void recalculateMonitor(const int&);
virtual void recalculateWindow(CWindow*); 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 void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool);
virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);

View file

@ -1638,7 +1638,7 @@ void CKeybindManager::resizeWindow(std::string args) {
if (SIZ.x < 1 || SIZ.y < 1) if (SIZ.x < 1 || SIZ.y < 1)
return; 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) if (PWINDOW->m_vRealSize.goalv().x > 1 && PWINDOW->m_vRealSize.goalv().y > 1)
PWINDOW->setHidden(false); PWINDOW->setHidden(false);