Created
December 9, 2023 10:50
-
-
Save kuuote/688977d6bbb4a5f8e97f7802f6f31620 to your computer and use it in GitHub Desktop.
Denoからslurpとswaymsg叩いてクリックしたウィンドウのサイズを取得するやつ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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