Skip to content

Feat/editor background tool - #23

Merged
aryasadeghy merged 4 commits into
mainfrom
feat/editor-background-tool
May 10, 2026
Merged

Feat/editor background tool#23
aryasadeghy merged 4 commits into
mainfrom
feat/editor-background-tool

Conversation

@aryasadeghy

Copy link
Copy Markdown
Contributor

Summary

Type

  • feat — new feature
  • fix — bug fix
  • docs — documentation only
  • refactor — code restructure, no behavior change
  • perf — performance improvement
  • test — adds or changes tests
  • chore / ci / build — tooling

Screenshots / recording

Test plan

  • npm run lint
  • npm run typecheck
  • npm test
  • Manual smoke: launched the app, exercised the changed feature
  • Manual smoke: nothing else regressed

Clean-room confirmation

  • I confirm this contribution is not derived from decompiled or leaked commercial software (see CONTRIBUTING.md).

Linked issues

Closes #

aryasadeghy and others added 4 commits May 10, 2026 11:42
…file open

Substantial expansion of the Background tool to catch up to CleanShot's
sidebar, plus two missing entry points:

Entry-point fixes:
- HUD card now has a visible "Edit" pill button next to Copy / Save (was
  only a tiny wand corner-button on hover).
- Empty editor has an "Open file…" button so users can edit any image
  on disk without re-capturing — backed by new `editor:open-file` IPC.

Editor sidebar additions:
- 10 gradient presets in a 5×2 swatch grid (CSS gradient strings — no
  asset bundling).
- Plain color: still 8 swatches + custom hex.
- Shadow slider (0–80 DIPs).
- Corners slider (0–48 DIPs) — adds a rounded clip on top of the image's
  natural alpha shape.
- Alignment 3×3 grid — slides the screenshot toward an edge by doubling
  padding on the opposite side, so it works without an aspect-ratio
  selector.

Compositor (`src/main/capture/compositor.ts`):
- New `gradient` background type (uses `value` as raw CSS).
- `shadowPx`, `cornersPx`, `alignment` params with sensible defaults.
- `paddingForAlignment()` helper splits the base padding into
  asymmetric `top/right/bottom/left` so alignment actually shifts the
  image. Also wired into the renderer for live preview parity.
- HTML now wraps the image in a `.clip` div when `cornersPx > 0`, so
  rounded corners apply correctly to area screenshots (which lack
  natural rounding).

Still scoped out, will land in a follow-up PR:
- Bundled wallpaper presets (need asset packaging in resources/)
- Blurred presets (different mechanism — backdrop-filter)
- Inset slider (ambiguous semantics in CleanShot)
- Aspect ratio selector + Auto-balance (needs canvas-crop pipeline)
- "Save as…" file picker
- Annotation tools (Konva — v0.3 milestone)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…creen

`screencapture -R x,y,w,h` requires integer pixel values. The selection
overlay produces fractional CSS-pixel coords (e.g. 806.2109375), which
on macOS 14+ makes screencapture silently fall back to a fullscreen
capture instead of the intended region. Fix: round x/y/w/h before
formatting the -R argument.

Side change: extracted `buildArgs` into a separate pure-Node module
(`screenshotArgs.ts`) so it's importable from vitest without dragging
in `electron`. Adds 7 regression tests covering the integer-coords
behavior + the existing arg-building branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Electron's default `window-all-closed` behavior quits the app — even on
macOS — when the last BrowserWindow goes away. `LSUIElement: true` only
applies to packaged builds, so in `npm run dev` (and likely in any code
path that spawns Electron without the packaged Info.plist) the app would
silently quit between captures.

Reproduction (before this fix):

  1. Fresh `npm run dev`.
  2. First action: take an area capture (Cmd+Shift+2).
  3. Selection overlay creates BrowserWindows; user commits the rect;
     overlays `close()`.
  4. `window-all-closed` fires → default → `app.quit()` → exit code 0.
  5. The pending screencapture promise dies with the process; main.log
     ends at "spawning screencapture" with no follow-up.

The window-mode flow happened to work because screencapture's UI is a
separate process — Snapora itself never opened or closed a window, so
the event never fired. Doing window-then-area also worked because the
HUD window stays in the BrowserWindow registry (it `hide()`s, not
`close()`s) and keeps the count positive.

Fix: subscribe to `window-all-closed` and refuse to quit on macOS.
Snapora is a menu-bar app — the tray keeps it running. The packaged
build's `LSUIElement` was already doing this for production users; this
hooks it for the dev build (and as a belt-and-suspenders production
guard).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@aryasadeghy
aryasadeghy enabled auto-merge (squash) May 10, 2026 10:01
@aryasadeghy
aryasadeghy merged commit 5edeccc into main May 10, 2026
3 checks passed
@aryasadeghy
aryasadeghy deleted the feat/editor-background-tool branch May 10, 2026 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant