dwindle: add rotatesplit layoutmsg and tests (#13235)
This commit is contained in:
parent
1fa157cf6d
commit
8685fd7b0c
3 changed files with 146 additions and 0 deletions
|
|
@ -135,6 +135,98 @@ static void testSplit() {
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void testRotatesplit() {
|
||||||
|
OK(getFromSocket("r/keyword general:gaps_in 0"));
|
||||||
|
OK(getFromSocket("r/keyword general:gaps_out 0"));
|
||||||
|
OK(getFromSocket("r/keyword general:border_size 0"));
|
||||||
|
|
||||||
|
for (auto const& win : {"a", "b"}) {
|
||||||
|
if (!Tests::spawnKitty(win)) {
|
||||||
|
NLog::log("{}Failed to spawn kitty with win class `{}`", Colors::RED, win);
|
||||||
|
++TESTS_FAILED;
|
||||||
|
ret = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 960,1080");
|
||||||
|
}
|
||||||
|
|
||||||
|
// test 4 repeated rotations by 90 degrees
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 1920,540");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 960,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 960,1080");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,540");
|
||||||
|
EXPECT_CONTAINS(str, "size: 1920,540");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 960,1080");
|
||||||
|
}
|
||||||
|
|
||||||
|
// test different angles
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit 180"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 960,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 960,1080");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit 270"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,540");
|
||||||
|
EXPECT_CONTAINS(str, "size: 1920,540");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit 360"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 1920,540");
|
||||||
|
}
|
||||||
|
|
||||||
|
// test negative angles
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit -90"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 0,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 960,1080");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch layoutmsg rotatesplit -180"));
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 960,0");
|
||||||
|
EXPECT_CONTAINS(str, "size: 960,1080");
|
||||||
|
}
|
||||||
|
|
||||||
|
NLog::log("{}Killing all windows", Colors::YELLOW);
|
||||||
|
Tests::killAllWindows();
|
||||||
|
|
||||||
|
OK(getFromSocket("/reload"));
|
||||||
|
}
|
||||||
|
|
||||||
static bool test() {
|
static bool test() {
|
||||||
NLog::log("{}Testing Dwindle layout", Colors::GREEN);
|
NLog::log("{}Testing Dwindle layout", Colors::GREEN);
|
||||||
|
|
||||||
|
|
@ -148,6 +240,9 @@ static bool test() {
|
||||||
NLog::log("{}Testing splits", Colors::GREEN);
|
NLog::log("{}Testing splits", Colors::GREEN);
|
||||||
testSplit();
|
testSplit();
|
||||||
|
|
||||||
|
NLog::log("{}Testing rotatesplit", Colors::GREEN);
|
||||||
|
testRotatesplit();
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
NLog::log("Cleaning up", Colors::YELLOW);
|
NLog::log("Cleaning up", Colors::YELLOW);
|
||||||
getFromSocket("/dispatch workspace 1");
|
getFromSocket("/dispatch workspace 1");
|
||||||
|
|
|
||||||
|
|
@ -666,6 +666,19 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_
|
||||||
if (!swapSplit(CURRENT_NODE))
|
if (!swapSplit(CURRENT_NODE))
|
||||||
return std::unexpected("can't swapsplit in the current workspace");
|
return std::unexpected("can't swapsplit in the current workspace");
|
||||||
}
|
}
|
||||||
|
} else if (ARGS[0] == "rotatesplit") {
|
||||||
|
if (CURRENT_NODE) {
|
||||||
|
int angle = 90;
|
||||||
|
if (!ARGS[1].empty()) {
|
||||||
|
try {
|
||||||
|
angle = std::stoi(std::string{ARGS[1]});
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Log::logger->log(Log::WARN, "Invalid angle argument for rotatesplit: {}", ARGS[1]);
|
||||||
|
return std::unexpected("Invalid angle argument");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rotateSplit(CURRENT_NODE, angle);
|
||||||
|
}
|
||||||
} 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()) {
|
||||||
|
|
@ -760,6 +773,43 @@ bool CDwindleAlgorithm::swapSplit(SP<SDwindleNodeData> x) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDwindleAlgorithm::rotateSplit(SP<SDwindleNodeData> x, int angle) {
|
||||||
|
if (!x || !x->pParent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (x->pTarget->fullscreenMode() != FSMODE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// normalize the angle to multiples of 90 degrees
|
||||||
|
int normalizedAngle = ((sc<int>(angle / 90) % 4) + 4) % 4; // ensures positive modulo
|
||||||
|
|
||||||
|
auto pParent = x->pParent;
|
||||||
|
|
||||||
|
bool shouldSwap = false;
|
||||||
|
|
||||||
|
switch (normalizedAngle) {
|
||||||
|
case 0: // 0 degrees - no change
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (pParent->splitTop)
|
||||||
|
shouldSwap = true;
|
||||||
|
pParent->splitTop = !pParent->splitTop;
|
||||||
|
break;
|
||||||
|
case 2: shouldSwap = true; break;
|
||||||
|
case 3:
|
||||||
|
if (!pParent->splitTop)
|
||||||
|
shouldSwap = true;
|
||||||
|
pParent->splitTop = !pParent->splitTop;
|
||||||
|
break;
|
||||||
|
default: break; // should never happen
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSwap)
|
||||||
|
std::swap(pParent->children[0], pParent->children[1]);
|
||||||
|
|
||||||
|
pParent->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
bool CDwindleAlgorithm::moveToRoot(SP<SDwindleNodeData> x, bool stable) {
|
bool CDwindleAlgorithm::moveToRoot(SP<SDwindleNodeData> x, bool stable) {
|
||||||
if (!x || !x->pParent)
|
if (!x || !x->pParent)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ namespace Layout::Tiled {
|
||||||
|
|
||||||
bool toggleSplit(SP<SDwindleNodeData>);
|
bool toggleSplit(SP<SDwindleNodeData>);
|
||||||
bool swapSplit(SP<SDwindleNodeData>);
|
bool swapSplit(SP<SDwindleNodeData>);
|
||||||
|
void rotateSplit(SP<SDwindleNodeData>, int angle = 90);
|
||||||
bool 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