A simple, high performance text editor.
Go to file
Greg Pomerantz 2a16c0017c Touch selection (v1): long-press/double-tap word selection, drag handles, floating copy/cut/paste menu
Implement the Android-native touch selection model, verified on-device:
- long-press selects the word under the finger (blank -> caret + paste-only
  menu); double-tap selects the word; drag handles resize the selection,
  drag the highlighted body to move it; floating menu offers copy/cut/paste
  (selection) or paste (bare caret), closing on any item tap.
- Renderer reports finger positions (app-local Dp) as tap/double-tap/
  long-press/selection-drag events; the logic goroutine owns all geometry
  (EditorRegion, menu rect, hit-testing, handles) and the renderer only
  draws the frame snapshot.
- Long press: 400 ms still-press on the editor, cancelled by movement
  (non-grabbing raw pointer probe) or by a scroll/handle grab. The main
  loop keeps invalidating while a press is pending (Gio renders on demand;
  a stationary finger produces no frames).
- Clipboard crosses the goroutine boundary via buffered channels
  (clipboardSetChan/pasteReqChan logic->main, pasteChan main->logic);
  main executes the Gio ops and, on Android, invalidates after ReadCmd
  because a queued transfer.DataEvent schedules no frame of its own.

Renderer fixes found while validating on-device:
- clickReg was stored by value in a map; range yielded copies so per-frame
  press bookkeeping (long-press state) was silently discarded. Now pointers.
- On Android a tap's press+release arrive in the same frame and
  gesture.Click/Drag return one event per Update call; without draining
  each gesture's queue every frame the release was lost on an idle window
  and every menu tap was swallowed (needed a second tap to 'rescue' it).
  Click and drag loops now drain to exhaustion (scroll already does).
- pointer.Filter queries must name Kinds: a zero-kinds filter matches
  nothing (the press-probe query was dead).
- Menu.Draw offsets items by the menu origin; the clippable drawElement
  branch registers SelDrag (handles now draw for the TextField).

Tests: internal/editor/touch_selection_test.go (word range, long-press,
double-tap, tap/menu guards, handle drags, menu actions, selection edits)
and internal/test/e2e/touch_selection_e2e_test.go; full suite green under
-race. Docs: spec.md §2.2 + §7, architecture.md §6.3a, development_plan.md
Phases 8-9.
2026-08-17 08:57:55 -04:00
.qwen Add ShapeText/DrawShapedText: single shaper call, zero-call drawing 2026-05-12 12:06:28 -04:00
cmd/pad Touch selection (v1): long-press/double-tap word selection, drag handles, floating copy/cut/paste menu 2026-08-17 08:57:55 -04:00
doc Touch selection (v1): long-press/double-tap word selection, drag handles, floating copy/cut/paste menu 2026-08-17 08:57:55 -04:00
internal Touch selection (v1): long-press/double-tap word selection, drag handles, floating copy/cut/paste menu 2026-08-17 08:57:55 -04:00
scripts doc: screen coordinate reference (screen vs display vs app-local px) 2026-08-16 22:19:40 -04:00
.DS_Store Add drawPng function to Renderer for PNG icon rendering 2026-05-10 06:26:29 -04:00
.gitignore Refactor RealFileSystem to use WorkingDir, and ensure clean shutdown with FlushAll 2026-06-05 11:42:39 -04:00
go.mod Update to gioui v0.10.0. 2026-06-03 22:17:52 -04:00
go.sum Update to gioui v0.10.0. 2026-06-03 22:17:52 -04:00