Skip to content

Instantly share code, notes, and snippets.

@kuuote
Created December 9, 2023 10:50
Show Gist options
  • Save kuuote/688977d6bbb4a5f8e97f7802f6f31620 to your computer and use it in GitHub Desktop.
Save kuuote/688977d6bbb4a5f8e97f7802f6f31620 to your computer and use it in GitHub Desktop.
Denoからslurpとswaymsg叩いてクリックしたウィンドウのサイズを取得するやつ
import * as u from "https://deno.land/x/[email protected]/mod.ts";
import { is } from "https://deno.land/x/[email protected]/mod.ts";
type Point = {
x: number;
y: number;
};
type Rect = Point & {
width: number;
height: number;
};
const isRect: u.Predicate<Rect> = is.ObjectOf({
x: is.Number,
y: is.Number,
width: is.Number,
height: is.Number,
});
function isInside(rect: Rect, point: Point) {
// ポイントが矩形内にあるかどうかを判定
// https://chat.openai.com/share/8b910f79-b5ca-468f-b4f3-d4aab8f145c1
return (
point.x >= rect.x &&
point.x <= rect.x + rect.width &&
point.y >= rect.y &&
point.y <= rect.y + rect.height
);
}
function* query<T>(
root: unknown,
finder: (obj: unknown) => obj is T,
): Generator<T> {
const queue = [root];
for (let i = 0; i < queue.length; i++) {
const obj = queue[i];
if (finder(obj)) {
yield obj;
}
if (is.Array(obj)) {
queue.push(...obj);
} else if (is.Record(obj)) {
queue.push(Object.values(obj));
}
}
}
export async function exec(cmd: string[], cwd?: string): Promise<string> {
if (cwd == null) {
cwd = Deno.cwd();
}
const proc = new Deno.Command(cmd[0], {
args: cmd.slice(1),
cwd,
});
const { stdout } = await proc.output();
return new TextDecoder().decode(stdout).trimEnd();
}
const slurp = await exec(["slurp", "-p"]);
const match = slurp.match(/(\d+),(\d+)/);
if (match == null) {
Deno.exit(1);
}
const point = {
x: Number(match[1]),
y: Number(match[2]),
};
const tree = JSON.parse(
await exec(["swaymsg", "-t", "get_tree"]),
);
const windows = query(
tree,
is.ObjectOf({
rect: isRect,
visible: is.LiteralOf(true),
window_rect: isRect,
}),
);
const target = [...windows].reverse().filter((w) => isInside(w.rect, point))[0];
if (target == null) {
Deno.exit(1);
}
const r = target.rect;
if (Deno.args.indexOf("-w") == -1) {
const wr = target.window_rect;
console.log(`${r.x + wr.x},${r.y + wr.y} ${wr.width}x${wr.height}`);
} else {
console.log(`${r.x},${r.y} ${r.width}x${r.height}`);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment