Files
KevinandClaude Opus 5.5 f91d1a1288 Pick a window, a screen or an area on screen
"Select area or window" in the source menu opens a picker over every
display. Hovering highlights the window under the cursor, or the whole
screen over the desktop, and a click picks it. Dragging draws an area,
and moving or resizing any pick turns it into an area. Record, Enter or
a double-click starts recording, Select only picks, Escape cancels.

The window-list helper gains a --z-order mode that lists windows front
to back with their owner process, so the picker hits the frontmost
window and skips Recordly's own. A picked window or screen becomes the
same source the lists offer. An area becomes an area:<displayId> source
that the capture helper crops like a window that never moves, cursor
telemetry normalizes to, and a dashed outline marks while recording.
The main process validates every pick: a window must be one the picker
offered. Picker windows stay hidden until they have painted, so opening
the picker does not flash the app background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 11:14:23 -07:00

149 lines
3.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import {
createAreaSource,
createWindowSource,
getSourceArea,
normalizeCapturePick,
} from "./sourceArea";
const displays = [
{ id: 1, bounds: { x: 0, y: 0, width: 1728, height: 1117 } },
{ id: 2, bounds: { x: 1728, y: -200, width: 2560, height: 1440 } },
];
const windows = [
{
id: "window:42:0",
appName: "Safari",
title: "Docs",
display_id: "1",
x: 10,
y: 40,
width: 1200,
height: 800,
},
];
describe("normalizeCapturePick", () => {
it("keeps an area that lies on its display", () => {
expect(
normalizeCapturePick(
{
kind: "area",
x: 100.4,
y: 50,
width: 1280,
height: 720,
displayId: 1,
record: true,
},
displays,
windows,
),
).toEqual({
kind: "area",
x: 100,
y: 50,
width: 1280,
height: 720,
displayId: 1,
record: true,
});
});
it("clips an area to its display, including displays left of or above the origin", () => {
expect(
normalizeCapturePick(
{ kind: "area", x: 1700, y: -300, width: 400, height: 400, displayId: 2 },
displays,
windows,
),
).toEqual({
kind: "area",
x: 1728,
y: -200,
width: 372,
height: 300,
displayId: 2,
record: false,
});
});
it("trims an area to an even size so it maps onto whole screen pixels", () => {
expect(
normalizeCapturePick(
{ kind: "area", x: 10, y: 20, width: 401, height: 301, displayId: 1 },
displays,
windows,
),
).toMatchObject({ x: 10, y: 20, width: 400, height: 300 });
});
it("rejects areas that are too small, unknown displays and malformed input", () => {
const area = { kind: "area", x: 0, y: 0, width: 20, height: 400, displayId: 1 };
expect(normalizeCapturePick(area, displays, windows)).toBeNull();
expect(
normalizeCapturePick({ ...area, width: 400, displayId: 9 }, displays, windows),
).toBeNull();
expect(normalizeCapturePick({ ...area, width: "400" }, displays, windows)).toBeNull();
expect(normalizeCapturePick({ ...area, kind: "region" }, displays, windows)).toBeNull();
expect(normalizeCapturePick(null, displays, windows)).toBeNull();
});
it("accepts only windows the picker offered", () => {
expect(
normalizeCapturePick(
{ kind: "window", windowId: "window:42:0", displayId: 1, record: true },
displays,
windows,
),
).toEqual({ kind: "window", windowId: "window:42:0", displayId: 1, record: true });
expect(
normalizeCapturePick(
{ kind: "window", windowId: "window:7:0", displayId: 1 },
displays,
windows,
),
).toBeNull();
});
it("accepts a connected screen", () => {
expect(normalizeCapturePick({ kind: "screen", displayId: 2 }, displays, windows)).toEqual({
kind: "screen",
displayId: 2,
record: false,
});
});
});
describe("picked sources", () => {
it("round-trips an area's rectangle", () => {
const source = createAreaSource({
kind: "area",
x: 10,
y: 20,
width: 640,
height: 480,
displayId: 1,
record: false,
});
expect(source).toMatchObject({ id: "area:1", name: "Area 640×480", display_id: "1" });
expect(getSourceArea(source)).toEqual({ x: 10, y: 20, width: 640, height: 480 });
});
it("builds the same window source the window list offers", () => {
expect(createWindowSource(windows[0])).toEqual({
id: "window:42:0",
name: "Docs",
display_id: "1",
sourceType: "window",
appName: "Safari",
windowTitle: "Docs",
});
});
it("ignores sources that are not areas", () => {
expect(getSourceArea({ id: "screen:1:0", name: "Screen" })).toBeNull();
expect(getSourceArea(null)).toBeNull();
});
});