Unverified Commit 781c3599 authored by Tong Mu's avatar Tong Mu Committed by GitHub

RawKeyEventData classes support diagnostic and equality (#86679)

This PR changes RawKeyEventData so that they use Diagnosticable to construct toString, and use operator== and hashCode to compare.
parent c4cf6f18
......@@ -115,7 +115,7 @@ enum ModifierKey {
/// reference to [RawKeyEventData] subclasses.
/// * [RawKeyboard], which uses these interfaces to expose key data.
@immutable
abstract class RawKeyEventData {
abstract class RawKeyEventData with Diagnosticable {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const RawKeyEventData();
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -286,6 +287,42 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
}
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<int>('flags', flags));
properties.add(DiagnosticsProperty<int>('codePoint', codePoint));
properties.add(DiagnosticsProperty<int>('plainCodePoint', plainCodePoint));
properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
properties.add(DiagnosticsProperty<int>('scanCode', scanCode));
properties.add(DiagnosticsProperty<int>('metaState', metaState));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataAndroid
&& other.flags == flags
&& other.codePoint == codePoint
&& other.plainCodePoint == plainCodePoint
&& other.keyCode == keyCode
&& other.scanCode == scanCode
&& other.metaState == metaState;
}
@override
int get hashCode => hashValues(
flags,
codePoint,
plainCodePoint,
keyCode,
scanCode,
metaState,
);
// Modifier key masks.
/// No modifier keys are pressed in the [metaState] field.
......@@ -430,11 +467,4 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
/// it's much easier to use [isModifierPressed] if you just want to know if
/// a modifier is pressed.
static const int modifierScrollLock = 0x400000;
@override
String toString() {
return '${objectRuntimeType(this, 'RawKeyEventDataAndroid')}(keyLabel: $keyLabel flags: $flags, codePoint: $codePoint, '
'keyCode: $keyCode, scanCode: $scanCode, metaState: $metaState, '
'modifiers down: $modifiersPressed)';
}
}
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -159,6 +160,33 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
}
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<int>('hidUsage', hidUsage));
properties.add(DiagnosticsProperty<int>('codePoint', codePoint));
properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataFuchsia
&& other.hidUsage == hidUsage
&& other.codePoint == codePoint
&& other.modifiers == modifiers;
}
@override
int get hashCode => hashValues(
hidUsage,
codePoint,
modifiers,
);
// Keyboard modifier masks for Fuchsia modifiers.
/// The [modifiers] field indicates that no modifier keys are pressed if it
......@@ -272,10 +300,4 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
/// it's much easier to use [isModifierPressed] if you just want to know if
/// a modifier is pressed.
static const int modifierMeta = modifierLeftMeta | modifierRightMeta;
@override
String toString() {
return '${objectRuntimeType(this, 'RawKeyEventDataFuchsia')}(hidUsage: $hidUsage, codePoint: $codePoint, modifiers: $modifiers, '
'modifiers down: $modifiersPressed)';
}
}
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
import 'keyboard_key.dart';
......@@ -253,6 +255,36 @@ class RawKeyEventDataIos extends RawKeyEventData {
}
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<String>('characters', characters));
properties.add(DiagnosticsProperty<String>('charactersIgnoringModifiers', charactersIgnoringModifiers));
properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataIos
&& other.characters == characters
&& other.charactersIgnoringModifiers == charactersIgnoringModifiers
&& other.keyCode == keyCode
&& other.modifiers == modifiers;
}
@override
int get hashCode => hashValues(
characters,
charactersIgnoringModifiers,
keyCode,
modifiers,
);
// Modifier key masks. See Apple's UIKey documentation
// https://developer.apple.com/documentation/uikit/uikeymodifierflags?language=objc
// https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-86/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h.auto.html
......@@ -361,11 +393,4 @@ class RawKeyEventDataIos extends RawKeyEventData {
/// applications to mask off the device-dependent modifier flags, including
/// event coalescing information.
static const int deviceIndependentMask = 0xffff0000;
@override
String toString() {
return '${objectRuntimeType(this, 'RawKeyEventDataIos')}(keyLabel: $keyLabel, keyCode: $keyCode, characters: $characters,'
' unmodifiedCharacters: $charactersIgnoringModifiers, modifiers: $modifiers, '
'modifiers down: $modifiersPressed)';
}
}
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -117,11 +118,40 @@ class RawKeyEventDataLinux extends RawKeyEventData {
}
@override
String toString() {
return '${objectRuntimeType(this, 'RawKeyEventDataLinux')}(keyLabel: $keyLabel, keyCode: $keyCode, scanCode: $scanCode,'
' unicodeScalarValues: $unicodeScalarValues, modifiers: $modifiers, '
'modifiers down: $modifiersPressed)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<String>('toolkit', keyHelper.debugToolkit));
properties.add(DiagnosticsProperty<int>('unicodeScalarValues', unicodeScalarValues));
properties.add(DiagnosticsProperty<int>('scanCode', scanCode));
properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
properties.add(DiagnosticsProperty<bool>('isDown', isDown));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataLinux
&& other.keyHelper.runtimeType == keyHelper.runtimeType
&& other.unicodeScalarValues == unicodeScalarValues
&& other.scanCode == scanCode
&& other.keyCode == keyCode
&& other.modifiers == modifiers
&& other.isDown == isDown;
}
@override
int get hashCode => hashValues(
keyHelper.runtimeType,
unicodeScalarValues,
scanCode,
keyCode,
modifiers,
isDown,
);
}
/// Abstract class for window-specific key mappings.
......@@ -141,6 +171,11 @@ abstract class KeyHelper {
}
}
/// Returns the name for the toolkit.
///
/// This is used in debug mode to generate readable string.
String get debugToolkit;
/// Returns a [KeyboardSide] enum value that describes which side or sides of
/// the given keyboard modifier key were pressed at the time of this event.
KeyboardSide getModifierSide(ModifierKey key);
......@@ -204,6 +239,9 @@ class GLFWKeyHelper implements KeyHelper {
/// {@macro flutter.services.GLFWKeyHelper.modifierCapsLock}
static const int modifierNumericPad = 0x0020;
@override
String get debugToolkit => 'GLFW';
int _mergeModifiers({required int modifiers, required int keyCode, required bool isDown}) {
// GLFW Key codes for modifier keys.
const int shiftLeftKeyCode = 340;
......@@ -343,6 +381,9 @@ class GtkKeyHelper implements KeyHelper {
/// {@macro flutter.services.GtkKeyHelper.modifierShift}
static const int modifierMeta = 1 << 26;
@override
String get debugToolkit => 'GTK';
int _mergeModifiers({required int modifiers, required int keyCode, required bool isDown}) {
// GTK Key codes for modifier keys.
const int shiftLeftKeyCode = 0xffe1;
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -216,6 +217,36 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
return logicalKey != LogicalKeyboardKey.fn;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<String>('characters', characters));
properties.add(DiagnosticsProperty<String>('charactersIgnoringModifiers', charactersIgnoringModifiers));
properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataMacOs
&& other.characters == characters
&& other.charactersIgnoringModifiers == charactersIgnoringModifiers
&& other.keyCode == keyCode
&& other.modifiers == modifiers;
}
@override
int get hashCode => hashValues(
characters,
charactersIgnoringModifiers,
keyCode,
modifiers,
);
/// Returns true if the given label represents an unprintable key.
///
/// Examples of unprintable keys are "NSUpArrowFunctionKey = 0xF700"
......@@ -341,11 +372,4 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
/// applications to mask off the device-dependent modifier flags, including
/// event coalescing information.
static const int deviceIndependentMask = 0xffff0000;
@override
String toString() {
return '${objectRuntimeType(this, 'RawKeyEventDataMacOs')}(keyLabel: $keyLabel, keyCode: $keyCode, characters: $characters,'
' unmodifiedCharacters: $charactersIgnoringModifiers, modifiers: $modifiers, '
'modifiers down: $modifiersPressed)';
}
}
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -29,18 +30,28 @@ class RawKeyEventDataWeb extends RawKeyEventData {
/// The `KeyboardEvent.code` corresponding to this event.
///
/// The [code] represents a physical key on the keyboard, a value that isn't
/// altered by keyboard layout or the state of the modifier keys.
///
/// See <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code>
/// for more information.
final String code;
/// The `KeyboardEvent.key` corresponding to this event.
///
/// The [key] represents the key pressed by the user, taking into
/// consideration the state of modifier keys such as Shift as well as the
/// keyboard locale and layout.
///
/// See <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key>
/// for more information.
final String key;
/// The `KeyboardEvent.location` corresponding to this event.
///
/// The [location] represents the location of the key on the keyboard or other
/// input device, such as left or right modifier keys, or Numpad keys.
///
/// See <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/location>
/// for more information.
final int location;
......@@ -126,6 +137,36 @@ class RawKeyEventDataWeb extends RawKeyEventData {
return KeyboardSide.any;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<String>('code', code));
properties.add(DiagnosticsProperty<String>('key', key));
properties.add(DiagnosticsProperty<int>('location', location));
properties.add(DiagnosticsProperty<int>('metaState', metaState));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataWeb
&& other.code == code
&& other.key == key
&& other.location == location
&& other.metaState == metaState;
}
@override
int get hashCode => hashValues(
code,
key,
location,
metaState,
);
// Modifier key masks.
/// No modifier keys are pressed in the [metaState] field.
......@@ -190,10 +231,4 @@ class RawKeyEventDataWeb extends RawKeyEventData {
/// it's much easier to use [isModifierPressed] if you just want to know if
/// a modifier is pressed.
static const int modifierScrollLock = 0x40;
@override
String toString() {
return '${objectRuntimeType(this, 'RawKeyEventDataWeb')}(keyLabel: $keyLabel, code: $code, '
'location: $location, metaState: $metaState, modifiers down: $modifiersPressed)';
}
}
......@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
import 'keyboard_key.dart';
import 'keyboard_maps.dart';
......@@ -197,6 +200,36 @@ class RawKeyEventDataWindows extends RawKeyEventData {
return keyCode != _vkProcessKey;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
properties.add(DiagnosticsProperty<int>('scanCode', scanCode));
properties.add(DiagnosticsProperty<int>('characterCodePoint', characterCodePoint));
properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is RawKeyEventDataWindows
&& other.keyCode == keyCode
&& other.scanCode == scanCode
&& other.characterCodePoint == characterCodePoint
&& other.modifiers == modifiers;
}
@override
int get hashCode => hashValues(
keyCode,
scanCode,
characterCodePoint,
modifiers,
);
// These are not the values defined by the Windows header for each modifier. Since they
// can't be packaged into a single int, we are re-defining them here to reduce the size
// of the message from the embedder. Embedders should map these values to the native key codes.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment