On Android tablets, input from active pens (S-Pen, USI styluses) must be strictly distinguished from fingers. Drawing gestures should only be triggered by pen input, while finger touches should default to viewport pan/zoom, preventing accidental marks caused by resting the palm on the glass.
Scope of Work
Track input device types in the viewport / canvas layer:
Inspect incoming pointer events for device/tool classification (winit pointer types or raw android-activityMotionEvent::tool_type).
Implement Palm-Rejection logic:
If an active stylus touch is detected (ToolType::Stylus), lock drawing stroke creation to that pointer ID.
If a touch contact is classified as finger (ToolType::Finger), ignore stroke generation and route it to canvas navigation (pan / pinch-to-zoom).
If multiple touch contacts occur simultaneously, abort any tentative drawing stroke and engage multitouch zoom/pan.
Pressure sensitivity:
Map normalized pressure values from pen events to stroke width interpolation if supported by the vector brush engine.
Acceptance Criteria
Resting the palm on the screen while drawing does not produce stray dots or erratic lines.
Two-finger gestures reliably pan and zoom the canvas without drawing vector points.
### Description
On Android tablets, input from active pens (S-Pen, USI styluses) must be strictly distinguished from fingers. Drawing gestures should only be triggered by pen input, while finger touches should default to viewport pan/zoom, preventing accidental marks caused by resting the palm on the glass.
### Scope of Work
1. Track input device types in the viewport / canvas layer:
- Inspect incoming pointer events for device/tool classification (`winit` pointer types or raw `android-activity` `MotionEvent::tool_type`).
2. Implement Palm-Rejection logic:
- If an active stylus touch is detected (`ToolType::Stylus`), lock drawing stroke creation to that pointer ID.
- If a touch contact is classified as finger (`ToolType::Finger`), ignore stroke generation and route it to canvas navigation (pan / pinch-to-zoom).
- If multiple touch contacts occur simultaneously, abort any tentative drawing stroke and engage multitouch zoom/pan.
3. Pressure sensitivity:
- Map normalized pressure values from pen events to stroke width interpolation if supported by the vector brush engine.
### Acceptance Criteria
- Resting the palm on the screen while drawing does not produce stray dots or erratic lines.
- Two-finger gestures reliably pan and zoom the canvas without drawing vector points.
Corrections after checking the code (planned for the future, not started)
The desktop app already has this logic in src/main.rs:
Fingers pan and zoom unless finger drawing is enabled.
Two fingers cancel a stroke and start pinch.
Palm rejection: touches that start while the pen is near, or within 700 ms after it leaves, are ignored until lifted (Issue #39).
The pen comes in through octotablet (Wayland tablet protocol), separately from winit touch.
On Android, octotablet does not work. winit 0.29 reports pen and finger both as WindowEvent::Touch, without the tool type. So we need either:
a small winit patch that passes MotionEvent::tool_type() along (we already vendor winit), or
reading the android-activity input events directly.
The patch is probably simpler, because the rest of the input code stays the same.
The best way to share code: turn pen events from both sources (octotablet on desktop, Android stylus) into the same internal pen events (proximity, down, move, up, pressure, tilt, buttons). The existing palm rejection and drawing code then works unchanged.
Pressure is already used (pressure curve in the settings, variable stroke width). Android delivers pressure 0..1 per pointer, so it can be passed straight through.
To check: S-Pen hover (proximity) and the side button (select and erase like on the desktop).
**Corrections after checking the code** (planned for the future, not started)
- The desktop app already has this logic in `src/main.rs`:
- Fingers pan and zoom unless finger drawing is enabled.
- Two fingers cancel a stroke and start pinch.
- Palm rejection: touches that start while the pen is near, or within 700 ms after it leaves, are ignored until lifted (Issue #39).
- The pen comes in through **octotablet** (Wayland tablet protocol), separately from winit touch.
- On Android, octotablet does not work. winit 0.29 reports pen and finger both as `WindowEvent::Touch`, without the tool type. So we need either:
- a small winit patch that passes `MotionEvent::tool_type()` along (we already vendor winit), or
- reading the `android-activity` input events directly.
The patch is probably simpler, because the rest of the input code stays the same.
- The best way to share code: turn pen events from both sources (octotablet on desktop, Android stylus) into the same internal pen events (proximity, down, move, up, pressure, tilt, buttons). The existing palm rejection and drawing code then works unchanged.
- Pressure is already used (pressure curve in the settings, variable stroke width). Android delivers pressure 0..1 per pointer, so it can be passed straight through.
- To check: S-Pen hover (proximity) and the side button (select and erase like on the desktop).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
On Android tablets, input from active pens (S-Pen, USI styluses) must be strictly distinguished from fingers. Drawing gestures should only be triggered by pen input, while finger touches should default to viewport pan/zoom, preventing accidental marks caused by resting the palm on the glass.
Scope of Work
winitpointer types or rawandroid-activityMotionEvent::tool_type).ToolType::Stylus), lock drawing stroke creation to that pointer ID.ToolType::Finger), ignore stroke generation and route it to canvas navigation (pan / pinch-to-zoom).Acceptance Criteria
Corrections after checking the code (planned for the future, not started)
The desktop app already has this logic in
src/main.rs:On Android, octotablet does not work. winit 0.29 reports pen and finger both as
WindowEvent::Touch, without the tool type. So we need either:MotionEvent::tool_type()along (we already vendor winit), orandroid-activityinput events directly.The patch is probably simpler, because the rest of the input code stays the same.
The best way to share code: turn pen events from both sources (octotablet on desktop, Android stylus) into the same internal pen events (proximity, down, move, up, pressure, tilt, buttons). The existing palm rejection and drawing code then works unchanged.
Pressure is already used (pressure curve in the settings, variable stroke width). Android delivers pressure 0..1 per pointer, so it can be passed straight through.
To check: S-Pen hover (proximity) and the side button (select and erase like on the desktop).