95 lines
4.6 KiB
QML
95 lines
4.6 KiB
QML
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
|
|
import "services/DisplayLayout.js" as DisplayLayout
|
|
|
|
ShellRoot {
|
|
readonly property var fixture: [
|
|
{ name: "DP-2", width: 4500, height: 3000, scale: 1.5, transform: 0, x: 140, y: 80, primary: true },
|
|
{ name: "HDMI-A-1", width: 2560, height: 1440, scale: 1, transform: 1, x: 3140, y: 80, primary: false }
|
|
]
|
|
|
|
// The same two displays, with the second mirroring the first. A mirrored
|
|
// display has no position of its own: the compositor puts it on top of its
|
|
// target, so its stored coordinates are stale the moment mirroring is on.
|
|
readonly property var mirrored: [
|
|
{ name: "DP-2", width: 4500, height: 3000, scale: 1.5, transform: 0, x: 140, y: 80, primary: true, mirrorOf: "" },
|
|
{ name: "HDMI-A-1", width: 2560, height: 1440, scale: 1, transform: 0, x: 3140, y: 80, primary: false, mirrorOf: "DP-2" }
|
|
]
|
|
|
|
IpcHandler {
|
|
target: "display-layout-test"
|
|
|
|
function mirror(): string {
|
|
const normalized = DisplayLayout.normalize(mirrored);
|
|
const canvas = DisplayLayout.canvasRects(normalized, 800, 500, 20);
|
|
return JSON.stringify({
|
|
valid: DisplayLayout.validate(mirrored),
|
|
normalized: normalized.map(record => ({
|
|
name: record.name, x: record.x, y: record.y,
|
|
primary: record.primary, mirrorOf: record.mirrorOf ?? ""
|
|
})),
|
|
bounds: canvas.bounds,
|
|
rects: canvas.rects
|
|
});
|
|
}
|
|
|
|
function invalidMirrors(): string {
|
|
const base = mirrored.map(record => Object.assign({}, record));
|
|
const cases = [];
|
|
const add = layout => cases.push(DisplayLayout.validate(layout));
|
|
// Mirroring itself.
|
|
add([base[0], Object.assign({}, base[1], { mirrorOf: "HDMI-A-1" })]);
|
|
// Mirroring an output that is not in the layout.
|
|
add([base[0], Object.assign({}, base[1], { mirrorOf: "NOPE-1" })]);
|
|
// The primary may not mirror: the desktop is anchored on it.
|
|
add([Object.assign({}, base[0], { mirrorOf: "HDMI-A-1" }), base[1]]);
|
|
// No chains. Hyprland resolves a mirror to one target, and a chain
|
|
// is a question nobody can answer from the canvas.
|
|
add([
|
|
base[0],
|
|
Object.assign({}, base[1], { mirrorOf: "DP-3" }),
|
|
{ name: "DP-3", width: 1920, height: 1080, scale: 1, transform: 0, x: 6000, y: 0, primary: false, mirrorOf: "DP-2" }
|
|
]);
|
|
// Not a name at all.
|
|
add([base[0], Object.assign({}, base[1], { mirrorOf: 5 })]);
|
|
return JSON.stringify(cases);
|
|
}
|
|
|
|
function status(): string {
|
|
const normalized = DisplayLayout.normalize(fixture);
|
|
const canvas = DisplayLayout.canvasRects(normalized, 800, 500, 20);
|
|
const near = normalized.map(record => Object.assign({}, record));
|
|
near[1].x = 3016;
|
|
const far = normalized.map(record => Object.assign({}, record));
|
|
far[1].x = 3017;
|
|
return JSON.stringify({
|
|
valid: DisplayLayout.validate(fixture),
|
|
sizes: fixture.map(DisplayLayout.logicalSize),
|
|
normalized: normalized.map(record => ({ name: record.name, x: record.x, y: record.y, primary: record.primary })),
|
|
bounds: canvas.bounds,
|
|
canvasScale: canvas.scale,
|
|
canvasRects: canvas.rects,
|
|
near: DisplayLayout.snap(near, "HDMI-A-1", 16).find(record => record.name === "HDMI-A-1").x,
|
|
far: DisplayLayout.snap(far, "HDMI-A-1", 16).find(record => record.name === "HDMI-A-1").x
|
|
});
|
|
}
|
|
|
|
function invalid(): string {
|
|
const base = fixture.map(record => Object.assign({}, record));
|
|
const cases = [];
|
|
const add = layout => cases.push(DisplayLayout.validate(layout));
|
|
add([base[0], Object.assign({}, base[1], { name: "DP-2" })]);
|
|
add(base.map(record => Object.assign({}, record, { primary: false })));
|
|
add(base.map(record => Object.assign({}, record, { primary: true })));
|
|
add([Object.assign({}, base[0], { x: 0.5 }), base[1]]);
|
|
add([Object.assign({}, base[0], { scale: 0 }), base[1]]);
|
|
add([Object.assign({}, base[0], { transform: 4 }), base[1]]);
|
|
add([Object.assign({}, base[0], { width: Infinity }), base[1]]);
|
|
add([Object.assign({}, base[0], { width: 0 }), base[1]]);
|
|
return JSON.stringify(cases);
|
|
}
|
|
}
|
|
}
|