aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/monitors/test_mon.js
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-30 20:34:19 +0100
committerDanilo M. <danix@danix.xyz>2026-10-30 20:34:19 +0100
commitffe1a7ccdd51f760fa1e742c0d09cc229a405544 (patch)
tree40c7828f339139fd936ab2521e3eb396c12b21fc /desktop/modules/monitors/test_mon.js
parentca5b313ae55b393b993488e83e90eeadf6ada38c (diff)
downloadquickshell-ffe1a7ccdd51f760fa1e742c0d09cc229a405544.tar.gz
quickshell-ffe1a7ccdd51f760fa1e742c0d09cc229a405544.zip
monitors: pure helpers for the settings page
The Lua for a monitor and for monitors.lua, logical size, edge snapping and the mode list, with the duplicates the ASUS reports collapsed and the current mode matched by nearest refresh (99.943 against 99.94). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules/monitors/test_mon.js')
-rw-r--r--desktop/modules/monitors/test_mon.js70
1 files changed, 70 insertions, 0 deletions
diff --git a/desktop/modules/monitors/test_mon.js b/desktop/modules/monitors/test_mon.js
new file mode 100644
index 0000000..6b12ee7
--- /dev/null
+++ b/desktop/modules/monitors/test_mon.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Run: node desktop/modules/monitors/test_mon.js
+// Mon.js is a QML library, so its .pragma line is stripped before node
+// evaluates it.
+
+const fs = require("fs");
+const assert = require("assert");
+
+const src = fs.readFileSync(__dirname + "/Mon.js", "utf8").replace(/^\.pragma library$/m, "");
+const M = new Function(src + "\nreturn { modes, current, draft, size, xy, lua, file, snap, AUTO };")();
+
+// Duplicates collapse, order kept, the Hz suffix dropped.
+assert.deepStrictEqual(M.modes(["1920x1080@60.00Hz", "1920x1080@120.00Hz", "1920x1080@120.00Hz", "1280x720@60.00Hz"]),
+ ["1920x1080@60.00", "1920x1080@120.00", "1280x720@60.00"]);
+
+// The nearest refresh at the same size, not the first.
+const lg = ["2560x1080@59.98", "2560x1080@99.94", "2560x1080@74.99", "1920x1080@99.94"];
+assert.strictEqual(M.current(lg, 2560, 1080, 99.943), "2560x1080@99.94");
+// A mode the list lacks is written from the live numbers.
+assert.strictEqual(M.current(lg, 3440, 1440, 60), "3440x1440@60.00");
+
+// A hyprctl monitor as a draft.
+const asus = { name: "DP-3", make: "ASUS", model: "VG279Q3A", width: 1920, height: 1080, refreshRate: 100,
+ scale: 1, transform: 1, vrr: false, x: -1080, y: -960,
+ availableModes: ["1920x1080@100.00Hz", "1920x1080@60.00Hz"] };
+const d = M.draft(asus);
+assert.deepStrictEqual([d.mode, d.scale, d.transform, d.vrr, d.position, d.x, d.y],
+ ["1920x1080@100.00", "1", 1, false, "-1080x-960", -1080, -960]);
+
+// Logical size: an odd transform swaps, scale divides.
+assert.deepStrictEqual(M.size("1920x1080@100.00", "1", 1), { w: 1080, h: 1920 });
+assert.deepStrictEqual(M.size("2560x1440@60.00", "1.25", 0), { w: 2048, h: 1152 });
+
+// Exact positions parse, auto ones fall back to where Hyprland put it.
+assert.deepStrictEqual(M.xy({ position: "-1080x-960", x: 0, y: 0 }), { x: -1080, y: -960 });
+assert.deepStrictEqual(M.xy({ position: "auto-center-left", x: 5, y: 6 }), { x: 5, y: 6 });
+assert.ok(M.AUTO.includes("auto-center-right"));
+
+// One line per monitor; vrr only when on.
+assert.strictEqual(M.lua(d),
+ 'hl.monitor({ output = "DP-3", mode = "1920x1080@100.00", position = "-1080x-960", scale = "1", transform = 1 })');
+assert.ok(M.lua(Object.assign({}, d, { vrr: true })).endsWith("transform = 1, vrr = 1 })"));
+
+// The file: header, then a comment and a line per monitor.
+const f = M.file([d]);
+assert.ok(f.startsWith("-- Monitors, written by the keystone settings window"));
+assert.ok(f.includes("-- DP-3: ASUS VG279Q3A\n" + M.lua(d) + "\n"));
+
+// Snapping: DP-1 is 2560x1080 at 0,-540. A 1080x1920 monitor dropped with
+// its right edge 30px short of DP-1's left edge snaps flush; 200px short
+// does not.
+const dp1 = [{ x: 0, y: -540, w: 2560, h: 1080 }];
+assert.deepStrictEqual(M.snap({ x: -1110, y: -950, w: 1080, h: 1920 }, dp1, 64), { x: -1080, y: -950 });
+assert.deepStrictEqual(M.snap({ x: -1280, y: -950, w: 1080, h: 1920 }, dp1, 64), { x: -1280, y: -950 });
+// Tops align when close.
+assert.deepStrictEqual(M.snap({ x: -1080, y: -520, w: 1080, h: 1920 }, dp1, 64), { x: -1080, y: -540 });
+// Results are integers.
+assert.deepStrictEqual(M.snap({ x: -1280.6, y: 3000.4, w: 1080, h: 1920 }, dp1, 64), { x: -1281, y: 3000 });
+
+console.log("ok");