Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 54 additions & 22 deletions apps/desktop/src/routes/capture-area.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,27 @@ export default function CaptureArea() {

const { rawOptions, setOptions } = createOptionsQuery();

const activeScreenId = createMemo(() => {
const target = rawOptions.captureTarget;
if (target.variant === "display") return target.id;
if (target.variant === "area") return target.screen;
return null;
});

const screenId = activeScreenId;

const hasStoredSelection = createMemo(() => {
const id = screenId();
if (!id) return false;

if (state.lastSelectedBounds?.some((entry) => entry.screenId === id))
return true;

const target = rawOptions.captureTarget;
if (target.variant !== "display") return false;
return (
state.lastSelectedBounds?.some((entry) => entry.screenId === target.id) ??
false
);
if (target.variant === "area" && target.screen === id) {
return target.bounds.size.width > 1 && target.bounds.size.height > 1;
}
return false;
});

async function handleConfirm() {
Expand All @@ -90,22 +104,22 @@ export default function CaptureArea() {
)
return;

const target = rawOptions.captureTarget;
if (target.variant !== "display") return;
const id = screenId();
if (!id) return;

const existingIndex = state.lastSelectedBounds?.findIndex(
(item) => item.screenId === target.id,
(item) => item.screenId === id,
);

if (existingIndex >= 0) {
setState("lastSelectedBounds", existingIndex, {
screenId: target.id,
screenId: id,
bounds: currentBounds,
});
} else {
setState("lastSelectedBounds", [
...state.lastSelectedBounds,
{ screenId: target.id, bounds: currentBounds },
{ screenId: id, bounds: currentBounds },
]);
}

Expand All @@ -114,7 +128,7 @@ export default function CaptureArea() {
"captureTarget",
reconcile({
variant: "area",
screen: target.id,
screen: id,
bounds: {
position: { x: b.x, y: b.y },
size: { width: b.width, height: b.height },
Expand Down Expand Up @@ -145,14 +159,20 @@ export default function CaptureArea() {
const [aspect, setAspect] = createSignal<Ratio | null>(null);

function reset() {
cropperRef?.reset();
setAspect(null);

const target = rawOptions.captureTarget;
if (target.variant !== "display") return;
const id = screenId();
if (!id) return;
setState("lastSelectedBounds", (values) =>
values?.filter((v) => v.screenId !== target.id),
values?.filter((v) => v.screenId !== id),
);

const target = rawOptions.captureTarget;
if (target.variant === "area" && target.screen === id) {
setOptions("captureTarget", reconcile({ variant: "display", id }));
}

cropperRef?.reset();
}

async function showCropOptionsMenu(e: UIEvent, positionAtCursor = false) {
Expand Down Expand Up @@ -287,14 +307,26 @@ export default function CaptureArea() {
onCropChange={setCrop}
snapToRatioEnabled={state.snapToRatio}
initialCrop={() => {
const id = screenId();
if (!id) return CROP_ZERO;

const target = rawOptions.captureTarget;
if (target.variant === "display")
return (
state.lastSelectedBounds?.find(
(m) => m.screenId === target.id,
)?.bounds ?? CROP_ZERO
);
return CROP_ZERO;
if (target.variant === "area" && target.screen === id) {
const { width, height } = target.bounds.size;
if (width > 1 && height > 1) {
return {
x: target.bounds.position.x,
y: target.bounds.position.y,
width,
height,
};
}
}

return (
state.lastSelectedBounds?.find((m) => m.screenId === id)
?.bounds ?? CROP_ZERO
);
}}
Comment thread
ManthanNimodiya marked this conversation as resolved.
onContextMenu={(e) => showCropOptionsMenu(e, true)}
/>
Expand Down
25 changes: 23 additions & 2 deletions apps/desktop/src/routes/target-select-overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,27 @@ function Inner() {
CropBounds | undefined
>(undefined);

const effectiveInitialBounds = createMemo<CropBounds | undefined>(() => {
const explicit = initialAreaBounds();
if (explicit !== undefined) return explicit;
const target = options.captureTarget;
if (
target.variant === "area" &&
params.displayId &&
target.screen === params.displayId
) {
const { width, height } = target.bounds.size;
if (width <= 1 || height <= 1) return undefined;
return {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If captureTarget.bounds can ever be a zero/placeholder crop, effectiveInitialBounds() becomes non-undefined and shouldShowSelectionHint won’t show. Might be worth treating <=1x1 as undefined here (matches the size check you added in capture-area.tsx).

Suggested change
return {
if (
target.variant === "area" &&
params.displayId &&
target.screen === params.displayId
) {
const { width, height } = target.bounds.size;
if (width <= 1 || height <= 1) return undefined;
return {
x: target.bounds.position.x,
y: target.bounds.position.y,
width,
height,
};
}

x: target.bounds.position.x,
y: target.bounds.position.y,
width,
height,
};
}
return undefined;
});

createEffect(() => {
const target = options.captureTarget;
if (
Expand Down Expand Up @@ -725,7 +746,7 @@ function Inner() {
() => isInteracting() || isActiveDisplay(),
);
const shouldShowSelectionHint = createMemo(() => {
if (initialAreaBounds() !== undefined) return false;
if (effectiveInitialBounds() !== undefined) return false;
if (!isActiveDisplay()) return false;
const bounds = crop();
return bounds.width <= 1 && bounds.height <= 1 && !isInteracting();
Expand Down Expand Up @@ -1146,7 +1167,7 @@ function Inner() {
ref={cropperRef}
onInteraction={setIsInteracting}
onCropChange={setCrop}
initialCrop={() => initialAreaBounds() ?? CROP_ZERO}
initialCrop={() => effectiveInitialBounds() ?? CROP_ZERO}
showBounds={isValid()}
aspectRatio={aspect() ?? undefined}
snapToRatioEnabled={snapToRatioEnabled()}
Expand Down
Loading