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.
16 lines
830 B
C
16 lines
830 B
C
#include <jni.h>
|
|
|
|
void registerFragment(JNIEnv *env, jobject view);
|
|
void GetId(JNIEnv* env, jobject p, int chint);
|
|
void Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint);
|
|
void Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint);
|
|
void Clip(JNIEnv* env, jobject p, char* cdata, int datalen);
|
|
void stringResult(JNIEnv* env, jclass cls, jint requestCode, jobject response);
|
|
void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID);
|
|
jint GetEnv(JavaVM *vm, JNIEnv **env, jint version);
|
|
jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args);
|
|
jint DetachCurrentThread(JavaVM *vm);
|
|
jobject NewGlobalRef(JNIEnv *env, jobject o);
|
|
void open_file_in_termux(JNIEnv *env, const char *path);
|
|
void SetGestureExclusions(JNIEnv *env, jint nrects, const jint *xyxy);
|