From 581a896ac75e84b21f7b8fd20d8e87aa81e1ba45 Mon Sep 17 00:00:00 2001 From: Luan Nico Date: Fri, 7 Aug 2026 09:04:26 -0400 Subject: [PATCH] chore!: Kill legacy Force Press event API --- doc/flame/inputs/gesture_input.md | 6 - doc/flame/migration.md | 24 +++ packages/flame/lib/events.dart | 2 - packages/flame/lib/src/game/flame_game.dart | 1 - .../game_widget/gesture_detector_builder.dart | 11 -- .../flame/lib/src/gestures/detectors.dart | 23 --- packages/flame/lib/src/gestures/events.dart | 9 - .../flame/test/gestures/detectors_test.dart | 165 ------------------ 8 files changed, 24 insertions(+), 217 deletions(-) diff --git a/doc/flame/inputs/gesture_input.md b/doc/flame/inputs/gesture_input.md index 00131ed5e30..e6dec94019d 100644 --- a/doc/flame/inputs/gesture_input.md +++ b/doc/flame/inputs/gesture_input.md @@ -38,12 +38,6 @@ Detectors will be deprecated in the future. Prefer `Callbacks` instead. - onHorizontalDragEnd - onHorizontalDragCancel -- ForcePressDetector - - onForcePressStart - - onForcePressPeak - - onForcePressUpdate - - onForcePressEnd - - PanDetector - onPanDown - onPanStart diff --git a/doc/flame/migration.md b/doc/flame/migration.md index ba59dba2a89..2e74c719f70 100644 --- a/doc/flame/migration.md +++ b/doc/flame/migration.md @@ -7,6 +7,30 @@ major versions of Flame, together with the steps required to migrate your code. ## Migrating from v1.38.0 to v2.0.0 +### `ForcePressDetector` removed + +The `ForcePressDetector` mixin and its `ForcePressInfo` event class have been removed, with no +replacement. + +It was a niche API, only available on some older Apple's 3D Touch devices; the iPhone XS and XS Max +(2018) were the last models to include it (see Apple's +[Models with 3D Touch](https://support.apple.com/guide/iphone/aside/iph945ccc462/14.0/ios/14.0), +a list that Apple even stopped carrying forward after the iOS 14 guide). Every iPhone since, +starting with the XR, uses Haptic Touch, which responds to how long a press lasts rather than how +hard it is, and so never produces these callbacks. Only a handful of Android devices ever +supported it, and some of those (such as the Pixel 2 and 3) have faux pressure sensors that never +fired the callbacks anyway. + +Combined with force press being the last gesture without an equivalent on the component-level event +system, maintaining it was no longer worth the surface area. + +If you do still target a 3D Touch device, the gesture remains fully available from Flutter: wrap +your `GameWidget` in a +[`GestureDetector`](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html) and use its +`onForcePressStart`, `onForcePressPeak`, `onForcePressUpdate` and `onForcePressEnd` callbacks +directly. + + ### Deprecated tap and long press game detectors removed The game-level detector mixins that were deprecated in v1.38.0 have now been removed, together with diff --git a/packages/flame/lib/events.dart b/packages/flame/lib/events.dart index b9cc484ad71..28bd1ff2ca2 100644 --- a/packages/flame/lib/events.dart +++ b/packages/flame/lib/events.dart @@ -80,7 +80,6 @@ export 'src/game/mixins/keyboard.dart' show HasKeyboardHandlerComponents, KeyboardEvents; export 'src/gestures/detectors.dart' show - ForcePressDetector, HorizontalDragDetector, MouseMovementDetector, PanDetector, @@ -93,7 +92,6 @@ export 'src/gestures/events.dart' DragEndInfo, DragStartInfo, DragUpdateInfo, - ForcePressInfo, PointerHoverInfo, PointerScrollInfo, PositionInfo, diff --git a/packages/flame/lib/src/game/flame_game.dart b/packages/flame/lib/src/game/flame_game.dart index 0a36de8f196..bb1c4cec7a9 100644 --- a/packages/flame/lib/src/game/flame_game.dart +++ b/packages/flame/lib/src/game/flame_game.dart @@ -249,7 +249,6 @@ class FlameGame extends ComponentTreeRoot // so any in-bounds point is a hit. if (this is VerticalDragDetector || this is HorizontalDragDetector || - this is ForcePressDetector || this is PanDetector || this is ScaleDetector || this is MultiTapListener || diff --git a/packages/flame/lib/src/game/game_widget/gesture_detector_builder.dart b/packages/flame/lib/src/game/game_widget/gesture_detector_builder.dart index 877a1b9d19e..046c29ee5fc 100644 --- a/packages/flame/lib/src/game/game_widget/gesture_detector_builder.dart +++ b/packages/flame/lib/src/game/game_widget/gesture_detector_builder.dart @@ -68,17 +68,6 @@ class GestureDetectorBuilder { }, ); } - if (game is ForcePressDetector) { - register( - ForcePressGestureRecognizer.new, - (ForcePressGestureRecognizer instance) { - instance.onStart = game.handleForcePressStart; - instance.onPeak = game.handleForcePressPeak; - instance.onUpdate = game.handleForcePressUpdate; - instance.onEnd = game.handleForcePressEnd; - }, - ); - } if (game is PanDetector) { register( PanGestureRecognizer.new, diff --git a/packages/flame/lib/src/gestures/detectors.dart b/packages/flame/lib/src/gestures/detectors.dart index 5e5e30f05a3..48bcc0520c5 100644 --- a/packages/flame/lib/src/gestures/detectors.dart +++ b/packages/flame/lib/src/gestures/detectors.dart @@ -50,29 +50,6 @@ mixin HorizontalDragDetector on Game { } } -mixin ForcePressDetector on Game { - void onForcePressStart(ForcePressInfo info) {} - void onForcePressPeak(ForcePressInfo info) {} - void onForcePressUpdate(ForcePressInfo info) {} - void onForcePressEnd(ForcePressInfo info) {} - - void handleForcePressStart(ForcePressDetails details) { - onForcePressStart(ForcePressInfo.fromDetails(this, details)); - } - - void handleForcePressPeak(ForcePressDetails details) { - onForcePressPeak(ForcePressInfo.fromDetails(this, details)); - } - - void handleForcePressUpdate(ForcePressDetails details) { - onForcePressUpdate(ForcePressInfo.fromDetails(this, details)); - } - - void handleForcePressEnd(ForcePressDetails details) { - onForcePressEnd(ForcePressInfo.fromDetails(this, details)); - } -} - mixin PanDetector on Game { void onPanDown(DragDownInfo info) {} void onPanStart(DragStartInfo info) {} diff --git a/packages/flame/lib/src/gestures/events.dart b/packages/flame/lib/src/gestures/events.dart index c511fb5421e..eab8f02ca53 100644 --- a/packages/flame/lib/src/gestures/events.dart +++ b/packages/flame/lib/src/gestures/events.dart @@ -75,15 +75,6 @@ class TapUpInfo extends PositionInfo { ) : super(game, raw.globalPosition, raw); } -class ForcePressInfo extends PositionInfo { - late final double pressure = raw.pressure; - - ForcePressInfo.fromDetails( - Game game, - ForcePressDetails raw, - ) : super(game, raw.globalPosition, raw); -} - class PointerScrollInfo extends PositionInfo { late final EventDelta scrollDelta = EventDelta(raw.scrollDelta); diff --git a/packages/flame/test/gestures/detectors_test.dart b/packages/flame/test/gestures/detectors_test.dart index 3e9aae0ba5f..8945091987c 100644 --- a/packages/flame/test/gestures/detectors_test.dart +++ b/packages/flame/test/gestures/detectors_test.dart @@ -155,144 +155,6 @@ void main() { ); }); - group('ForcePressDetector', () { - final forcePressGame = FlameTester(_ForcePressDetectorGame.new); - - forcePressGame.testGameWidget( - 'can register forcePress', - verify: (game, tester) async { - const forcePressOffset = Offset(10, 10); - - final pointerValue = tester.nextPointer; - - final gesture = await tester.createGesture(); - await gesture.downWithCustomEvent( - forcePressOffset, - PointerDownEvent( - pointer: pointerValue, - position: forcePressOffset, - pressure: 0.0, - pressureMax: 6.0, - pressureMin: 0.0, - ), - ); - - await gesture.updateWithCustomEvent( - PointerMoveEvent( - pointer: pointerValue, - pressure: 0.3, - pressureMin: 0, - ), - ); - - expect(game.forcePressStart, equals(0)); - expect(game.forcePressPeaked, equals(0)); - expect(game.forcePressUpdate, equals(0)); - expect(game.forcePressEnded, equals(0)); - - await gesture.updateWithCustomEvent( - PointerMoveEvent( - pointer: pointerValue, - pressure: 0.5, - pressureMin: 0, - ), - ); - - expect(game.forcePressStart, equals(1)); - expect(game.forcePressPeaked, equals(0)); - expect(game.forcePressUpdate, equals(1)); - expect(game.forcePressEnded, equals(0)); - - await gesture.updateWithCustomEvent( - PointerMoveEvent( - pointer: pointerValue, - pressure: 0.9, - pressureMin: 0, - ), - ); - - expect(game.forcePressStart, equals(1)); - expect(game.forcePressPeaked, equals(1)); - expect(game.forcePressUpdate, equals(2)); - expect(game.forcePressEnded, equals(0)); - - await gesture.up(); - - expect(game.forcePressStart, equals(1)); - expect(game.forcePressPeaked, equals(1)); - expect(game.forcePressUpdate, equals(2)); - expect(game.forcePressEnded, equals(1)); - }, - ); - - testWithGame<_ForcePressDetectorGame>( - 'can be Force Press started', - _ForcePressDetectorGame.new, - (game) async { - await game.ready(); - - game.handleForcePressStart( - ForcePressDetails( - globalPosition: const Offset(10, 10), - pressure: 0.4, - ), - ); - - expect(game.forcePressStart, equals(1)); - }, - ); - - testWithGame<_ForcePressDetectorGame>( - 'can be Force Press Updated', - _ForcePressDetectorGame.new, - (game) async { - await game.ready(); - - game.handleForcePressUpdate( - ForcePressDetails( - globalPosition: const Offset(10, 10), - pressure: 0.7, - ), - ); - - expect(game.forcePressUpdate, equals(1)); - }, - ); - - testWithGame<_ForcePressDetectorGame>( - 'can be Force Press peaked', - _ForcePressDetectorGame.new, - (game) async { - await game.ready(); - - game.handleForcePressPeak( - ForcePressDetails( - globalPosition: const Offset(10, 10), - pressure: 0.9, - ), - ); - - expect(game.forcePressPeaked, equals(1)); - }, - ); - - testWithGame<_ForcePressDetectorGame>( - 'can be Force Press Ended', - _ForcePressDetectorGame.new, - (game) async { - await game.ready(); - - game.handleForcePressEnd( - ForcePressDetails( - globalPosition: const Offset(10, 10), - pressure: 0.2, - ), - ); - expect(game.forcePressEnded, equals(1)); - }, - ); - }); - group('PanDetector', () { final panGame = FlameTester(_PanDetectorGame.new); @@ -518,33 +380,6 @@ class _VerticalDragDetectorGame extends FlameGame with VerticalDragDetector { } } -class _ForcePressDetectorGame extends FlameGame with ForcePressDetector { - int forcePressStart = 0; - int forcePressPeaked = 0; - int forcePressUpdate = 0; - int forcePressEnded = 0; - - @override - void onForcePressStart(ForcePressInfo info) { - forcePressStart++; - } - - @override - void onForcePressEnd(ForcePressInfo info) { - forcePressEnded++; - } - - @override - void onForcePressUpdate(ForcePressInfo info) { - forcePressUpdate++; - } - - @override - void onForcePressPeak(ForcePressInfo info) { - forcePressPeaked++; - } -} - class _PanDetectorGame extends FlameGame with PanDetector { bool hasPanDown = false; bool hasPanCancel = false;