aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/layout
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2023-09-04 15:34:07 +0200
committervaxerski <[email protected]>2023-09-04 15:34:13 +0200
commit9f3a64481ecb277de6775efbb0f3d8d7648a610c (patch)
tree3cb4632d376e389cf2bfad882a71627e5ee95182 /src/layout
parent69439871e60eeb16993fd6044843d14d2191c9fb (diff)
downloadHyprland-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.cpp45
-rw-r--r--src/layout/DwindleLayout.hpp21
-rw-r--r--src/layout/IHyprLayout.hpp9
-rw-r--r--src/layout/MasterLayout.cpp9
-rw-r--r--src/layout/MasterLayout.hpp4
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);