Skip to content

Commit d3a16ec

Browse files
committed
dwindle: Respect force_split when moving windows to workspaces
Respect `dwindle:force_split` not only when mapping new windows, but also when moving windows to workspaces. Fixes #13009.
1 parent eb0480b commit d3a16ec

File tree

5 files changed

+48
-25
lines changed

5 files changed

+48
-25
lines changed

hyprtester/src/tests/main/dwindle.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,38 @@ static void testFloatClamp() {
3636
Tests::killAllWindows();
3737
}
3838

39+
static void testForceSplitOnMoveToWorkspace() {
40+
OK(getFromSocket("/dispatch workspace 2"));
41+
EXPECT(!!Tests::spawnKitty("kitty"), true);
42+
43+
OK(getFromSocket("/dispatch workspace 1"));
44+
EXPECT(!!Tests::spawnKitty("kitty"), true);
45+
std::string posBefore = Tests::getWindowAttribute(getFromSocket("/activewindow"), "at:");
46+
47+
OK(getFromSocket("/keyword dwindle:force_split 2"));
48+
OK(getFromSocket("/dispatch movecursortocorner 3")); // top left
49+
OK(getFromSocket("/dispatch movetoworkspace 2"));
50+
51+
// Should be moved to the right, so the position should change
52+
std::string activeWindow = getFromSocket("/activewindow");
53+
EXPECT(activeWindow.contains(posBefore), false);
54+
55+
// clean up
56+
OK(getFromSocket("/reload"));
57+
Tests::killAllWindows();
58+
Tests::waitUntilWindowsN(0);
59+
}
60+
3961
static bool test() {
4062
NLog::log("{}Testing Dwindle layout", Colors::GREEN);
4163

4264
// test
4365
NLog::log("{}Testing float clamp", Colors::GREEN);
4466
testFloatClamp();
4567

68+
NLog::log("{}Testing force_split on move to workspace", Colors::GREEN);
69+
testForceSplitOnMoveToWorkspace();
70+
4671
// clean up
4772
NLog::log("Cleaning up", Colors::YELLOW);
4873
getFromSocket("/dispatch workspace 1");

hyprtester/src/tests/main/window.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,6 @@ static std::string spawnKittyActivating(const std::string& class_ = "kitty_activ
4747
return tmpFilename;
4848
}
4949

50-
static std::string getWindowAttribute(const std::string& winInfo, const std::string& attr) {
51-
auto pos = winInfo.find(attr);
52-
if (pos == std::string::npos) {
53-
NLog::log("{}Wrong window attribute", Colors::RED);
54-
ret = 1;
55-
return "Wrong window attribute";
56-
}
57-
auto pos2 = winInfo.find('\n', pos);
58-
return winInfo.substr(pos, pos2 - pos);
59-
}
60-
6150
static std::string getWindowAddress(const std::string& winInfo) {
6251
auto pos = winInfo.find("Window ");
6352
auto pos2 = winInfo.find(" -> ");
@@ -92,7 +81,7 @@ static void testSwapWindow() {
9281
// Test swapwindow by direction
9382
{
9483
getFromSocket("/dispatch focuswindow class:kitty_A");
95-
auto pos = getWindowAttribute(getFromSocket("/activewindow"), "at:");
84+
auto pos = Tests::getWindowAttribute(getFromSocket("/activewindow"), "at:");
9685
NLog::log("{}Testing kitty_A {}, swapwindow with direction 'l'", Colors::YELLOW, pos);
9786

9887
OK(getFromSocket("/dispatch swapwindow l"));
@@ -104,7 +93,7 @@ static void testSwapWindow() {
10493
// Test swapwindow by class
10594
{
10695
getFromSocket("/dispatch focuswindow class:kitty_A");
107-
auto pos = getWindowAttribute(getFromSocket("/activewindow"), "at:");
96+
auto pos = Tests::getWindowAttribute(getFromSocket("/activewindow"), "at:");
10897
NLog::log("{}Testing kitty_A {}, swapwindow with class:kitty_B", Colors::YELLOW, pos);
10998

11099
OK(getFromSocket("/dispatch swapwindow class:kitty_B"));
@@ -118,7 +107,7 @@ static void testSwapWindow() {
118107
getFromSocket("/dispatch focuswindow class:kitty_B");
119108
auto addr = getWindowAddress(getFromSocket("/activewindow"));
120109
getFromSocket("/dispatch focuswindow class:kitty_A");
121-
auto pos = getWindowAttribute(getFromSocket("/activewindow"), "at:");
110+
auto pos = Tests::getWindowAttribute(getFromSocket("/activewindow"), "at:");
122111
NLog::log("{}Testing kitty_A {}, swapwindow with address:0x{}(kitty_B)", Colors::YELLOW, pos, addr);
123112

124113
OK(getFromSocket(std::format("/dispatch swapwindow address:0x{}", addr)));
@@ -141,7 +130,7 @@ static void testSwapWindow() {
141130
{
142131
getFromSocket("/dispatch focuswindow class:kitty_B");
143132
auto addr = getWindowAddress(getFromSocket("/activewindow"));
144-
auto ws = getWindowAttribute(getFromSocket("/activewindow"), "workspace:");
133+
auto ws = Tests::getWindowAttribute(getFromSocket("/activewindow"), "workspace:");
145134
NLog::log("{}Sending address:0x{}(kitty_B) to workspace \"swapwindow2\"", Colors::YELLOW, addr);
146135

147136
OK(getFromSocket("/dispatch movetoworkspacesilent name:swapwindow2"));
@@ -222,8 +211,8 @@ static void testGroupRules() {
222211

223212
static bool isActiveWindow(const std::string& class_, char fullscreen = '0', bool log = true) {
224213
std::string activeWin = getFromSocket("/activewindow");
225-
auto winClass = getWindowAttribute(activeWin, "class:");
226-
auto winFullscreen = getWindowAttribute(activeWin, "fullscreen:").back();
214+
auto winClass = Tests::getWindowAttribute(activeWin, "class:");
215+
auto winFullscreen = Tests::getWindowAttribute(activeWin, "fullscreen:").back();
227216
if (winClass.substr(strlen("class: ")) == class_ && winFullscreen == fullscreen)
228217
return true;
229218
else {

hyprtester/src/tests/shared.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,13 @@ std::string Tests::execAndGet(const std::string& cmd) {
105105

106106
return proc.stdOut();
107107
}
108+
109+
std::string Tests::getWindowAttribute(const std::string& winInfo, const std::string& attr) {
110+
auto pos = winInfo.find(attr);
111+
if (pos == std::string::npos) {
112+
NLog::log("{}Window attribute not found: '{}'", Colors::RED, attr);
113+
return "Wrong window attribute";
114+
}
115+
auto pos2 = winInfo.find('\n', pos);
116+
return winInfo.substr(pos, pos2 - pos);
117+
}

hyprtester/src/tests/shared.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ namespace Tests {
1515
bool killAllWindows();
1616
void waitUntilWindowsN(int n);
1717
std::string execAndGet(const std::string& cmd);
18+
std::string getWindowAttribute(const std::string& winInfo, const std::string& attr);
1819
};

src/layout/DwindleLayout.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
428428
NEWPARENT->children[1] = OPENINGON;
429429
}
430430
}
431-
} else if (*PFORCESPLIT == 0 || !pWindow->m_firstMap) {
431+
} else if (*PFORCESPLIT == 0) {
432432
if ((SIDEBYSIDE &&
433433
VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / *PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w / 2.f, NEWPARENT->box.y + NEWPARENT->box.h)) ||
434434
(!SIDEBYSIDE &&
@@ -441,14 +441,12 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
441441
NEWPARENT->children[0] = OPENINGON;
442442
NEWPARENT->children[1] = PNODE;
443443
}
444+
} else if (*PFORCESPLIT == 1) {
445+
NEWPARENT->children[1] = OPENINGON;
446+
NEWPARENT->children[0] = PNODE;
444447
} else {
445-
if (*PFORCESPLIT == 1) {
446-
NEWPARENT->children[1] = OPENINGON;
447-
NEWPARENT->children[0] = PNODE;
448-
} else {
449-
NEWPARENT->children[0] = OPENINGON;
450-
NEWPARENT->children[1] = PNODE;
451-
}
448+
NEWPARENT->children[0] = OPENINGON;
449+
NEWPARENT->children[1] = PNODE;
452450
}
453451

454452
// split in favor of a specific window

0 commit comments

Comments
 (0)