diff options
| author | Mike Will <myQwil@gmail.com> | 2025-07-15 16:24:40 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-15 22:24:40 +0200 |
| commit | 8453fbf4eb0af2e3265fd34a693b7d0e9167f4d2 (patch) | |
| tree | 06f0f728453228226388f1cad124f306a538c60a /hyprtester/src/tests/main/snap.cpp | |
| parent | e15014e031589e1df2dc29a5ce94325676796ac4 (diff) | |
snap: fix `border_overlap` option for monitor snapping (#10987)
Diffstat (limited to 'hyprtester/src/tests/main/snap.cpp')
| -rw-r--r-- | hyprtester/src/tests/main/snap.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/hyprtester/src/tests/main/snap.cpp b/hyprtester/src/tests/main/snap.cpp new file mode 100644 index 00000000..c7c2b256 --- /dev/null +++ b/hyprtester/src/tests/main/snap.cpp @@ -0,0 +1,174 @@ +#include <hyprutils/math/Vector2D.hpp> +#include <hyprutils/memory/WeakPtr.hpp> +#include <hyprutils/os/Process.hpp> + +#include "../../shared.hpp" +#include "../../hyprctlCompat.hpp" +#include "../shared.hpp" +#include "tests.hpp" + +using Hyprutils::Math::Vector2D; + +static int ret = 0; + +static bool spawnFloatingKitty() { + if (!Tests::spawnKitty()) { + NLog::log("{}Error: kitty did not spawn", Colors::RED); + return false; + } + OK(getFromSocket("/dispatch setfloating active")); + OK(getFromSocket("/dispatch resizeactive exact 100 100")); + return true; +} + +static void expectSocket(const std::string& CMD) { + if (const auto RESULT = getFromSocket(CMD); RESULT != "ok") { + NLog::log("{}Failed: {}getFromSocket({}), expected ok, got {}. Source: {}@{}.", Colors::RED, Colors::RESET, CMD, RESULT, __FILE__, __LINE__); + ret = 1; + TESTS_FAILED++; + } else { + NLog::log("{}Passed: {}getFromSocket({}). Got ok", Colors::GREEN, Colors::RESET, CMD); + TESTS_PASSED++; + } +} + +static void expectSnapMove(const Vector2D FROM, const Vector2D* TO) { + const Vector2D& A = FROM; + const Vector2D& B = TO ? *TO : FROM; + if (TO) + NLog::log("{}Expecting snap to ({},{}) when window is moved to ({},{})", Colors::YELLOW, B.x, B.y, A.x, A.y); + else + NLog::log("{}Expecting no snap when window is moved to ({},{})", Colors::YELLOW, A.x, A.y); + + expectSocket(std::format("/dispatch moveactive exact {} {}", A.x, A.y)); + expectSocket("/dispatch plugin:test:snapmove"); + EXPECT_CONTAINS(getFromSocket("/activewindow"), std::format("at: {},{}", B.x, B.y)); +} + +static void testSnap(const bool OVERLAP, const bool RESPECT) { + const double BORDERSIZE = 2; + const double WINDOWSIZE = 100; + + // test window snapping + { + const double OTHER = 500; + const double WINDOWGAP = 8; + const double GAPSIN = 5; + const double GAP = (RESPECT ? GAPSIN : 0) + BORDERSIZE + (OVERLAP ? 0 : BORDERSIZE); + const double END = GAP + WINDOWSIZE; + + double x; + Vector2D predict; + + x = WINDOWGAP + END; + expectSnapMove({OTHER + x, OTHER}, nullptr); + expectSnapMove({OTHER - x, OTHER}, nullptr); + expectSnapMove({OTHER, OTHER + x}, nullptr); + expectSnapMove({OTHER, OTHER - x}, nullptr); + x -= 1; + expectSnapMove({OTHER + x, OTHER}, &(predict = {OTHER + END, OTHER})); + expectSnapMove({OTHER - x, OTHER}, &(predict = {OTHER - END, OTHER})); + expectSnapMove({OTHER, OTHER + x}, &(predict = {OTHER, OTHER + END})); + expectSnapMove({OTHER, OTHER - x}, &(predict = {OTHER, OTHER - END})); + } + + // test monitor snapping + { + const double MONITORGAP = 10; + const double GAPSOUT = 20; + const double RESP = (RESPECT ? GAPSOUT : 0); + const double GAP = RESP + (OVERLAP ? 0 : BORDERSIZE); + const double END = GAP + WINDOWSIZE; + + double x; + Vector2D predict; + + x = MONITORGAP + GAP; + expectSnapMove({x, x}, nullptr); + x -= 1; + expectSnapMove({x, x}, &(predict = {GAP, GAP})); + + x = MONITORGAP + END; + expectSnapMove({1920 - x, 1080 - x}, nullptr); + x -= 1; + expectSnapMove({1920 - x, 1080 - x}, &(predict = {1920 - END, 1080 - END})); + + // test reserved area + const double RESERVED = 200; + const double RGAP = RESERVED + RESP + BORDERSIZE; + const double REND = RGAP + WINDOWSIZE; + + x = MONITORGAP + RGAP; + expectSnapMove({x, x}, nullptr); + x -= 1; + expectSnapMove({x, x}, &(predict = {RGAP, RGAP})); + + x = MONITORGAP + REND; + expectSnapMove({1920 - x, 1080 - x}, nullptr); + x -= 1; + expectSnapMove({1920 - x, 1080 - x}, &(predict = {1920 - REND, 1080 - REND})); + } +} + +static bool test() { + NLog::log("{}Testing snap", Colors::GREEN); + + // move to monitor HEADLESS-2 + NLog::log("{}Moving to monitor HEADLESS-2", Colors::YELLOW); + OK(getFromSocket("/dispatch focusmonitor HEADLESS-2")); + NLog::log("{}Adding reserved monitor area to HEADLESS-2", Colors::YELLOW); + OK(getFromSocket("/keyword monitor HEADLESS-2,addreserved,200,200,200,200")); + + // test on workspace "snap" + NLog::log("{}Dispatching workspace `snap`", Colors::YELLOW); + OK(getFromSocket("/dispatch workspace name:snap")); + + // spawn a kitty terminal and move to (500,500) + NLog::log("{}Spawning kittyProcA", Colors::YELLOW); + if (!spawnFloatingKitty()) + return false; + + NLog::log("{}Expecting 1 window", Colors::YELLOW); + EXPECT(Tests::windowCount(), 1); + + NLog::log("{}Move the kitty window to (500,500)", Colors::YELLOW); + OK(getFromSocket("/dispatch moveactive exact 500 500")); + + // spawn a second kitty terminal + NLog::log("{}Spawning kittyProcB", Colors::YELLOW); + if (!spawnFloatingKitty()) + return false; + + NLog::log("{}Expecting 2 windows", Colors::YELLOW); + EXPECT(Tests::windowCount(), 2); + + NLog::log(""); + testSnap(false, false); + + NLog::log("\n{}Turning on border_overlap", Colors::YELLOW); + OK(getFromSocket("/keyword general:snap:border_overlap true")); + testSnap(true, false); + + NLog::log("\n{}Turning on respect_gaps", Colors::YELLOW); + OK(getFromSocket("/keyword general:snap:border_overlap false")); + OK(getFromSocket("/keyword general:snap:respect_gaps true")); + testSnap(false, true); + + NLog::log("\n{}Turning on both border_overlap and respect_gaps", Colors::YELLOW); + OK(getFromSocket("/keyword general:snap:border_overlap true")); + testSnap(true, true); + + // kill all + NLog::log("\n{}Killing all windows", Colors::YELLOW); + Tests::killAllWindows(); + + NLog::log("{}Expecting 0 windows", Colors::YELLOW); + EXPECT(Tests::windowCount(), 0); + + NLog::log("{}Reloading the config", Colors::YELLOW); + OK(getFromSocket("/reload")); + + return !ret; +} + +REGISTER_TEST_FN(test) |
