Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,6 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/initialization.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/js_interop/js_loader.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/js_interop/js_promise.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/key_map.g.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/keyboard.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/keyboard_binding.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/mouse_cursor.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/navigation.dart
Expand All @@ -1285,6 +1284,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/plugins.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/pointer_binding.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/pointer_converter.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/profiler.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/raw_keyboard.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/renderer.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/rrect_renderer.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/safe_browser_api.dart
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ export 'engine/initialization.dart';
export 'engine/js_interop/js_loader.dart';
export 'engine/js_interop/js_promise.dart';
export 'engine/key_map.g.dart';
export 'engine/keyboard.dart';
export 'engine/keyboard_binding.dart';
export 'engine/mouse_cursor.dart';
export 'engine/navigation/history.dart';
Expand All @@ -125,6 +124,7 @@ export 'engine/plugins.dart';
export 'engine/pointer_binding.dart';
export 'engine/pointer_converter.dart';
export 'engine/profiler.dart';
export 'engine/raw_keyboard.dart';
export 'engine/renderer.dart';
export 'engine/rrect_renderer.dart';
export 'engine/safe_browser_api.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/embedder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ class FlutterViewEmbedder {
}

PointerBinding.initInstance(glassPaneElement);
KeyboardBinding.initInstance(glassPaneElement);
KeyboardBinding.initInstance();

if (domWindow.visualViewport == null && isWebKit) {
// Older Safari versions sometimes give us bogus innerWidth/innerHeight
Expand Down
4 changes: 2 additions & 2 deletions lib/web_ui/lib/src/engine/initialization.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import 'dart:developer' as developer;
import 'package:ui/src/engine/assets.dart';
import 'package:ui/src/engine/browser_detection.dart';
import 'package:ui/src/engine/embedder.dart';
import 'package:ui/src/engine/keyboard.dart';
import 'package:ui/src/engine/mouse_cursor.dart';
import 'package:ui/src/engine/navigation.dart';
import 'package:ui/src/engine/platform_dispatcher.dart';
import 'package:ui/src/engine/platform_views/content_manager.dart';
import 'package:ui/src/engine/profiler.dart';
import 'package:ui/src/engine/raw_keyboard.dart';
import 'package:ui/src/engine/renderer.dart';
import 'package:ui/src/engine/safe_browser_api.dart';
import 'package:ui/src/engine/window.dart';
Expand Down Expand Up @@ -234,7 +234,7 @@ Future<void> initializeEngineUi() async {
}
_initializationState = DebugEngineInitializationState.initializingUi;

Keyboard.initialize(onMacOs: operatingSystem == OperatingSystem.macOs);
RawKeyboard.initialize(onMacOs: operatingSystem == OperatingSystem.macOs);
MouseCursor.initialize();
ensureFlutterViewEmbedderInitialized();
_initializationState = DebugEngineInitializationState.initialized;
Expand Down
11 changes: 6 additions & 5 deletions lib/web_ui/lib/src/engine/keyboard_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,25 @@ Duration _eventTimeStampToDuration(num milliseconds) {
}

class KeyboardBinding {
KeyboardBinding._(this.glassPaneElement) {
KeyboardBinding._() {
_setup();
}

/// The singleton instance of this object.
static KeyboardBinding? get instance => _instance;
static KeyboardBinding? _instance;

static void initInstance(DomElement glassPaneElement) {
static void initInstance() {
if (_instance == null) {
_instance = KeyboardBinding._(glassPaneElement);
_instance = KeyboardBinding._();
assert(() {
registerHotRestartListener(_instance!._reset);
return true;
}());
}
}

final DomElement glassPaneElement;
late KeyboardConverter _converter;
late final KeyboardConverter _converter;
final Map<String, DomEventListener> _listeners = <String, DomEventListener>{};

void _addEventListener(String eventName, DomEventListener handler) {
Expand Down Expand Up @@ -179,6 +178,7 @@ class FlutterHtmlKeyboardEvent {
String get type => _event.type;
String? get code => _event.code;
String? get key => _event.key;
int get keyCode => _event.keyCode;
bool? get repeat => _event.repeat;
int? get location => _event.location;
num? get timeStamp => _event.timeStamp;
Expand All @@ -189,6 +189,7 @@ class FlutterHtmlKeyboardEvent {

bool getModifierState(String key) => _event.getModifierState(key);
void preventDefault() => _event.preventDefault();
bool get defaultPrevented => _event.defaultPrevented;
}

// Reads [DomKeyboardEvent], then [dispatches ui.KeyData] accordingly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import 'dart:typed_data';

import '../engine.dart' show registerHotRestartListener;
import 'dom.dart';
import 'keyboard_binding.dart';
import 'platform_dispatcher.dart';
import 'safe_browser_api.dart';
import 'services.dart';

/// Provides keyboard bindings, such as the `flutter/keyevent` channel.
class Keyboard {
Keyboard._(this._onMacOs) {
class RawKeyboard {
RawKeyboard._(this._onMacOs) {
_keydownListener = allowInterop((DomEvent event) {
_handleHtmlEvent(event);
});
Expand All @@ -28,16 +29,16 @@ class Keyboard {
});
}

/// Initializes the [Keyboard] singleton.
/// Initializes the [RawKeyboard] singleton.
///
/// Use the [instance] getter to get the singleton after calling this method.
static void initialize({bool onMacOs = false}) {
_instance ??= Keyboard._(onMacOs);
_instance ??= RawKeyboard._(onMacOs);
}

/// The [Keyboard] singleton.
static Keyboard? get instance => _instance;
static Keyboard? _instance;
/// The [RawKeyboard] singleton.
static RawKeyboard? get instance => _instance;
static RawKeyboard? _instance;

/// A mapping of [KeyboardEvent.code] to [Timer].
///
Expand All @@ -48,7 +49,7 @@ class Keyboard {
DomEventListener? _keydownListener;
DomEventListener? _keyupListener;

/// Uninitializes the [Keyboard] singleton.
/// Uninitializes the [RawKeyboard] singleton.
///
/// After calling this method this object becomes unusable and [instance]
/// becomes `null`. Call [initialize] again to initialize a new singleton.
Expand Down Expand Up @@ -87,13 +88,13 @@ class Keyboard {
return _onMacOs;
}

void _handleHtmlEvent(DomEvent event) {
if (!domInstanceOfString(event, 'KeyboardEvent')) {
void _handleHtmlEvent(DomEvent domEvent) {
if (!domInstanceOfString(domEvent, 'KeyboardEvent')) {
return;
}

final DomKeyboardEvent keyboardEvent = event as DomKeyboardEvent;
final String timerKey = keyboardEvent.code!;
final FlutterHtmlKeyboardEvent event = FlutterHtmlKeyboardEvent(domEvent as DomKeyboardEvent);
final String timerKey = event.code!;

// Don't handle synthesizing a keyup event for modifier keys
if (!_isModifierKey(event) && _shouldDoKeyGuard()) {
Expand Down Expand Up @@ -126,11 +127,11 @@ class Keyboard {
final Map<String, dynamic> eventData = <String, dynamic>{
'type': event.type,
'keymap': 'web',
'code': keyboardEvent.code,
'key': keyboardEvent.key,
'location': keyboardEvent.location,
'code': event.code,
'key': event.key,
'location': event.location,
'metaState': _lastMetaState,
'keyCode': keyboardEvent.keyCode,
'keyCode': event.keyCode,
};

EnginePlatformDispatcher.instance.invokeOnPlatformMessage('flutter/keyevent',
Expand All @@ -147,7 +148,7 @@ class Keyboard {
);
}

void _synthesizeKeyup(DomKeyboardEvent event) {
void _synthesizeKeyup(FlutterHtmlKeyboardEvent event) {
final Map<String, dynamic> eventData = <String, dynamic>{
'type': 'keyup',
'keymap': 'web',
Expand Down Expand Up @@ -180,7 +181,7 @@ const int modifierCapsLock = 0x20;
const int modifierScrollLock = 0x40;

/// Creates a bitmask representing the meta state of the [event].
int _getMetaState(DomKeyboardEvent event) {
int _getMetaState(FlutterHtmlKeyboardEvent event) {
int metaState = _modifierNone;
if (event.getModifierState('Shift')) {
metaState |= _modifierShift;
Expand Down Expand Up @@ -212,15 +213,15 @@ int _getMetaState(DomKeyboardEvent event) {
///
/// Modifier keys are shift, alt, ctrl and meta/cmd/win. These are the keys used
/// to perform keyboard shortcuts (e.g. `cmd+c`, `cmd+l`).
bool _isModifierKey(DomKeyboardEvent event) {
bool _isModifierKey(FlutterHtmlKeyboardEvent event) {
final String key = event.key!;
return key == 'Meta' || key == 'Shift' || key == 'Alt' || key == 'Control';
}

/// Returns true if the [event] is been affects by any of the modifiers key
///
/// This is a strong indication that this key is been used for a shortcut
bool _isAffectedByModifiers(DomKeyboardEvent event) {
bool _isAffectedByModifiers(FlutterHtmlKeyboardEvent event) {
return event.ctrlKey || event.shiftKey || event.altKey || event.metaKey;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void testMain() {
expect(windowFlutterCanvasKit, isNull);

expect(findGlassPane(), isNull);
expect(Keyboard.instance, isNull);
expect(RawKeyboard.instance, isNull);
expect(MouseCursor.instance, isNull);
expect(KeyboardBinding.instance, isNull);
expect(PointerBinding.instance, isNull);
Expand All @@ -27,15 +27,15 @@ void testMain() {
expect(windowFlutterCanvasKit, isNotNull);

expect(findGlassPane(), isNull);
expect(Keyboard.instance, isNull);
expect(RawKeyboard.instance, isNull);
expect(MouseCursor.instance, isNull);
expect(KeyboardBinding.instance, isNull);
expect(PointerBinding.instance, isNull);

// Now UI should be taken over by Flutter.
await initializeEngineUi();
expect(findGlassPane(), isNotNull);
expect(Keyboard.instance, isNotNull);
expect(RawKeyboard.instance, isNotNull);
expect(MouseCursor.instance, isNotNull);
expect(KeyboardBinding.instance, isNotNull);
expect(PointerBinding.instance, isNotNull);
Expand Down
Loading