From 3ef32f040765f6da3e5ea94b4471d90e0fae3081 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Fri, 13 Oct 2023 17:25:18 -0700 Subject: [PATCH] Change some usage of RawKeyEvent to KeyEvent in preparation for deprecation (#136420) ## Description This converts some usages of `RawKeyEvent` to `KeyEvent` to prepare the repo for deprecation of `RawKeyEvent`, and swaps out the `raw_keyboard.dart` manual test for `hardware_keyboard.dart`. ## Related Issues - https://github.com/flutter/flutter/issues/136419 ## Tests - Just refactoring code, no semantic changes. --- dev/manual_tests/lib/focus.dart | 11 +- dev/manual_tests/lib/hardware_keyboard.dart | 94 +++++++++++ dev/manual_tests/lib/raw_keyboard.dart | 152 ------------------ .../keyboard_key/logical_keyboard_key.0.dart | 4 +- .../keyboard_key/physical_keyboard_key.0.dart | 4 +- .../widgets/focus_manager/focus_node.0.dart | 6 +- .../api/lib/widgets/focus_scope/focus.0.dart | 6 +- 7 files changed, 110 insertions(+), 167 deletions(-) create mode 100644 dev/manual_tests/lib/hardware_keyboard.dart delete mode 100644 dev/manual_tests/lib/raw_keyboard.dart diff --git a/dev/manual_tests/lib/focus.dart b/dev/manual_tests/lib/focus.dart index 4c93af35d7..6680909e45 100644 --- a/dev/manual_tests/lib/focus.dart +++ b/dev/manual_tests/lib/focus.dart @@ -91,13 +91,14 @@ class _FocusDemoState extends State { super.dispose(); } - KeyEventResult _handleKeyPress(FocusNode node, RawKeyEvent event) { - if (event is RawKeyDownEvent) { + KeyEventResult _handleKeyPress(FocusNode node, KeyEvent event) { + if (event is KeyDownEvent) { print('Scope got key event: ${event.logicalKey}, $node'); - print('Keys down: ${RawKeyboard.instance.keysPressed}'); + print('Keys down: ${HardwareKeyboard.instance.logicalKeysPressed}'); if (event.logicalKey == LogicalKeyboardKey.tab) { debugDumpFocusTree(); - if (event.isShiftPressed) { + if (HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftLeft) + || HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftRight)) { print('Moving to previous.'); node.previousFocus(); return KeyEventResult.handled; @@ -135,7 +136,7 @@ class _FocusDemoState extends State { policy: ReadingOrderTraversalPolicy(), child: FocusScope( debugLabel: 'Scope', - onKey: _handleKeyPress, + onKeyEvent: _handleKeyPress, autofocus: true, child: DefaultTextStyle( style: textTheme.headlineMedium!, diff --git a/dev/manual_tests/lib/hardware_keyboard.dart b/dev/manual_tests/lib/hardware_keyboard.dart new file mode 100644 index 0000000000..e841011ca2 --- /dev/null +++ b/dev/manual_tests/lib/hardware_keyboard.dart @@ -0,0 +1,94 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +void main() { + runApp(MaterialApp( + title: 'Hardware Key Demo', + home: Scaffold( + appBar: AppBar( + title: const Text('Hardware Key Demo'), + ), + body: const Center( + child: HardwareKeyboardDemo(), + ), + ), + )); +} + +class HardwareKeyboardDemo extends StatefulWidget { + const HardwareKeyboardDemo({super.key}); + + @override + State createState() => _HardwareKeyboardDemoState(); +} + +class _HardwareKeyboardDemoState extends State { + final FocusNode _focusNode = FocusNode(); + KeyEvent? _event; + + @override + void dispose() { + _focusNode.dispose(); + super.dispose(); + } + + KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) { + setState(() { + _event = event; + }); + return KeyEventResult.ignored; + } + + @override + Widget build(BuildContext context) { + final TextTheme textTheme = Theme.of(context).textTheme; + return Focus( + focusNode: _focusNode, + onKeyEvent: _handleKeyEvent, + autofocus: true, + child: AnimatedBuilder( + animation: _focusNode, + builder: (BuildContext context, Widget? child) { + if (!_focusNode.hasFocus) { + return GestureDetector( + onTap: () { + _focusNode.requestFocus(); + }, + child: Text('Tap to focus', style: textTheme.headlineMedium), + ); + } + + if (_event == null) { + return Text('Press a key', style: textTheme.headlineMedium); + } + + final List dataText = [ + Text('${_event.runtimeType}'), + if (_event?.character?.isNotEmpty ?? false) Text('character produced: "${_event?.character}"'), + ]; + dataText.add(Text('logical: ${_event?.logicalKey}')); + dataText.add(Text('physical: ${_event?.physicalKey}')); + if (_event?.character != null) { + dataText.add(Text('character: ${_event?.character}')); + } + final List pressed = ['Pressed:']; + for (final LogicalKeyboardKey key in HardwareKeyboard.instance.logicalKeysPressed) { + pressed.add(key.debugName!); + } + dataText.add(Text(pressed.join(' '))); + return DefaultTextStyle( + style: textTheme.titleMedium!, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: dataText, + ), + ); + }, + ), + ); + } +} diff --git a/dev/manual_tests/lib/raw_keyboard.dart b/dev/manual_tests/lib/raw_keyboard.dart deleted file mode 100644 index 55cd56074f..0000000000 --- a/dev/manual_tests/lib/raw_keyboard.dart +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -void main() { - runApp(MaterialApp( - title: 'Hardware Key Demo', - home: Scaffold( - appBar: AppBar( - title: const Text('Hardware Key Demo'), - ), - body: const Center( - child: RawKeyboardDemo(), - ), - ), - )); -} - -class RawKeyboardDemo extends StatefulWidget { - const RawKeyboardDemo({super.key}); - - @override - State createState() => _HardwareKeyDemoState(); -} - -class _HardwareKeyDemoState extends State { - final FocusNode _focusNode = FocusNode(); - RawKeyEvent? _event; - - @override - void dispose() { - _focusNode.dispose(); - super.dispose(); - } - - KeyEventResult _handleKeyEvent(FocusNode node, RawKeyEvent event) { - setState(() { - _event = event; - }); - return KeyEventResult.ignored; - } - - String _asHex(int value) => '0x${value.toRadixString(16)}'; - - String _getEnumName(dynamic enumItem) { - final String name = '$enumItem'; - final int index = name.indexOf('.'); - return index == -1 ? name : name.substring(index + 1); - } - - @override - Widget build(BuildContext context) { - final TextTheme textTheme = Theme.of(context).textTheme; - return Focus( - focusNode: _focusNode, - onKey: _handleKeyEvent, - autofocus: true, - child: AnimatedBuilder( - animation: _focusNode, - builder: (BuildContext context, Widget? child) { - if (!_focusNode.hasFocus) { - return GestureDetector( - onTap: () { - _focusNode.requestFocus(); - }, - child: Text('Tap to focus', style: textTheme.headlineMedium), - ); - } - - if (_event == null) { - return Text('Press a key', style: textTheme.headlineMedium); - } - - final RawKeyEventData? data = _event?.data; - final String? modifierList = data?.modifiersPressed.keys.map(_getEnumName).join(', ').replaceAll('Modifier', ''); - final List dataText = [ - Text('${_event.runtimeType}'), - if (_event?.character?.isNotEmpty ?? false) Text('character produced: "${_event?.character}"'), - Text('modifiers set: $modifierList'), - ]; - if (data is RawKeyEventDataAndroid) { - const int combiningCharacterMask = 0x7fffffff; - final String codePointChar = String.fromCharCode(combiningCharacterMask & data.codePoint); - dataText.add(Text('codePoint: ${data.codePoint} (${_asHex(data.codePoint)}: $codePointChar)')); - final String plainCodePointChar = String.fromCharCode(combiningCharacterMask & data.plainCodePoint); - dataText.add(Text('plainCodePoint: ${data.plainCodePoint} (${_asHex(data.plainCodePoint)}: $plainCodePointChar)')); - dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); - dataText.add(Text('scanCode: ${data.scanCode} (${_asHex(data.scanCode)})')); - dataText.add(Text('metaState: ${data.metaState} (${_asHex(data.metaState)})')); - dataText.add(Text('source: ${data.eventSource} (${_asHex(data.eventSource)})')); - dataText.add(Text('vendorId: ${data.vendorId} (${_asHex(data.vendorId)})')); - dataText.add(Text('productId: ${data.productId} (${_asHex(data.productId)})')); - dataText.add(Text('flags: ${data.flags} (${_asHex(data.flags)})')); - dataText.add(Text('repeatCount: ${data.repeatCount} (${_asHex(data.repeatCount)})')); - } else if (data is RawKeyEventDataFuchsia) { - dataText.add(Text('codePoint: ${data.codePoint} (${_asHex(data.codePoint)})')); - dataText.add(Text('hidUsage: ${data.hidUsage} (${_asHex(data.hidUsage)})')); - dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); - } else if (data is RawKeyEventDataMacOs) { - dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); - dataText.add(Text('characters: ${data.characters}')); - dataText.add(Text('charactersIgnoringModifiers: ${data.charactersIgnoringModifiers}')); - dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); - } else if (data is RawKeyEventDataLinux) { - dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); - dataText.add(Text('scanCode: ${data.scanCode}')); - dataText.add(Text('unicodeScalarValues: ${data.unicodeScalarValues}')); - dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); - } else if (data is RawKeyEventDataWindows) { - dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); - dataText.add(Text('scanCode: ${data.scanCode}')); - dataText.add(Text('characterCodePoint: ${data.characterCodePoint}')); - dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); - } else if (data is RawKeyEventDataWeb) { - dataText.add(Text('key: ${data.key}')); - dataText.add(Text('code: ${data.code}')); - dataText.add(Text('metaState: ${data.metaState} (${_asHex(data.metaState)})')); - } - dataText.add(Text('logical: ${_event?.logicalKey}')); - dataText.add(Text('physical: ${_event?.physicalKey}')); - if (_event?.character != null) { - dataText.add(Text('character: ${_event?.character}')); - } - for (final ModifierKey modifier in data!.modifiersPressed.keys) { - for (final KeyboardSide side in KeyboardSide.values) { - if (data.isModifierPressed(modifier, side: side)) { - dataText.add( - Text('${_getEnumName(side)} ${_getEnumName(modifier).replaceAll('Modifier', '')} pressed'), - ); - } - } - } - final List pressed = ['Pressed:']; - for (final LogicalKeyboardKey key in RawKeyboard.instance.keysPressed) { - pressed.add(key.debugName!); - } - dataText.add(Text(pressed.join(' '))); - return DefaultTextStyle( - style: textTheme.titleMedium!, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: dataText, - ), - ); - }, - ), - ); - } -} diff --git a/examples/api/lib/services/keyboard_key/logical_keyboard_key.0.dart b/examples/api/lib/services/keyboard_key/logical_keyboard_key.0.dart index 77b09d3038..4dc3d8febd 100644 --- a/examples/api/lib/services/keyboard_key/logical_keyboard_key.0.dart +++ b/examples/api/lib/services/keyboard_key/logical_keyboard_key.0.dart @@ -46,7 +46,7 @@ class _MyKeyExampleState extends State { // Handles the key events from the Focus widget and updates the // _message. - KeyEventResult _handleKeyEvent(FocusNode node, RawKeyEvent event) { + KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) { setState(() { if (event.logicalKey == LogicalKeyboardKey.keyQ) { _message = 'Pressed the "Q" key!'; @@ -73,7 +73,7 @@ class _MyKeyExampleState extends State { style: textTheme.headlineMedium!, child: Focus( focusNode: _focusNode, - onKey: _handleKeyEvent, + onKeyEvent: _handleKeyEvent, child: ListenableBuilder( listenable: _focusNode, builder: (BuildContext context, Widget? child) { diff --git a/examples/api/lib/services/keyboard_key/physical_keyboard_key.0.dart b/examples/api/lib/services/keyboard_key/physical_keyboard_key.0.dart index 6b569409bb..5e1d635b42 100644 --- a/examples/api/lib/services/keyboard_key/physical_keyboard_key.0.dart +++ b/examples/api/lib/services/keyboard_key/physical_keyboard_key.0.dart @@ -46,7 +46,7 @@ class _MyPhysicalKeyExampleState extends State { // Handles the key events from the RawKeyboardListener and update the // _message. - KeyEventResult _handleKeyEvent(FocusNode node, RawKeyEvent event) { + KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) { setState(() { if (event.physicalKey == PhysicalKeyboardKey.keyA) { _message = 'Pressed the key next to CAPS LOCK!'; @@ -73,7 +73,7 @@ class _MyPhysicalKeyExampleState extends State { style: textTheme.headlineMedium!, child: Focus( focusNode: _focusNode, - onKey: _handleKeyEvent, + onKeyEvent: _handleKeyEvent, child: ListenableBuilder( listenable: _focusNode, builder: (BuildContext context, Widget? child) { diff --git a/examples/api/lib/widgets/focus_manager/focus_node.0.dart b/examples/api/lib/widgets/focus_manager/focus_node.0.dart index 8069a7e071..8d52b03c85 100644 --- a/examples/api/lib/widgets/focus_manager/focus_node.0.dart +++ b/examples/api/lib/widgets/focus_manager/focus_node.0.dart @@ -41,7 +41,7 @@ class _ColorfulButtonState extends State { super.initState(); _node = FocusNode(debugLabel: 'Button'); _node.addListener(_handleFocusChange); - _nodeAttachment = _node.attach(context, onKey: _handleKeyPress); + _nodeAttachment = _node.attach(context, onKeyEvent: _handleKeyPress); } void _handleFocusChange() { @@ -52,8 +52,8 @@ class _ColorfulButtonState extends State { } } - KeyEventResult _handleKeyPress(FocusNode node, RawKeyEvent event) { - if (event is RawKeyDownEvent) { + KeyEventResult _handleKeyPress(FocusNode node, KeyEvent event) { + if (event is KeyDownEvent) { debugPrint('Focus node ${node.debugLabel} got key event: ${event.logicalKey}'); if (event.logicalKey == LogicalKeyboardKey.keyR) { debugPrint('Changing color to red.'); diff --git a/examples/api/lib/widgets/focus_scope/focus.0.dart b/examples/api/lib/widgets/focus_scope/focus.0.dart index f62d5de6ea..37bafe783d 100644 --- a/examples/api/lib/widgets/focus_scope/focus.0.dart +++ b/examples/api/lib/widgets/focus_scope/focus.0.dart @@ -33,8 +33,8 @@ class FocusExample extends StatefulWidget { class _FocusExampleState extends State { Color _color = Colors.white; - KeyEventResult _handleKeyPress(FocusNode node, RawKeyEvent event) { - if (event is RawKeyDownEvent) { + KeyEventResult _handleKeyPress(FocusNode node, KeyEvent event) { + if (event is KeyDownEvent) { debugPrint('Focus node ${node.debugLabel} got key event: ${event.logicalKey}'); if (event.logicalKey == LogicalKeyboardKey.keyR) { debugPrint('Changing color to red.'); @@ -68,7 +68,7 @@ class _FocusExampleState extends State { child: DefaultTextStyle( style: textTheme.headlineMedium!, child: Focus( - onKey: _handleKeyPress, + onKeyEvent: _handleKeyPress, debugLabel: 'Button', child: Builder( builder: (BuildContext context) {