What happened
With trackpad_gestures_enabled forced on (see #11), an up-swipe on the physical keys picks the left or centre suggestion fine, but the right-hand slot only responds to a flick that starts in the rightmost tenth of the keys.
Why
nativeImeTrackpadThird() in PhysicalKeyboardInputMethodService.kt splits the swipe's start X against a hard-coded 1440 px width (upstream's Titan 2 figure): left below 480, centre below 960, right otherwise. The Elite's touch layer is narrower. Captured on Titan 2 Elite_V02.00.04, Android 16:
$ adb shell getevent -p /dev/input/event4
name: "touchPad"
ABS (0003): 0030 : min 0, max 255 (ABS_MT_TOUCH_MAJOR)
0035 : min 0, max 1079 (ABS_MT_POSITION_X)
0036 : min 0, max 599 (ABS_MT_POSITION_Y)
input props: INPUT_PROP_DIRECT
$ adb shell dumpsys input (what Android hands to the IME)
Device 6: touchPad
Sources: KEYBOARD | TOUCHPAD
X: source=TOUCHPAD, min=0.000, max=1079.000
Y: source=TOUCHPAD, min=0.000, max=748.750
So the right third begins at x >= 960 of 1079. The 3.0 spec already suspected this (trackpad-caret-nav.md §3.3 and the quirks table: "D2 unverified"); this is the device confirmation.
Two related observations from the same capture:
- The default
trackpad_suggestion_swipe_threshold of 500 px is two thirds of the 749 px height Android reports, so a flick has to travel most of the pad. Upstream Pastiera's later f974c17 ("fix(trackpad): normalize device coordinates", 2026-08-18) normalises the thirds but also leaves the threshold in raw pixels; PhysiBoard does not carry that commit.
- The same input node also declares KEY events for BTN_TOUCH, the D-pad and a handful of letters, which looks like the path Unihertz's Scroll Assistant uses to turn swipes into key presses.
Fix
On my fork, rebased on legacy-2.x 2.0.7: read the X range from the event's InputDevice at gesture start and keep 1440 only as the fallback when no range is declared. djbclark@2ce1244 (branch native-trackpad-thirds). Builds, unit tests and lint pass. Happy to open it as a PR against legacy-2.x if you take fixes there; otherwise it is here for 3.0's spec, and a docs PR adding the capture to D2 follows.
PhysiBoard version
2.0.7 (built from legacy-2.x)
Phone
Unihertz Titan 2 Elite, Titan 2 Elite_V02.00.04, Android 16
What happened
With
trackpad_gestures_enabledforced on (see #11), an up-swipe on the physical keys picks the left or centre suggestion fine, but the right-hand slot only responds to a flick that starts in the rightmost tenth of the keys.Why
nativeImeTrackpadThird()inPhysicalKeyboardInputMethodService.ktsplits the swipe's start X against a hard-coded 1440 px width (upstream's Titan 2 figure): left below 480, centre below 960, right otherwise. The Elite's touch layer is narrower. Captured onTitan 2 Elite_V02.00.04, Android 16:So the right third begins at x >= 960 of 1079. The 3.0 spec already suspected this (
trackpad-caret-nav.md§3.3 and the quirks table: "D2 unverified"); this is the device confirmation.Two related observations from the same capture:
trackpad_suggestion_swipe_thresholdof 500 px is two thirds of the 749 px height Android reports, so a flick has to travel most of the pad. Upstream Pastiera's laterf974c17("fix(trackpad): normalize device coordinates", 2026-08-18) normalises the thirds but also leaves the threshold in raw pixels; PhysiBoard does not carry that commit.Fix
On my fork, rebased on
legacy-2.x2.0.7: read the X range from the event'sInputDeviceat gesture start and keep 1440 only as the fallback when no range is declared. djbclark@2ce1244 (branchnative-trackpad-thirds). Builds, unit tests and lint pass. Happy to open it as a PR againstlegacy-2.xif you take fixes there; otherwise it is here for 3.0's spec, and a docs PR adding the capture to D2 follows.PhysiBoard version
2.0.7 (built from
legacy-2.x)Phone
Unihertz Titan 2 Elite,
Titan 2 Elite_V02.00.04, Android 16