microsoft / microsoft/vscode

Gesture handler never releases touches cancelled by touchcancel

Open
#332,619 0 comments 0 reactions 1 assignee Claimed by @benibenj View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

### Bug description

The `Gesture` singleton (`src/vs/base/browser/touch.ts`) listens for `touchstart`, `touchmove` and `touchend` but never for `touchcancel`. When the browser takes over a touch (system gesture, palm rejection, navigation), it delivers `touchcancel` instead of `touchend`, so `onTouchEnd` never runs and the entry in `activeTouches` stays forever.

Consequences per leaked entry:

- the DOM node reference in `activeTouches` is pinned (no garbage collection while the page lives),
- `Gesture.addTarget` bookkeeping on that node is never undone,
- with exactly one remaining active touch, the inertia dispatch branch treats the session as multi-touch, so single-finger inertia scrolling stops working after a few cancelled swipes.

`grep -r touchcancel src/vs` finds no match: nothing under `src/vs/` handles cancellation today.

### Steps to reproduce

1. On a touch device, start a scroll gesture and trigger a UA takeover mid-gesture (e.g. invoke the system edge swipe) a few times.
2. Single-finger inertia scrolling stops responding afterwards; DevTools shows stale entries in `Gesture`'s internal touch map.

### Expected behavior

`touchcancel` releases the cancelled touch identifiers silently: no tap, context menu or inertia dispatch for an interrupted gesture, and the internal state is cleaned up like a normal end.

### Version tested

Commit `38ec3d57f91b` on `main`; verified by executing the compiled Gesture handler with synthesized cancel events. A fix is ready.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.