algo/dwindle: don't crash on empty swapsplit (#13533)
ref https://github.com/hyprwm/Hyprland/discussions/13530
This commit is contained in:
parent
a6e3a2478c
commit
3faddf40d0
3 changed files with 36 additions and 26 deletions
|
|
@ -84,14 +84,13 @@ static void test13349() {
|
||||||
static void testSplit() {
|
static void testSplit() {
|
||||||
// Test various split methods
|
// Test various split methods
|
||||||
|
|
||||||
for (auto const& win : {"a", "b"}) {
|
Tests::spawnKitty("a");
|
||||||
if (!Tests::spawnKitty(win)) {
|
|
||||||
NLog::log("{}Failed to spawn kitty with win class `{}`", Colors::RED, win);
|
// these must not crash
|
||||||
++TESTS_FAILED;
|
EXPECT_NOT(getFromSocket("/dispatch layoutmsg swapsplit"), "ok");
|
||||||
ret = 1;
|
EXPECT_NOT(getFromSocket("/dispatch layoutmsg splitratio 1 exact"), "ok");
|
||||||
return;
|
|
||||||
}
|
Tests::spawnKitty("b");
|
||||||
}
|
|
||||||
|
|
||||||
OK(getFromSocket("/dispatch focuswindow class:a"));
|
OK(getFromSocket("/dispatch focuswindow class:a"));
|
||||||
OK(getFromSocket("/dispatch layoutmsg splitratio -0.2"));
|
OK(getFromSocket("/dispatch layoutmsg splitratio -0.2"));
|
||||||
|
|
|
||||||
|
|
@ -657,11 +657,15 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_
|
||||||
const auto CURRENT_NODE = getNodeFromWindow(Desktop::focusState()->window());
|
const auto CURRENT_NODE = getNodeFromWindow(Desktop::focusState()->window());
|
||||||
|
|
||||||
if (ARGS[0] == "togglesplit") {
|
if (ARGS[0] == "togglesplit") {
|
||||||
if (CURRENT_NODE)
|
if (CURRENT_NODE) {
|
||||||
toggleSplit(CURRENT_NODE);
|
if (!toggleSplit(CURRENT_NODE))
|
||||||
|
return std::unexpected("can't togglesplit in the current workspace");
|
||||||
|
}
|
||||||
} else if (ARGS[0] == "swapsplit") {
|
} else if (ARGS[0] == "swapsplit") {
|
||||||
if (CURRENT_NODE)
|
if (CURRENT_NODE) {
|
||||||
swapSplit(CURRENT_NODE);
|
if (!swapSplit(CURRENT_NODE))
|
||||||
|
return std::unexpected("can't swapsplit in the current workspace");
|
||||||
|
}
|
||||||
} else if (ARGS[0] == "movetoroot") {
|
} else if (ARGS[0] == "movetoroot") {
|
||||||
auto node = CURRENT_NODE;
|
auto node = CURRENT_NODE;
|
||||||
if (!ARGS[1].empty()) {
|
if (!ARGS[1].empty()) {
|
||||||
|
|
@ -671,7 +675,8 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto STABLE = ARGS[2].empty() || ARGS[2] != "unstable";
|
const auto STABLE = ARGS[2].empty() || ARGS[2] != "unstable";
|
||||||
moveToRoot(node, STABLE);
|
if (!moveToRoot(node, STABLE))
|
||||||
|
return std::unexpected("can't movetoroot in the current workspace");
|
||||||
} else if (ARGS[0] == "preselect") {
|
} else if (ARGS[0] == "preselect") {
|
||||||
auto direction = ARGS[1];
|
auto direction = ARGS[1];
|
||||||
|
|
||||||
|
|
@ -730,37 +735,41 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDwindleAlgorithm::toggleSplit(SP<SDwindleNodeData> x) {
|
bool CDwindleAlgorithm::toggleSplit(SP<SDwindleNodeData> x) {
|
||||||
if (!x || !x->pParent)
|
if (!x || !x->pParent)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (x->pTarget->fullscreenMode() != FSMODE_NONE)
|
if (x->pTarget->fullscreenMode() != FSMODE_NONE)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
x->pParent->splitTop = !x->pParent->splitTop;
|
x->pParent->splitTop = !x->pParent->splitTop;
|
||||||
|
|
||||||
x->pParent->recalcSizePosRecursive();
|
x->pParent->recalcSizePosRecursive();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDwindleAlgorithm::swapSplit(SP<SDwindleNodeData> x) {
|
bool CDwindleAlgorithm::swapSplit(SP<SDwindleNodeData> x) {
|
||||||
if (x->pTarget->fullscreenMode() != FSMODE_NONE)
|
if (x->pTarget->fullscreenMode() != FSMODE_NONE || !x->pParent)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
std::swap(x->pParent->children[0], x->pParent->children[1]);
|
std::swap(x->pParent->children[0], x->pParent->children[1]);
|
||||||
|
|
||||||
x->pParent->recalcSizePosRecursive();
|
x->pParent->recalcSizePosRecursive();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDwindleAlgorithm::moveToRoot(SP<SDwindleNodeData> x, bool stable) {
|
bool CDwindleAlgorithm::moveToRoot(SP<SDwindleNodeData> x, bool stable) {
|
||||||
if (!x || !x->pParent)
|
if (!x || !x->pParent)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (x->pTarget->fullscreenMode() != FSMODE_NONE)
|
if (x->pTarget->fullscreenMode() != FSMODE_NONE)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
// already at root
|
// already at root
|
||||||
if (!x->pParent->pParent)
|
if (!x->pParent->pParent)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
auto& pNode = x->pParent->children[0] == x ? x->pParent->children[0] : x->pParent->children[1];
|
auto& pNode = x->pParent->children[0] == x ? x->pParent->children[0] : x->pParent->children[1];
|
||||||
|
|
||||||
|
|
@ -781,4 +790,6 @@ void CDwindleAlgorithm::moveToRoot(SP<SDwindleNodeData> x, bool stable) {
|
||||||
std::swap(pRoot->children[0], pRoot->children[1]);
|
std::swap(pRoot->children[0], pRoot->children[1]);
|
||||||
|
|
||||||
pRoot->recalcSizePosRecursive();
|
pRoot->recalcSizePosRecursive();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,9 @@ namespace Layout::Tiled {
|
||||||
SP<SDwindleNodeData> getClosestNode(const Vector2D&, SP<ITarget> skip = nullptr);
|
SP<SDwindleNodeData> getClosestNode(const Vector2D&, SP<ITarget> skip = nullptr);
|
||||||
SP<SDwindleNodeData> getMasterNode();
|
SP<SDwindleNodeData> getMasterNode();
|
||||||
|
|
||||||
void toggleSplit(SP<SDwindleNodeData>);
|
bool toggleSplit(SP<SDwindleNodeData>);
|
||||||
void swapSplit(SP<SDwindleNodeData>);
|
bool swapSplit(SP<SDwindleNodeData>);
|
||||||
void moveToRoot(SP<SDwindleNodeData>, bool stable = true);
|
bool moveToRoot(SP<SDwindleNodeData>, bool stable = true);
|
||||||
|
|
||||||
Math::eDirection m_overrideDirection = Math::DIRECTION_DEFAULT;
|
Math::eDirection m_overrideDirection = Math::DIRECTION_DEFAULT;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue