dwindle: add proper movement for window move binds

ditches the "movewindow = swapwindow" mechanism. Fixes #2804
This commit is contained in:
vaxerski 2023-09-04 15:34:07 +02:00
parent 69439871e6
commit 9f3a64481e
6 changed files with 76 additions and 18 deletions

View file

@ -245,11 +245,13 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
PNODE->layout = this; PNODE->layout = this;
SDwindleNodeData* OPENINGON; 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 && if (PMONITOR->ID == MONFROMCURSOR->ID &&
(PNODE->workspaceID == PMONITOR->activeWorkspace || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->specialWorkspaceID)) && !*PUSEACTIVE) { (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 // happens on reserved area
if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0) 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) { g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) {
OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow); OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow);
} else { } else {
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())); OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(MOUSECOORDS));
} }
if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0) if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0)
@ -312,8 +314,6 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
return; return;
} }
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
// if it's a group, add the window // if it's a group, add the window
if (OPENINGON->pWindow->m_sGroupData.pNextWindow && !OPENINGON->pWindow->getGroupHead()->m_sGroupData.locked && 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
@ -884,6 +884,41 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
return hints; 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) { void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
// windows should be valid, insallah // windows should be valid, insallah

View file

@ -5,11 +5,13 @@
#include <deque> #include <deque>
#include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include <array> #include <array>
#include <optional>
class CHyprDwindleLayout; class CHyprDwindleLayout;
enum eFullscreenMode : uint8_t; enum eFullscreenMode : uint8_t;
enum OneTimeFocus { enum OneTimeFocus
{
UP = 0, UP = 0,
RIGHT, RIGHT,
DOWN, DOWN,
@ -60,6 +62,7 @@ class CHyprDwindleLayout : public IHyprLayout {
virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
virtual void switchWindows(CWindow*, CWindow*); virtual void switchWindows(CWindow*, CWindow*);
virtual void moveWindowTo(CWindow*, const std::string& dir);
virtual void alterSplitRatio(CWindow*, float, bool); virtual void alterSplitRatio(CWindow*, float, bool);
virtual std::string getLayoutName(); virtual std::string getLayoutName();
virtual void replaceWindowDataWith(CWindow* from, CWindow* to); virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
@ -77,15 +80,17 @@ class CHyprDwindleLayout : public IHyprLayout {
bool yExtent = false; bool yExtent = false;
} m_PseudoDragFlags; } m_PseudoDragFlags;
int getNodesOnWorkspace(const int&); std::optional<Vector2D> m_vOverrideFocalPoint; // for onWindowCreatedTiling.
void applyNodeDataToWindow(SDwindleNodeData*, bool force = false);
SDwindleNodeData* getNodeFromWindow(CWindow*);
SDwindleNodeData* getFirstNodeOnWorkspace(const int&);
SDwindleNodeData* getMasterNodeOnWorkspace(const int&);
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; friend struct SDwindleNodeData;
}; };

View file

@ -15,7 +15,8 @@ struct SLayoutMessageHeader {
enum eFullscreenMode : uint8_t; enum eFullscreenMode : uint8_t;
enum eRectCorner { enum eRectCorner
{
CORNER_NONE = 0, CORNER_NONE = 0,
CORNER_TOPLEFT, CORNER_TOPLEFT,
CORNER_TOPRIGHT, CORNER_TOPRIGHT,
@ -122,6 +123,12 @@ class IHyprLayout {
*/ */
virtual void switchWindows(CWindow*, CWindow*) = 0; 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 Called when the user requests to change the splitratio by or to X
on a window on a window

View file

@ -743,6 +743,15 @@ SWindowRenderLayoutHints CHyprMasterLayout::requestRenderHints(CWindow* pWindow)
return hints; // master doesnt have any hints 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) { void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
// windows should be valid, insallah // windows should be valid, insallah

View file

@ -9,7 +9,8 @@
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,
@ -56,6 +57,7 @@ class CHyprMasterLayout : public IHyprLayout {
virtual std::any layoutMessage(SLayoutMessageHeader, std::string); virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
virtual void switchWindows(CWindow*, CWindow*); virtual void switchWindows(CWindow*, CWindow*);
virtual void moveWindowTo(CWindow*, const std::string& dir);
virtual void alterSplitRatio(CWindow*, float, bool); virtual void alterSplitRatio(CWindow*, float, bool);
virtual std::string getLayoutName(); virtual std::string getLayoutName();
virtual void replaceWindowDataWith(CWindow* from, CWindow* to); virtual void replaceWindowDataWith(CWindow* from, CWindow* to);

View file

@ -1160,9 +1160,9 @@ void CKeybindManager::moveActiveTo(std::string args) {
// If the window to change to is on the same workspace, switch them // If the window to change to is on the same workspace, switch them
const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
if (PWINDOWTOCHANGETO && PWINDOWTOCHANGETO->m_iWorkspaceID == PLASTWINDOW->m_iWorkspaceID) { if (PWINDOWTOCHANGETO) {
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, PWINDOWTOCHANGETO); g_pLayoutManager->getCurrentLayout()->moveWindowTo(PLASTWINDOW, args);
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->m_vRealPosition.vec() + PWINDOWTOCHANGETO->m_vRealSize.vec() / 2.0); g_pCompositor->warpCursorTo(PLASTWINDOW->m_vRealPosition.goalv() + PLASTWINDOW->m_vRealSize.goalv() / 2.0);
return; return;
} }