A universal gesture-interaction specification and C++17 engine that unifies touch controls across every major OS and hardware platform.
OctaTouch maps raw multi-touch input onto eight functional channels — L1–L4 on the left hand, R1–R4 on the right — with the thumb acting as a global modifier (Navigate / Switch / Confirm). The result is a consistent, hardware-agnostic gesture vocabulary that works identically whether the surface is a phone screen, a tablet, an in-vehicle display, or a resistive touchscreen on embedded hardware.
When it works, it is invisible.
| Channel | Hand | Finger position |
|---|---|---|
L1 |
Left | Index, top zone |
L2 |
Left | Index, mid zone |
L3 |
Left | Ring, top zone |
L4 |
Left | Ring, mid zone |
R1 |
Right | Index, top zone |
R2 |
Right | Index, mid zone |
R3 |
Right | Ring, top zone |
R4 |
Right | Ring, mid zone |
The thumb modifier changes the semantic of any channel gesture:
| Modifier | Meaning |
|---|---|
None |
Default action |
Navigate |
Move / scroll |
Switch |
Context switch |
Confirm |
Commit / select |
Raw hardware input flows through four stages:
- FingerTracker — assigns stable finger IDs across frames
- GestureRecognizer — classifies tap, hold, swipe, and chord-press
- IntentResolver — maps gestures to archive-bound channel intents
- App — receives typed
ChannelIntentevents
The entire pipeline is implemented in core/ as a dependency-free C++17 library.
# Requires CMake >= 3.16 and a C++17 compiler
make build # cmake configure + build
make test # ctestnode tests/runtime/expo_runtime_smoke.mjscd apps/expo-demo
npm install
npx expo start| Platform | Adapter | Status |
|---|---|---|
| Web | platforms/web/PointerEventAdapter.ts |
✅ |
| iOS / Android (Expo) | apps/expo-demo/modules/octatouch-native/ |
✅ |
| AD7879 resistive touchscreen | integrations/firmware-ad7879/ad7879_driver.c |
✅ |
| In-vehicle HMI (CAN bus) | integrations/in-vehicle-hmi/DrivingModeGate.cpp |
✅ |
The in-vehicle HMI integration enforces a DrivingModeGate that restricts available channels based on vehicle speed and handbrake state. See integrations/in-vehicle-hmi/ and docs/adr/0002-storage-enforces-policy.md.
core/ C++17 gesture engine (no OS dependencies)
├── include/ Types.h, GestureEngine.h, FingerTracker.h, ...
└── src/ Implementations
platforms/
├── expo/ React Native design system (OctaButton, OctaCard, ...)
└── web/ PointerEventAdapter.ts
integrations/
├── firmware-ad7879/ Resistive touchscreen driver (C)
├── in-vehicle-hmi/ DrivingModeGate + CANBusMonitor (C++)
└── text-editor/ TextSelectionPlugin.ts
apps/expo-demo/ Runnable Expo demo application
tests/ Unit, integration, runtime smoke tests
docs/ ADRs, architecture, PRD, gesture vocabulary
assets/ SVG diagrams used in this README
| Document | Description |
|---|---|
docs/architecture.md |
Engine architecture and data flow |
docs/gesture-vocabulary.md |
Full gesture taxonomy |
docs/prd.md |
Product requirements |
docs/adr/0001-eight-channel-archive-model.md |
Why eight channels |
docs/adr/0002-storage-enforces-policy.md |
Archive binding policy |
docs/security-threat-model.md |
Threat model |
- Fork the repo and create a branch from
main. - Run
make testbefore opening a PR — all CTest and JS smoke tests must pass. - Follow the existing C++17 style in
core/; no OS-specific headers in the core library. - For platform adapters, keep the adapter thin — translate input to
GestureInputFrame, then callGestureEngine::Submit().
See docs/agent-guides/ for AI-assisted contribution guidelines.