Skip to content

fix(main-editor): ignore spurious scale-end on mid-gesture pointer change (#850) - #851

Merged
hm21 merged 2 commits into
stablefrom
fix/850-multitouch-third-finger-crash
Jul 23, 2026
Merged

fix(main-editor): ignore spurious scale-end on mid-gesture pointer change (#850)#851
hm21 merged 2 commits into
stablefrom
fix/850-multitouch-third-finger-crash

Conversation

@hm21

@hm21 hm21 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Problem

Fixes #850 — editor freezes / crashes after a three-finger gesture while rotating an emoji layer (reported on iOS).

Flutter's ScaleGestureRecognizer fires a spurious onScaleEnd (immediately followed by a fresh onScaleStart) whenever the active pointer count changes mid-gesture — e.g. when a third finger touches the screen while two fingers are still rotating a layer (verified in gestures/scale.dart _reconfigure, line 717).

_onScaleEnd then ran its full interaction teardown (replacing the last screenshot, mutating the history stack, clearing the selection) even though the gesture was only being reconfigured, not ended. Two symptoms of the same root cause:

  • With a populated history → reentrant tree rebuild → assert(_dependents.isEmpty) in InheritedElement.debugDeactivated() → red screen + frozen editor on iOS.
  • With an empty history → RangeError from screenshots.removeLast().

Fix

  • _onScaleEnd returns early when details.pointerCount > 0 (a reconfiguration rather than a real end). The interactive viewer still receives the event so its own start/end pairing stays balanced.
  • _onScaleStart no longer adds a second history entry when a transform is already in progress (!isLayerBeingTransformed).

Test

Adds test/features/main_editor/multitouch_third_finger_test.dart, a deterministic multi-pointer widget test that drives the exact sequence (two-finger rotate on a selected emoji layer, then a third pointer down). It reproduces the crash before the fix and passes after — no physical device needed.

  • flutter analyze: clean
  • All main-editor test suites pass, including the new regression test.

hm21 added 2 commits July 23, 2026 11:03
…ange (#850)

Flutter's ScaleGestureRecognizer fires a spurious onScaleEnd (followed by a
fresh onScaleStart) whenever the active pointer count changes mid-gesture,
e.g. when a third finger touches the screen while two fingers are rotating a
layer. _onScaleEnd then ran its full interaction teardown (replacing the last
screenshot, mutating the history stack, clearing the selection), which
corrupted the history/screenshot stack and, on iOS, crashed the editor with a
`_dependents.isEmpty` framework assertion.

- _onScaleEnd now returns early when details.pointerCount > 0 (reconfiguration
  rather than a real end); the interactive viewer still receives the event so
  its start/end pairing stays balanced.
- _onScaleStart no longer adds a second history entry when a transform is
  already in progress.

Adds a deterministic multi-pointer widget test reproducing the crash.
@hm21
hm21 merged commit c8b2c92 into stable Jul 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Editor freezes after a three-finger gesture while rotating an emoji layer on iOS

1 participant