fix!: Migrate from RawKeyEvent to KeyEvent (#3002)

First pass at migrating from `RawKeyEvent` and `RawKeyboard`
to `KeyEvent` and `HardwareKeyboard`.

Context:
https://docs.flutter.dev/release/breaking-changes/key-event-migration
This commit is contained in:
Brett Morgan
2024-02-16 09:10:51 +11:00
committed by GitHub
parent 20d368c326
commit 330862c98e
53 changed files with 90 additions and 83 deletions

View File

@ -9,7 +9,7 @@ on:
env:
FLUTTER_MIN_VERSION: '3.16.0'
FLUTTER_MIN_VERSION: '3.19.0'
jobs:
# BEGIN LINTING STAGE

View File

@ -5,7 +5,7 @@ publish_to: none
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -44,7 +44,7 @@ class EmberPlayer extends SpriteAnimationComponent
}
@override
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
horizontalDirection = 0;
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyA) ||
keysPressed.contains(LogicalKeyboardKey.arrowLeft))

View File

@ -5,6 +5,7 @@ version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -209,7 +209,7 @@ class PadRacingGame extends Forge2DGame with KeyboardEvents {
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
super.onKeyEvent(event, keysPressed);

View File

@ -7,7 +7,7 @@ version: 0.1.0
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -88,7 +88,7 @@ class TRexGame extends FlameGame
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
if (keysPressed.contains(LogicalKeyboardKey.enter) ||

View File

@ -7,7 +7,7 @@ version: 0.1.0
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
collection: ^1.16.0

View File

@ -142,8 +142,8 @@ class Player extends PositionComponent with KeyboardHandler {
}
@override
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
final isKeyDown = event is RawKeyDownEvent;
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
final isKeyDown = event is KeyDownEvent;
final keyLeft = (event.logicalKey == LogicalKeyboardKey.arrowLeft) ||
(event.logicalKey == LogicalKeyboardKey.keyA);
final keyRight = (event.logicalKey == LogicalKeyboardKey.arrowRight) ||

View File

@ -155,10 +155,10 @@ class CoordinateSystemsExample extends FlameGame
/// Camera controls.
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
final isKeyDown = event is RawKeyDownEvent;
final isKeyDown = event is KeyDownEvent;
if (event.logicalKey == LogicalKeyboardKey.keyA) {
cameraVelocity.x = isKeyDown ? -1 : 0;

View File

@ -100,8 +100,8 @@ class MovableEmber extends Ember<FollowComponentExample>
}
@override
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
final isKeyDown = event is RawKeyDownEvent;
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
final isKeyDown = event is KeyDownEvent;
final bool handled;
if (event.logicalKey == LogicalKeyboardKey.keyA) {

View File

@ -142,7 +142,7 @@ Press T button to toggle player to collide with other objects.
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
for (final key in keysPressed) {

View File

@ -39,14 +39,14 @@ class KeyboardExample extends FlameGame with KeyboardEvents {
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
final isKeyDown = event is RawKeyDownEvent;
final isKeyDown = event is KeyDownEvent;
// Avoiding repeat event as we are interested only in
// key up and key down event.
if (!event.repeat) {
if (key is! KeyRepeatEvent) {
if (event.logicalKey == LogicalKeyboardKey.keyA) {
_direction.x += isKeyDown ? -1 : 1;
} else if (event.logicalKey == LogicalKeyboardKey.keyD) {

View File

@ -30,10 +30,10 @@ class NoFlameGameExample extends Game with KeyboardEvents {
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
final isKeyDown = event is RawKeyDownEvent;
final isKeyDown = event is KeyDownEvent;
if (event.logicalKey == LogicalKeyboardKey.keyA) {
velocity.x = isKeyDown ? -1 : 0;

View File

@ -7,7 +7,7 @@ version: 0.1.0
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
dashbook: ^0.1.12

View File

@ -16,6 +16,7 @@ command:
bootstrap:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ^3.19.0
dependencies:
meta: ^1.9.1
vector_math: ^2.1.4

View File

@ -5,7 +5,7 @@ publish_to: 'none'
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -23,8 +23,8 @@ class KeyboardListenerComponent extends Component with KeyboardHandler {
final Map<LogicalKeyboardKey, KeyHandlerCallback> _keyDown;
@override
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
final isUp = event is RawKeyUpEvent;
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
final isUp = event is KeyUpEvent;
final handlers = isUp ? _keyUp : _keyDown;
final handler = handlers[event.logicalKey];

View File

@ -6,7 +6,7 @@ import 'package:flutter/services.dart';
/// Must be used in components that can only be added to games that are mixed
/// with [HasKeyboardHandlerComponents].
mixin KeyboardHandler on Component {
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
return true;
}
}

View File

@ -311,7 +311,7 @@ class GameWidgetState<T extends Game> extends State<GameWidget<T>> {
}
}
KeyEventResult _handleKeyEvent(FocusNode focusNode, RawKeyEvent event) {
KeyEventResult _handleKeyEvent(FocusNode focusNode, KeyEvent event) {
final game = currentGame;
if (!_focusNode.hasPrimaryFocus) {
@ -319,7 +319,10 @@ class GameWidgetState<T extends Game> extends State<GameWidget<T>> {
}
if (game is KeyboardEvents) {
return game.onKeyEvent(event, RawKeyboard.instance.keysPressed);
return game.onKeyEvent(
event,
HardwareKeyboard.instance.logicalKeysPressed,
);
}
return KeyEventResult.handled;
}
@ -361,7 +364,7 @@ class GameWidgetState<T extends Game> extends State<GameWidget<T>> {
focusNode: _focusNode,
autofocus: widget.autofocus,
descendantsAreFocusable: true,
onKey: _handleKeyEvent,
onKeyEvent: _handleKeyEvent,
child: MouseRegion(
cursor: currentGame.mouseCursor,
child: Directionality(

View File

@ -13,7 +13,7 @@ mixin HasKeyboardHandlerComponents<W extends World> on FlameGame<W>
@override
@mustCallSuper
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
final blockedPropagation = !propagateToChildren<KeyboardHandler>(
@ -34,7 +34,7 @@ mixin HasKeyboardHandlerComponents<W extends World> on FlameGame<W>
/// Override [onKeyEvent] to customize the keyboard handling behavior.
mixin KeyboardEvents on Game {
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
assert(

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
collection: ^1.17.1

View File

@ -9,15 +9,15 @@ abstract class _KeyCallStub {
class KeyCallStub extends Mock implements _KeyCallStub {}
class MockRawKeyUpEvent extends Mock implements RawKeyUpEvent {
class MockKeyUpEvent extends Mock implements KeyUpEvent {
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return super.toString();
}
}
RawKeyUpEvent _mockKeyUp(LogicalKeyboardKey key) {
final event = MockRawKeyUpEvent();
KeyUpEvent _mockKeyUp(LogicalKeyboardKey key) {
final event = MockKeyUpEvent();
when(() => event.logicalKey).thenReturn(key);
return event;
}

View File

@ -12,7 +12,7 @@ class _KeyboardEventsGame extends FlameGame with KeyboardEvents {
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
this.keysPressed.add(event.character ?? 'none');
@ -25,7 +25,7 @@ class _KeyboardHandlerComponent extends Component with KeyboardHandler {
final List<String> keysPressed = [];
@override
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
this.keysPressed.add(event.character ?? 'none');
return false;
}

View File

@ -25,7 +25,7 @@ class _GameWithKeyboardEvents extends FlameGame with KeyboardEvents {
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
keyEvents.add(event.logicalKey);
@ -443,7 +443,7 @@ void main() {
testWidgets('overlay handles keys', (tester) async {
final overlayKeyEvents = <LogicalKeyboardKey>[];
final overlayFocusNode = FocusNode(
onKey: (_, keyEvent) {
onKeyEvent: (_, keyEvent) {
overlayKeyEvents.add(keyEvent.logicalKey);
return KeyEventResult.ignored;
},
@ -475,7 +475,7 @@ void main() {
await simulateKeyDownEvent(LogicalKeyboardKey.keyA);
await tester.pump();
expect(game.keyEvents, <RawKeyEvent>[]);
expect(game.keyEvents, <KeyEvent>[]);
expect(overlayKeyEvents, [LogicalKeyboardKey.keyA]);
});
});

View File

@ -3,27 +3,23 @@ import 'package:flame/input.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
class _ValidGame extends FlameGame with KeyboardEvents {}
class _InvalidGame extends FlameGame
with HasKeyboardHandlerComponents, KeyboardEvents {}
class _MockRawKeyEventData extends Mock implements RawKeyEventData {
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.debug}) {
return super.toString();
}
}
void main() {
group('Keyboard events', () {
test(
'game with KeyboardEvents can handle key events',
() {
final validGame = _ValidGame();
final event = RawKeyDownEvent(data: _MockRawKeyEventData());
const event = KeyDownEvent(
physicalKey: PhysicalKeyboardKey.arrowUp,
logicalKey: LogicalKeyboardKey.arrowUp,
timeStamp: Duration.zero,
);
// Should just work with the default implementation
expect(
@ -37,7 +33,11 @@ void main() {
'cannot mix KeyboardEvent and HasKeyboardHandlerComponents together',
() {
final invalidGame = _InvalidGame();
final event = RawKeyDownEvent(data: _MockRawKeyEventData());
const event = KeyDownEvent(
physicalKey: PhysicalKeyboardKey.arrowUp,
logicalKey: LogicalKeyboardKey.arrowUp,
timeStamp: Duration.zero,
);
// Should throw an assertion error
expect(

View File

@ -10,7 +10,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
audioplayers: ^5.0.0

View File

@ -107,7 +107,7 @@ class PlayerComponent extends SpriteAnimationComponent
@override
bool onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
if (keysPressed.contains(LogicalKeyboardKey.tab)) {

View File

@ -7,6 +7,7 @@ version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ^3.19.0
dependencies:
equatable: ^2.0.5

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"
flutter: ^3.19.0
dependencies:
bloc: ^8.1.1

View File

@ -10,7 +10,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
archive: ^3.3.9

View File

@ -7,7 +7,7 @@ version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
dashbook: ^0.1.12

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -58,32 +58,32 @@ class ColonistsGame extends FlameGame with KeyboardEvents {
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
var howMuch = 0.0;
if (event is RawKeyDownEvent) {
if (event is KeyDownEvent) {
howMuch = 1;
} else if (event is RawKeyUpEvent) {
} else if (event is KeyUpEvent) {
howMuch = 0;
}
if (event.data.logicalKey == LogicalKeyboardKey.keyS) {
if (event.logicalKey == LogicalKeyboardKey.keyS) {
_downForce = howMuch;
} else if (event.data.logicalKey == LogicalKeyboardKey.keyW) {
} else if (event.logicalKey == LogicalKeyboardKey.keyW) {
_upForce = howMuch;
} else if (event.data.logicalKey == LogicalKeyboardKey.keyD) {
} else if (event.logicalKey == LogicalKeyboardKey.keyD) {
_rightForce = howMuch;
} else if (event.data.logicalKey == LogicalKeyboardKey.keyA) {
} else if (event.logicalKey == LogicalKeyboardKey.keyA) {
_leftForce = howMuch;
} else if (event.data.logicalKey == LogicalKeyboardKey.numpadAdd &&
event is RawKeyDownEvent) {
} else if (event.logicalKey == LogicalKeyboardKey.numpadAdd &&
event is KeyDownEvent) {
camera.viewfinder.zoom = min(
camera.viewfinder.zoom + 0.1,
5,
);
} else if (event.data.logicalKey == LogicalKeyboardKey.numpadSubtract &&
event is RawKeyDownEvent) {
} else if (event.logicalKey == LogicalKeyboardKey.numpadSubtract &&
event is KeyDownEvent) {
camera.viewfinder.zoom = max(
camera.viewfinder.zoom - 0.1,
0.1,

View File

@ -7,6 +7,7 @@ version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ^3.19.0
dependencies:
collection: ^1.18.0

View File

@ -5,7 +5,7 @@ repository: https://github.com/flame-engine/flame/blob/main/packages/flame_isola
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=1.17.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -10,7 +10,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
collection: ^1.17.1

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -10,7 +10,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=1.17.0"
flutter: ^3.19.0
dependencies:
dev: ^1.0.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
fast_noise: ^2.0.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -5,7 +5,7 @@ version: 5.2.0
homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_riverpod
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=1.17.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0
flutter:

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
collection: ^1.17.1

View File

@ -6,7 +6,7 @@ version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame_splash_screen: ^0.2.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flutter:

View File

@ -10,7 +10,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"
flutter: ^3.19.0
dependencies:
collection: ^1.17.1

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -5,7 +5,7 @@ publish_to: none
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
flame: ^1.15.0

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
collection: ^1.17.1

View File

@ -9,7 +9,7 @@ funding:
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.13.0"
flutter: ^3.19.0
dependencies:
collection: ^1.17.1