Skip to content

Repository files navigation

flip

hoijunkim.github.io/flip · Releases

release downloads platform license

Pick a region of your screen. flip captures it, sends the page-turn key to the window you chose, waits for the redraw to settle, and repeats - then hands you a folder of images or an assembled PDF.

flip

Windows only. Single executable, no runtime dependencies, no cgo.

Get flip

flip is one .exe. There is no installer.

  1. Download flip-v<version>-windows-amd64.zip from the releases page.
  2. Right-click the zip > Properties > Unblock, then extract flip.exe.
  3. Run it.

The build is not code-signed, so Windows SmartScreen warns on first run: More info > Run anyway. That is expected for an unsigned exe from a small project; verify the download against the published .sha256 if you want certainty.

Using it

Home > Target (pick the window to capture) > Region (drag a box over the page; a live heatmap shows what is changing so you can keep a blinking toolbar or caret outside it) > Settings (speed, format, spread splitting) > Preflight (one test capture, checked for capture protection and integrity) > Run (a five-second countdown to click the target, then flip shrinks to a small always-on-top widget and works through the pages) > Results (reorder, delete, and export to images or a PDF). Ctrl+Shift+F9 aborts a run at any time.

flip does not work around capture protection. A DRM reader (some ebook viewers) tells Windows not to let its window be captured, so it reads as solid black - flip detects that at preflight and stops. Use it on content that is yours to reproduce.

Status

In development. Plans 1 through 6 of 8 are merged, plus a design pass and this brand/distribution work in progress. The capture foundation (internal/capture), internal/detect's tile fingerprint and page-advance, settle and blank decision rules, internal/session's capture-loop state machine, Win32 input and window targeting (internal/input, internal/winfo, internal/hotkey), and post-processing and export (internal/postproc, internal/export, internal/exportpipe) - spread splitting, margin trim, aspect crop, resize, and JPEG/PNG/BMP/PDF output, driven end to end by flipdbg run and flipdbg export.

Plan 6 adds a Wails GUI over the same internal/exportpipe pipeline: seven screens (Home, Target, Region, Settings, Preflight, Run, Results) covering target/region selection, a live difference heatmap while dragging a region, the run itself, and a results screen with reorder, delete and export. Settings includes spread splitting - split mode, reading order and a cut offset - the same internal/postproc.Split flipdbg export -split already used, now reachable from the GUI rather than the CLI alone. internal/app/e2e_test.go drives the whole flow - region, config, a scripted document through the run goroutine, results, a reorder, a delete, and an export - in Go, with no screen and no Win32 target, and asserts the exported files and their order.

A later design pass reworked the frontend into flip's own instrument look (a calibration-teal-on-graphite token system, the platform's Segoe UI for chrome and a mono face for every measured number, a centred responsive layout, both OS themes) and added a compact capture widget: while actively capturing, flip shrinks to a small always-on-top readout parked off the region's monitor, so its own window is not read into the pages, and restores the moment interaction is needed. The logo is a dog-eared page, rendered onto the app icon by a pure-Go supersampling renderer in internal/brand.

What is verified, and what is not

go test ./... and the frontend's Vitest suite are green, including the end-to-end test above, and cover every stage's own logic plus that one composed flow. What they do not cover:

  • No frame from a real document viewer has been through the detector or the capture loop. Plan 4 named four manual gates - the physical-pixel coordinate identity through a real region drag, a real capture-target selection, a full document run against a real viewer, and the settle detector's behaviour against a real redraw - and they are still open. Plan 6 makes them easier to run (a GUI to click through, instead of the CLI alone); it does not close them.
  • The heatmap countermeasure - the region selector's live difference overlay - is unverified. It responds to a measured problem (a small toolbar repaint reads as statistically indistinguishable from a real content change of the same size), but whether showing a user what blinks actually lets them avoid it is something only real use will say.
  • maxTile may be doing nothing. One real-pixel reading (Plan 4) found it far above its own idle threshold while changed sat far below its threshold; if that holds against a real document viewer, Advanced's two-clause rule may be effectively one clause with a decoration. Not changed in this plan - measure first.
  • Nothing about the frontend's look and feel is verified beyond type-checking (svelte-check) and its own unit tests (vitest, pure logic only - no component-level or visual testing). Whether a drag feels right, whether Settings' split controls read clearly, whether the status panel dodges the capture region - all of that needs a person looking at it.
  • CI (.github/workflows/ci.yml) has not yet executed on this project's account - its Actions budget is exhausted. Every step (format, the dependency cap, vet, the Go build/test matrix, the frontend's Vitest suite and build, and the production-tagged GUI build) has instead been run locally, against a clean checkout equivalent, as each plan lands.

What flip will not do

flip reads pixels that are already rendered and visible on your screen. It does not work around windows that have opted out of screen capture via SetWindowDisplayAffinity, and it does not try to hide that its keystrokes are synthetic. When it detects either, it stops and tells you which one it hit.

A viewer with a large blinking text-cursor caret can defeat the settle detector: the caret toggling reads as continuous change, the page never measures as settled, and every page trips the no-change budget - the symptom is zero pages captured, then "end of document?" after about 7.5 seconds, on a document that plainly has more pages. Use flipdbg detect against the viewer to measure whether your caret falls in the affected range before reporting this as a bug.

Development

Requires Go 1.26.4 on Windows.

go test ./...
go build -o flipdbg.exe ./cmd/flipdbg

flipdbg is a debug harness for the capture layer, and also flip's own CLI front end for driving a capture end to end:

flipdbg monitors                        # list displays, bounds, DPI
flipdbg dpi                             # DPI awareness and refresh rate
flipdbg grab -r 0,0,800,600 -o out.png  # capture a region
flipdbg detect -r 0,0,800,600           # poll a region, print the detector's verdict
flipdbg windows [-all]                  # list windows a capture could target
flipdbg sendkey [-vk 0x22] [-w 5s]      # send an advance keystroke to a window you pick
flipdbg run -hwnd 0x... -r 0,0,800,600 [-out DIR] [-format jpg] [-pdf FILE]
                                         # capture a document end to end: turn pages,
                                         # poll for settle, stop at -max or end of document
flipdbg export -in DIR [-out DIR2] [-pdf FILE] [-split half] [-trim] [-long 2000]
                                         # post-process and assemble a directory of
                                         # spooled PNGs, with no capture involved

Run any subcommand with -h for its full flag list.

Coordinates are physical pixels on the virtual screen. Monitors left of or above the primary monitor have negative coordinates.

The GUI

Building or testing the frontend needs Node (the frontend's own package.json and package-lock.json are under frontend/) and the Wails CLI - frontend/wailsjs/ (the generated JS/TS bridge every screen imports from) is gitignored and regenerated, not tracked, so it has to exist before npm run build or npm run check will resolve:

go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0   # matches go.mod's wails/v2 version
wails generate module                                       # writes frontend/wailsjs/

cd frontend
npm install
npm run test -- --run   # Vitest - pure logic only (frontend/src/lib), no component/visual tests
npm run check            # svelte-check
npm run build

wails build -tags production   # or: go build -tags production -o flip.exe .   after npm run build

A plain go build ./... (no build tag) compiles internal/app/app_default_windows.go, a stub that shows a Win32 error dialog and exits - useful for confirming the cgo-free build stays green without a Node/npm setup, not for running the real GUI.

Design

  • Spec: docs/superpowers/specs/2026-07-28-flip-design.md
  • Plans: docs/superpowers/plans/

About

Automated screen-region capture: pick a region, flip through pages, export images or a PDF

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages