diff options
author | vaxerski <[email protected]> | 2023-09-04 15:34:07 +0200 |
---|---|---|
committer | vaxerski <[email protected]> | 2023-09-04 15:34:13 +0200 |
commit | 9f3a64481ecb277de6775efbb0f3d8d7648a610c (patch) | |
tree | 3cb4632d376e389cf2bfad882a71627e5ee95182 /src/layout | |
parent | 69439871e60eeb16993fd6044843d14d2191c9fb (diff) | |
download | Hyprland-9f3a64481ecb277de6775efbb0f3d8d7648a610c.tar.gz Hyprland-9f3a64481ecb277de6775efbb0f3d8d7648a610c.zip |
dwindle: add proper movement for window move binds
ditches the "movewindow = swapwindow" mechanism. Fixes #2804
Diffstat (limited to 'src/layout')
-rw-r--r-- | src/layout/DwindleLayout.cpp | 45 | ||||
-rw-r--r-- | src/layout/DwindleLayout.hpp | 21 | ||||
-rw-r--r-- | src/layout/IHyprLayout.hpp | 9 | ||||
-rw-r--r-- | src/layout/MasterLayout.cpp | 9 | ||||
-rw-r--r-- | src/layout/MasterLayout.hpp | 4 |
5 files changed, 73 insertions, 15 deletions
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 5bee0f4f..92b81687 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -245,11 +245,13 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { PNODE->layout = this; SDwindleNodeData* OPENINGON; - const auto MONFROMCURSOR = g_pCompositor->getMonitorFromCursor(); + + const auto MOUSECOORDS = m_vOverrideFocalPoint.value_or(g_pInputManager->getMouseCoordsInternal()); + const auto MONFROMCURSOR = g_pCompositor->getMonitorFromVector(MOUSECOORDS); if (PMONITOR->ID == MONFROMCURSOR->ID && (PNODE->workspaceID == PMONITOR->activeWorkspace || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->specialWorkspaceID)) && !*PUSEACTIVE) { - OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())); + OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(MOUSECOORDS)); // happens on reserved area if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0) @@ -260,7 +262,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) { OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow); } else { - OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())); + OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(MOUSECOORDS)); } if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0) @@ -312,8 +314,6 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { return; } - const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); - // 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 @@ -884,6 +884,41 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow return hints; } +void CHyprDwindleLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) { + if (!isDirection(dir)) + return; + + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE) + return; + + Vector2D focalPoint; + + switch (dir[0]) { + case 't': + case 'u': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x / 2.f, -1}; break; + case 'd': + case 'b': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x / 2.f, pWindow->m_vSize.y + 1}; break; + case 'l': focalPoint = pWindow->m_vPosition + Vector2D{-1, pWindow->m_vSize.y / 2.f}; break; + case 'r': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x + 1, pWindow->m_vSize.y / 2.f}; break; + default: UNREACHABLE(); + } + + onWindowRemovedTiling(pWindow); + + m_vOverrideFocalPoint = focalPoint; + + const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(focalPoint); + + pWindow->moveToWorkspace(PMONITORFOCAL->activeWorkspace); + pWindow->m_iMonitorID = PMONITORFOCAL->ID; + + onWindowCreatedTiling(pWindow); + + m_vOverrideFocalPoint.reset(); +} + void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { // windows should be valid, insallah diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index efb3fc5d..a901e4da 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -5,11 +5,13 @@ #include <deque> #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include <array> +#include <optional> class CHyprDwindleLayout; enum eFullscreenMode : uint8_t; -enum OneTimeFocus { +enum OneTimeFocus +{ UP = 0, RIGHT, DOWN, @@ -60,6 +62,7 @@ class CHyprDwindleLayout : public IHyprLayout { virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); virtual void switchWindows(CWindow*, CWindow*); + virtual void moveWindowTo(CWindow*, const std::string& dir); virtual void alterSplitRatio(CWindow*, float, bool); virtual std::string getLayoutName(); virtual void replaceWindowDataWith(CWindow* from, CWindow* to); @@ -77,15 +80,17 @@ class CHyprDwindleLayout : public IHyprLayout { bool yExtent = false; } m_PseudoDragFlags; - int getNodesOnWorkspace(const int&); - void applyNodeDataToWindow(SDwindleNodeData*, bool force = false); - SDwindleNodeData* getNodeFromWindow(CWindow*); - SDwindleNodeData* getFirstNodeOnWorkspace(const int&); - SDwindleNodeData* getMasterNodeOnWorkspace(const int&); + std::optional<Vector2D> m_vOverrideFocalPoint; // for onWindowCreatedTiling. - void toggleSplit(CWindow*); + int getNodesOnWorkspace(const int&); + void applyNodeDataToWindow(SDwindleNodeData*, bool force = false); + SDwindleNodeData* getNodeFromWindow(CWindow*); + SDwindleNodeData* getFirstNodeOnWorkspace(const int&); + SDwindleNodeData* getMasterNodeOnWorkspace(const int&); - OneTimeFocus overrideDirection = OneTimeFocus::NOFOCUS; + void toggleSplit(CWindow*); + + OneTimeFocus overrideDirection = OneTimeFocus::NOFOCUS; friend struct SDwindleNodeData; }; diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index c673b330..a0d5b2bb 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -15,7 +15,8 @@ struct SLayoutMessageHeader { enum eFullscreenMode : uint8_t; -enum eRectCorner { +enum eRectCorner +{ CORNER_NONE = 0, CORNER_TOPLEFT, CORNER_TOPRIGHT, @@ -123,6 +124,12 @@ class IHyprLayout { virtual void switchWindows(CWindow*, CWindow*) = 0; /* + Called when the user requests a window move in a direction. + The layout is free to ignore. + */ + virtual void moveWindowTo(CWindow*, const std::string& direction) = 0; + + /* Called when the user requests to change the splitratio by or to X on a window */ diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index cae0f67a..b5a867d8 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -743,6 +743,15 @@ SWindowRenderLayoutHints CHyprMasterLayout::requestRenderHints(CWindow* pWindow) return hints; // master doesnt have any hints } +void CHyprMasterLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) { + if (!isDirection(dir)) + return; + + const auto PWINDOW2 = g_pCompositor->getWindowInDirection(pWindow, dir[0]); + + switchWindows(pWindow, PWINDOW2); +} + void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { // windows should be valid, insallah diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 251e95f5..7cc11511 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -9,7 +9,8 @@ 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, @@ -56,6 +57,7 @@ class CHyprMasterLayout : public IHyprLayout { virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); virtual void switchWindows(CWindow*, CWindow*); + virtual void moveWindowTo(CWindow*, const std::string& dir); virtual void alterSplitRatio(CWindow*, float, bool); virtual std::string getLayoutName(); virtual void replaceWindowDataWith(CWindow* from, CWindow* to); |