Two feature bodies accumulated in the working tree:
1. Pinch to change the app font size, continuously (no snapping):
- internal/ui/pinch_tracker.go: logic-free touch state machine.
Two-mover formation (the resting palm can land first or last;
movement is the only signal valid for both), pair = the mover
pair whose distance changed most, baseline = press distance
(formDist), lazy pending releases, survivor-scroll forwarding
after a pair break. Robust to ~1 fps frames: a whole pinch can
land in one drain (formDist/brokeFactor/lazy releases).
- render.go: pinch probe (raw pointer events) + grab lifecycle so
the pair is exclusive (scroll sees nothing of the pair) and the
survivor's finger keeps working as a scroll after the pinch.
- state.go/logic.go/session.go/frame.go: app-local float font
scale, content-point pin (buffer byte + offset from baseline,
not a layout point, so rewrap keeps the same character under
the center), restore/font pins, session persistence.
- pinch_test.go, pinch_font_test.go, tag_identity_test.go,
real_draw_probe_test.go: unit + real-Renderer/real-Router tests.
2. Soft keyboard must not shift content:
- Root cause: gioui.org/app calls Router.RevealFocus on any frame
the viewport shrinks (IME open under adjustResize) and
synthesizes a pointer.Scroll nudge aimed at the focused field's
stale pre-resize bounds; gesture.Scroll consumed it -> a 32 dp
content jump.
- Fix: main.go flags the shrink frame; render.go drains that one
synthetic scroll for the gesture's tag before Update (scroll-
range clamping cannot work: the router UNIONs ranges across
frames). Finger scroll (pointer.Drag) and the flinger are
untouched. reveal_focus_drain_test.go reproduces RevealFocus at
the router level and verifies the drain + zero delta.
Also: tools/touchinject (platform-signed emulator multi-touch
injection harness + e2e script, adb has no two-finger input),
docs (spec 2.2 + development_plan 18-20), .gitignore, gofmt.
49 lines
2.5 KiB
Bash
Executable File
49 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Builds touchinject.apk (a privileged multi-touch gesture injector) from
|
|
# Injector.java using the local Android SDK. The APK must be installed under
|
|
# /system/priv-app for the INJECT_EVENTS (signature|privileged) permission to
|
|
# be granted — see the bottom of this file.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
SDK=/home/gmp/android-sdk
|
|
BT="$SDK/build-tools/35.0.0"
|
|
PLAT="$SDK/platforms/android-35/android.jar"
|
|
|
|
rm -rf build
|
|
mkdir -p build/classes
|
|
javac -nowarn -source 1.8 -target 1.8 -classpath "$PLAT" -d build/classes Injector.java
|
|
"$BT/d8" --release --min-api 24 --lib "$PLAT" --output build build/classes/touch/inject/*.class
|
|
# aapt2 resolves the android: namespace against the framework resource
|
|
# table, which is shipped inside android.jar (resources.arsc).
|
|
"$BT/aapt2" link --manifest AndroidManifest.xml -I "$PLAT" \
|
|
--min-sdk-version 24 --target-sdk-version 35 -o build/base.apk
|
|
cp build/base.apk build/touchinject-unsigned.apk
|
|
jar uf build/touchinject-unsigned.apk -C build classes.dex
|
|
|
|
if [ ! -f build/ts.jks ]; then
|
|
keytool -genkeypair -keystore build/ts.jks -storepass android -keypass android \
|
|
-alias ts -dname "CN=TouchInject, OU=Dev" -keyalg RSA -keysize 2048 -validity 10000
|
|
fi
|
|
"$BT/apksigner" sign --ks build/ts.jks --ks-pass pass:android --key-pass pass:android \
|
|
--out touchinject.apk build/touchinject-unsigned.apk
|
|
"$BT/apksigner" verify --print-certs touchinject.apk | head -1
|
|
echo "=== DONE: $(pwd)/touchinject.apk"
|
|
|
|
# --- Install as a privileged system app (emulator, rooted) ---------------
|
|
# SER=emulator-5554
|
|
# adb -s $SER root && adb -s $SER remount
|
|
# adb -s $SER shell mkdir -p /system/priv-app/TouchInject
|
|
# adb -s $SER push touchinject.apk /system/priv-app/TouchInject/TouchInject.apk
|
|
# adb -s $SER shell chmod 644 /system/priv-app/TouchInject/TouchInject.apk
|
|
# adb -s $SER reboot # permission grant is evaluated at install/boot
|
|
# adb -s $SER wait-for-device && adb -s $SER shell 'while [ -z $(getprop sys.boot_completed) ]; do sleep 1; done'
|
|
# adb -s $SER shell dumpsys package touch.inject | grep -A2 INJECT_EVENTS # granted=true
|
|
#
|
|
# --- Inject a gesture ------------------------------------------------------
|
|
# adb -s $SER shell am startservice -n touch.inject/.Injector \
|
|
# -e script "down 1 400 1000 wait 100 down 2 700 1200 wait 100 \
|
|
# move 1 380 980 move 2 720 1220 wait 50 \
|
|
# move 1 340 940 move 2 760 1260 wait 50 up 1 up 2"
|
|
# adb -s $SER logcat -d -s TouchInject
|