Commit Graph

4 Commits

Author SHA1 Message Date
275a78efaa Fix selection-handle drags, menu anchoring, and left-edge back-gesture theft
Three user-reported selection bugs, one root cause each:

1. Start handle ungrabbable at line start. Two interacting causes:
   a) The 48dp grab box straddles two visual lines; a finger in the
      lower half mapped (by y-to-line) to the neighbouring line, whose
      byte past the other handle clamped to a zero-length selection ->
      cleared on the first drag event. The cleared selection
      un-registered the drag op, so the router silently stopped
      delivering drag events (the observed 'stream cutoff'). Fix:
      handle drags now project the finger's x onto the anchor's own
      visual line (visualLineOfByte + textPosOnLineAtX); the anchor
      never crosses lines during a handle drag.
   b) A horizontal flick from the line-start handle (screen x~26px)
      started the system back gesture, which cancelled the touch
      stream. Fix: report the handle grab rects as system gesture
      exclusion rects (setSystemGestureExclusionRects, API 29+),
      marshalled to the UI thread via a PadExcl smali Runnable
      (generated identically by build_emu.sh/build_phone.sh).

2. End-handle drag downward made the menu chase the finger and cover
   the selection. Fix: the menu anchors to the STABLE end of the
   selection (the end not being dragged), so it stays parked by the
   selection start, clear of the finger and the highlighted text.

3. Menu above the selection vanished permanently when the selection
   was extended onto the top line. Fix: off-window anchors no longer
   hide the menu while any part of the selection is visible (keep-last
   rect, clamped); hiding happens only for fully off-window selections.

Also: registerDrag simplified (single shared drag path, body before
handles in z-order), debug logging removed, regression tests
(mutation-verified) for line projection and menu anchoring, docs
section 17. Verified on device: start-handle drag shrinks the word
without clearing or triggering back navigation; end-handle vertical
drag leaves menu/highlight/handles undisturbed; menu stays visible
with the selection at the top line.
2026-08-18 13:09:29 -04:00
dcb96d04d8 Fix Android window geometry, selection menu tracking
- SurfaceView windows are always translucent, so adjustResize cannot
  resize them: the keyboard overlapped the bottom of the window and the
  top bar sat under the status bar. Consume the insets in app instead:
  a smali-injected PadInsetsListener (identical block in build_emu.sh
  and build_phone.sh) shrinks the GioView to statusBarBottom..keyboardTop
  (or ..navBarTop) on every API 30+ insets dispatch, with
  setDecorFitsSystemWindows(false) so IME insets are delivered at
  targetSdk 34.
- Fix a change-detection bug in the listener: the height write skipped
  the topMargin/bottomMargin checks on every IME state transition, so
  the margins were never applied while the keyboard animated. All three
  params are now checked with a single requestLayout on any change.
- Selection menu now re-anchors to the selected word every frame while
  it is visible and hides when the word scrolls out of the viewport
  (positionSelectionMenu + regression test).
- Doc: development_plan.md section 14 (invariants, geometry contract,
  build-script identity invariant).

Verified on device: top bar below status bar and clickable, bottom bar
flush with keyboard top (view 128..1517 at 1080x2400), BACK dismiss +
re-tap re-raise without a show loop, typing saves, menu tracks scrolls.
2026-08-17 23:58:19 -04:00
941285e7cc Fix scroll-anchored selection (shadowing) + IME insets keyboard handling
Two user-reported bugs in the post-wrap build:

1. Selection 'jumped' when scrolling: frameOf's chunked branch shadowed the
   outer start/end with 'start, end, winLine := cb.VisibleByteRange(...)',
   leaving IMEWindowStartByte at 0 for chunked files while scrolled, so the
   window-relative selection highlight (and IME commits) mis-mapped near the
   file top. Fix: declare winLine outside, assign. Mutation-verified
   regression tests: real_file_scroll_selection_test.go.

2. Bottom bar hidden behind the keyboard: GioView extends SurfaceView, which
   unconditionally marks the window FORMAT_TRANSLUCENT; translucent windows
   are never IME-resized, so adjustResize is dead. Fix (build scripts):
   smali-patch a PadInsetsListener OnApplyWindowInsetsListener onto the
   GioView (shrinks it by the IME inset bottom) + setDecorFitsSystemWindows
   (false) on API 30+ so insets are dispatched. targetSdk kept at 34.

3. (Found while fixing 2) Keyboard could not be dismissed: TextField.Draw
   issued SoftKeyboardCmd{Show:true} every frame; with insets-driven
   resizes, the hide animation triggered redraws that re-showed the keyboard
   mid-animation. Fix: ShowIMESeq pulse from the logic layer (open/tap/
   double-tap); renderer shows only on pulse change, re-arming on focus
   loss — matching widget.Editor.

On-device (emulator): BACK dismisses and stays down; tap re-shows; typing
works; bottom bar above keyboard; word selection anchored across flick
scroll. go test -race ./... green. Phone APK rebuilt with the same patch.
2026-08-17 21:52:53 -04:00
95a2143e16 Add scripts/build_phone.sh: real-phone APK build (arm64+arm)
Same pipeline as build_emu.sh (gogio -> apktool MANAGE_EXTERNAL_STORAGE
injection -> debug-sign) for a real phone: -arch arm64,arm (covers any
phone from the last decade; gogio accepts a comma-separated arch list)
and output cmd/pad/pad-phone.apk. Notes in the header: on Android 11+
the user must grant 'All files access' in system settings after
installing (MANAGE_EXTERNAL_STORAGE is app-restricted; the emulator AVD
had it granted, phones do not).
2026-08-17 17:03:35 -04:00