mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 13:05:58 +01:00
layout: add direction parameter to onWindowCreated and friends (#3269)
* feat(layout): add direction parameter to onWindowCreated and friends In addition: - Implement directional moveWindowOutOfGroup for `movewindoworgroup` when using dwindle layout. (augmentation of #3006) - Replace `DWindleLayout::OneTimeFocus` with `IHyprLayout::eDirection`. - Slight formatting change (clang-format). * fix: nullptr dereference in dwindle window creation * refactor: generalized eDirection * refactor: eliminate DIRECTION_NONE * Update IHyprLayout.hpp
This commit is contained in:
parent
b0d5e4008b
commit
6b1ac659e0
8 changed files with 69 additions and 59 deletions
|
@ -226,7 +226,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||||
PWINDOW->updateWindowDecos();
|
PWINDOW->updateWindowDecos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direction) {
|
||||||
if (pWindow->m_bIsFloating)
|
if (pWindow->m_bIsFloating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -238,6 +238,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||||
static auto* const PUSEACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:use_active_for_splits")->intValue;
|
static auto* const PUSEACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:use_active_for_splits")->intValue;
|
||||||
static auto* const PDEFAULTSPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:default_split_ratio")->floatValue;
|
static auto* const PDEFAULTSPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:default_split_ratio")->floatValue;
|
||||||
|
|
||||||
|
if (direction != DIRECTION_DEFAULT && overrideDirection == DIRECTION_DEFAULT)
|
||||||
|
overrideDirection = direction;
|
||||||
|
|
||||||
// Populate the node with our window's data
|
// Populate the node with our window's data
|
||||||
PNODE->workspaceID = pWindow->m_iWorkspaceID;
|
PNODE->workspaceID = pWindow->m_iWorkspaceID;
|
||||||
PNODE->pWindow = pWindow;
|
PNODE->pWindow = pWindow;
|
||||||
|
@ -297,7 +300,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||||
// last fail-safe to avoid duplicate fullscreens
|
// last fail-safe to avoid duplicate fullscreens
|
||||||
if ((!OPENINGON || OPENINGON->pWindow == pWindow) && getNodesOnWorkspace(PNODE->workspaceID) > 1) {
|
if ((!OPENINGON || OPENINGON->pWindow == pWindow) && getNodesOnWorkspace(PNODE->workspaceID) > 1) {
|
||||||
for (auto& node : m_lDwindleNodesData) {
|
for (auto& node : m_lDwindleNodesData) {
|
||||||
if (node.workspaceID == PNODE->workspaceID && node.pWindow != pWindow) {
|
if (node.workspaceID == PNODE->workspaceID && node.pWindow != nullptr && node.pWindow != pWindow) {
|
||||||
OPENINGON = &node;
|
OPENINGON = &node;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -372,7 +375,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||||
bool verticalOverride = false;
|
bool verticalOverride = false;
|
||||||
|
|
||||||
// let user select position -> top, right, bottom, left
|
// let user select position -> top, right, bottom, left
|
||||||
if (overrideDirection != OneTimeFocus::NOFOCUS) {
|
if (overrideDirection != DIRECTION_DEFAULT) {
|
||||||
|
|
||||||
// this is horizontal
|
// this is horizontal
|
||||||
if (overrideDirection % 2 == 0)
|
if (overrideDirection % 2 == 0)
|
||||||
|
@ -391,7 +394,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||||
|
|
||||||
// whether or not the override persists after opening one window
|
// whether or not the override persists after opening one window
|
||||||
if (*PERMANENTDIRECTIONOVERRIDE == 0)
|
if (*PERMANENTDIRECTIONOVERRIDE == 0)
|
||||||
overrideDirection = OneTimeFocus::NOFOCUS;
|
overrideDirection = DIRECTION_DEFAULT;
|
||||||
} else if (*PSMARTSPLIT == 1) {
|
} else if (*PSMARTSPLIT == 1) {
|
||||||
const auto tl = NEWPARENT->position;
|
const auto tl = NEWPARENT->position;
|
||||||
const auto tr = NEWPARENT->position + Vector2D(NEWPARENT->size.x, 0);
|
const auto tr = NEWPARENT->position + Vector2D(NEWPARENT->size.x, 0);
|
||||||
|
@ -994,26 +997,26 @@ std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::str
|
||||||
switch (direction.front()) {
|
switch (direction.front()) {
|
||||||
case 'u':
|
case 'u':
|
||||||
case 't': {
|
case 't': {
|
||||||
overrideDirection = OneTimeFocus::UP;
|
overrideDirection = DIRECTION_UP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'b': {
|
case 'b': {
|
||||||
overrideDirection = OneTimeFocus::DOWN;
|
overrideDirection = DIRECTION_DOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'r': {
|
case 'r': {
|
||||||
overrideDirection = OneTimeFocus::RIGHT;
|
overrideDirection = DIRECTION_RIGHT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'l': {
|
case 'l': {
|
||||||
overrideDirection = OneTimeFocus::LEFT;
|
overrideDirection = DIRECTION_LEFT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
// any other character resets the focus direction
|
// any other character resets the focus direction
|
||||||
// needed for the persistent mode
|
// needed for the persistent mode
|
||||||
overrideDirection = OneTimeFocus::NOFOCUS;
|
overrideDirection = DIRECTION_DEFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,6 @@
|
||||||
class CHyprDwindleLayout;
|
class CHyprDwindleLayout;
|
||||||
enum eFullscreenMode : uint8_t;
|
enum eFullscreenMode : uint8_t;
|
||||||
|
|
||||||
enum OneTimeFocus
|
|
||||||
{
|
|
||||||
UP = 0,
|
|
||||||
RIGHT,
|
|
||||||
DOWN,
|
|
||||||
LEFT,
|
|
||||||
NOFOCUS,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDwindleNodeData {
|
struct SDwindleNodeData {
|
||||||
SDwindleNodeData* pParent = nullptr;
|
SDwindleNodeData* pParent = nullptr;
|
||||||
bool isNode = false;
|
bool isNode = false;
|
||||||
|
@ -51,7 +42,7 @@ struct SDwindleNodeData {
|
||||||
|
|
||||||
class CHyprDwindleLayout : public IHyprLayout {
|
class CHyprDwindleLayout : public IHyprLayout {
|
||||||
public:
|
public:
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
virtual void onWindowCreatedTiling(CWindow*, eDirection direction = DIRECTION_DEFAULT);
|
||||||
virtual void onWindowRemovedTiling(CWindow*);
|
virtual void onWindowRemovedTiling(CWindow*);
|
||||||
virtual bool isWindowTiled(CWindow*);
|
virtual bool isWindowTiled(CWindow*);
|
||||||
virtual void recalculateMonitor(const int&);
|
virtual void recalculateMonitor(const int&);
|
||||||
|
@ -90,7 +81,7 @@ class CHyprDwindleLayout : public IHyprLayout {
|
||||||
|
|
||||||
void toggleSplit(CWindow*);
|
void toggleSplit(CWindow*);
|
||||||
|
|
||||||
OneTimeFocus overrideDirection = OneTimeFocus::NOFOCUS;
|
eDirection overrideDirection = DIRECTION_DEFAULT;
|
||||||
|
|
||||||
friend struct SDwindleNodeData;
|
friend struct SDwindleNodeData;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
void IHyprLayout::onWindowCreated(CWindow* pWindow) {
|
void IHyprLayout::onWindowCreated(CWindow* pWindow, eDirection direction) {
|
||||||
if (pWindow->m_bIsFloating) {
|
if (pWindow->m_bIsFloating) {
|
||||||
onWindowCreatedFloating(pWindow);
|
onWindowCreatedFloating(pWindow);
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,7 +18,7 @@ void IHyprLayout::onWindowCreated(CWindow* pWindow) {
|
||||||
|
|
||||||
pWindow->m_vPseudoSize = pWindow->m_vLastFloatingSize;
|
pWindow->m_vPseudoSize = pWindow->m_vLastFloatingSize;
|
||||||
|
|
||||||
onWindowCreatedTiling(pWindow);
|
onWindowCreatedTiling(pWindow, direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@ 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,
|
||||||
|
@ -24,6 +23,14 @@ enum eRectCorner
|
||||||
CORNER_BOTTOMLEFT
|
CORNER_BOTTOMLEFT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eDirection {
|
||||||
|
DIRECTION_DEFAULT = -1,
|
||||||
|
DIRECTION_UP = 0,
|
||||||
|
DIRECTION_RIGHT,
|
||||||
|
DIRECTION_DOWN,
|
||||||
|
DIRECTION_LEFT
|
||||||
|
};
|
||||||
|
|
||||||
class IHyprLayout {
|
class IHyprLayout {
|
||||||
public:
|
public:
|
||||||
virtual ~IHyprLayout() = 0;
|
virtual ~IHyprLayout() = 0;
|
||||||
|
@ -35,8 +42,8 @@ class IHyprLayout {
|
||||||
The layout HAS TO set the goal pos and size (anim mgr will use it)
|
The layout HAS TO set the goal pos and size (anim mgr will use it)
|
||||||
If !animationinprogress, then the anim mgr will not apply an anim.
|
If !animationinprogress, then the anim mgr will not apply an anim.
|
||||||
*/
|
*/
|
||||||
virtual void onWindowCreated(CWindow*);
|
virtual void onWindowCreated(CWindow*, eDirection direction = DIRECTION_DEFAULT);
|
||||||
virtual void onWindowCreatedTiling(CWindow*) = 0;
|
virtual void onWindowCreatedTiling(CWindow*, eDirection direction = DIRECTION_DEFAULT) = 0;
|
||||||
virtual void onWindowCreatedFloating(CWindow*);
|
virtual void onWindowCreatedFloating(CWindow*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -68,7 +68,7 @@ SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const int& ws) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direction) {
|
||||||
if (pWindow->m_bIsFloating)
|
if (pWindow->m_bIsFloating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -734,8 +734,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||||
if (RESIZEDELTA != 0 && nodesInSameColumn > 1) {
|
if (RESIZEDELTA != 0 && nodesInSameColumn > 1) {
|
||||||
const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE);
|
const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE);
|
||||||
const auto REVNODEIT = std::find(m_lMasterNodesData.rbegin(), m_lMasterNodesData.rend(), *PNODE);
|
const auto REVNODEIT = std::find(m_lMasterNodesData.rbegin(), m_lMasterNodesData.rend(), *PNODE);
|
||||||
const auto SIZE = isStackVertical ?
|
const auto SIZE = isStackVertical ? (PMONITOR->vecSize.y - PMONITOR->vecReservedTopLeft.y - PMONITOR->vecReservedBottomRight.y) / nodesInSameColumn :
|
||||||
(PMONITOR->vecSize.y - PMONITOR->vecReservedTopLeft.y - PMONITOR->vecReservedBottomRight.y) / nodesInSameColumn:
|
|
||||||
(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) / nodesInSameColumn;
|
(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) / nodesInSameColumn;
|
||||||
|
|
||||||
const float totalSize = isStackVertical ? WSSIZE.y : WSSIZE.x;
|
const float totalSize = isStackVertical ? WSSIZE.y : WSSIZE.x;
|
||||||
|
@ -774,7 +773,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||||
|
|
||||||
// resize the other nodes
|
// resize the other nodes
|
||||||
nodeCount = 0;
|
nodeCount = 0;
|
||||||
auto resizeNodesLeft = [maxSizeIncrease, resizeDiff, minSize, orientation, isStackVertical, SIZE, &nodeCount, nodesLeft, PNODE](auto &it) {
|
auto resizeNodesLeft = [maxSizeIncrease, resizeDiff, minSize, orientation, isStackVertical, SIZE, &nodeCount, nodesLeft, PNODE](auto& it) {
|
||||||
if (it.isMaster != PNODE->isMaster || it.workspaceID != PNODE->workspaceID)
|
if (it.isMaster != PNODE->isMaster || it.workspaceID != PNODE->workspaceID)
|
||||||
return;
|
return;
|
||||||
nodeCount++;
|
nodeCount++;
|
||||||
|
@ -782,8 +781,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||||
if (!it.isMaster && orientation == ORIENTATION_CENTER && nodeCount % 2 == 1)
|
if (!it.isMaster && orientation == ORIENTATION_CENTER && nodeCount % 2 == 1)
|
||||||
return;
|
return;
|
||||||
const float size = isStackVertical ? it.size.y : it.size.x;
|
const float size = isStackVertical ? it.size.y : it.size.x;
|
||||||
const float resizeDeltaForEach = maxSizeIncrease != 0 ?
|
const float resizeDeltaForEach = maxSizeIncrease != 0 ? resizeDiff * (size - minSize) / maxSizeIncrease : resizeDiff / nodesLeft;
|
||||||
resizeDiff * (size - minSize) / maxSizeIncrease : resizeDiff / nodesLeft;
|
|
||||||
it.percSize -= resizeDeltaForEach / SIZE;
|
it.percSize -= resizeDeltaForEach / SIZE;
|
||||||
};
|
};
|
||||||
if (resizePrevNodes) {
|
if (resizePrevNodes) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct SMasterWorkspaceData {
|
||||||
|
|
||||||
class CHyprMasterLayout : public IHyprLayout {
|
class CHyprMasterLayout : public IHyprLayout {
|
||||||
public:
|
public:
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
virtual void onWindowCreatedTiling(CWindow*, eDirection direction = DIRECTION_DEFAULT);
|
||||||
virtual void onWindowRemovedTiling(CWindow*);
|
virtual void onWindowRemovedTiling(CWindow*);
|
||||||
virtual bool isWindowTiled(CWindow*);
|
virtual bool isWindowTiled(CWindow*);
|
||||||
virtual void recalculateMonitor(const int&);
|
virtual void recalculateMonitor(const int&);
|
||||||
|
|
|
@ -1963,9 +1963,20 @@ void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDi
|
||||||
g_pCompositor->warpCursorTo(pWindow->middle());
|
g_pCompositor->warpCursorTo(pWindow->middle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow) {
|
void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir) {
|
||||||
static auto* const BFOCUSREMOVEDWINDOW = &g_pConfigManager->getConfigValuePtr("misc:group_focus_removed_window")->intValue;
|
static auto* const BFOCUSREMOVEDWINDOW = &g_pConfigManager->getConfigValuePtr("misc:group_focus_removed_window")->intValue;
|
||||||
const auto PWINDOWPREV = pWindow->getGroupPrevious();
|
const auto PWINDOWPREV = pWindow->getGroupPrevious();
|
||||||
|
eDirection direction;
|
||||||
|
|
||||||
|
switch (dir[0]) {
|
||||||
|
case 't':
|
||||||
|
case 'u': direction = DIRECTION_UP; break;
|
||||||
|
case 'd':
|
||||||
|
case 'b': direction = DIRECTION_DOWN; break;
|
||||||
|
case 'l': direction = DIRECTION_LEFT; break;
|
||||||
|
case 'r': direction = DIRECTION_RIGHT; break;
|
||||||
|
default: direction = DIRECTION_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow);
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow);
|
||||||
|
|
||||||
|
@ -1973,7 +1984,7 @@ void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow) {
|
||||||
|
|
||||||
g_pKeybindManager->m_bGroupsLocked = true;
|
g_pKeybindManager->m_bGroupsLocked = true;
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow);
|
g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow, direction);
|
||||||
|
|
||||||
g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV;
|
g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV;
|
||||||
|
|
||||||
|
@ -2059,13 +2070,13 @@ void CKeybindManager::moveWindowOrGroup(std::string args) {
|
||||||
moveWindowIntoGroup(PWINDOW, PWINDOWINDIR);
|
moveWindowIntoGroup(PWINDOW, PWINDOWINDIR);
|
||||||
} else if (PWINDOWINDIR) {
|
} else if (PWINDOWINDIR) {
|
||||||
if (ISWINDOWGROUP && (*BIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED))
|
if (ISWINDOWGROUP && (*BIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED))
|
||||||
moveWindowOutOfGroup(PWINDOW);
|
moveWindowOutOfGroup(PWINDOW, args);
|
||||||
else {
|
else {
|
||||||
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
|
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
|
||||||
g_pCompositor->warpCursorTo(PWINDOW->middle());
|
g_pCompositor->warpCursorTo(PWINDOW->middle());
|
||||||
}
|
}
|
||||||
} else if (ISWINDOWGROUP && (*BIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED)) {
|
} else if (ISWINDOWGROUP && (*BIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED)) {
|
||||||
moveWindowOutOfGroup(PWINDOW);
|
moveWindowOutOfGroup(PWINDOW, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ class CKeybindManager {
|
||||||
bool ensureMouseBindState();
|
bool ensureMouseBindState();
|
||||||
|
|
||||||
static bool tryMoveFocusToMonitor(CMonitor* monitor);
|
static bool tryMoveFocusToMonitor(CMonitor* monitor);
|
||||||
static void moveWindowOutOfGroup(CWindow* pWindow);
|
static void moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir = "");
|
||||||
static void moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDirection);
|
static void moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDirection);
|
||||||
static void switchToWindow(CWindow* PWINDOWTOCHANGETO);
|
static void switchToWindow(CWindow* PWINDOWTOCHANGETO);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue