Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@dkwingsmt
Copy link
Contributor

@dkwingsmt dkwingsmt commented Jan 6, 2021

Description

This PR is part of Hardware Keyboard project, specifically the embedder API, dart:ui API, and Web engine parts. The embedder and dart:ui parts are the foundation to other engine changes, while Web is required to change simultaneously for the API mirroring check.

The hardware keyboard API requires each platform to convert native events to "key data" that meets Flutter's specification and send them via the embedder API. The framework is then able to receive ui.KeyDatas in a regular, unified form, and perform the simplest 1-to-1 conversion into KeyEvent (to be added) and assertions.

The key event model is described at here. Simply put,

  • Key events are categorized into down, up, and repeat
  • A key press always starts with a down, goes through zero or more repeats, then ends with an up.
  • All events throughout the press contains the same physical key and logical key.
  • Missing native down or up events will be synthesized to guarantee the regularity.

Public API changes

This PR adds the following APIs to dart:ui:

  • enum KeyChange
  • class KeyData
  • typedef KeyDataCallback
  • property PlatformDispatcher.onKeyData
  • property SingletonFlutterWindow.onKeyData

This PR adds the following APIs to embedder.h:

  • enum FlutterKeyEventKind
  • struct FlutterKeyEvent
  • function FlutterEngineSendKeyEvent
  • typedef FlutterEngineSendKeyEventFnPtr
  • property FlutterEngineProcTable.SendKeyEvent

Although the key mapping file claims to be auto-generated, the codegen script is not checked in until flutter/flutter#73440.

Related Issues

Tests

I added the following tests:

For web engine:

  • Single key press, repeat, and release
  • Release modifier during a repeated sequence
  • Distinguish between left and right modifiers
  • Distinguish between normal and numpad digits
  • Prevents default when pressing Tab
  • Dead keys are distinguishable
  • Duplicate down is ignored
  • Duplicate ups are skipped
  • Conflict from multiple keyboards do not crash
  • CapsLock down synthesizes an immediate cancel on macOS
  • CapsLock behaves normally on non-macOS
  • Key guards: key down events are guarded
  • Key guards: key repeated down events refreshes guards
  • Key guards: cleared by keyups
  • Lock flags of other keys
  • Deduce modifier key cancel from modifier field

For embedder:

  • KeyDataIsCorrectlySerialized
  • KeyDataResponseIsCorrectlyInvoked

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the contributor guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the C++, Objective-C, Java style guides for the engine.
  • I read the tree hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation.
  • All existing and new tests are passing.
  • I am willing to follow-up on review comments in a timely manner.

Reviewer Checklist

Breaking Change

Did any tests fail when you ran them? Please read handling breaking changes.

@dkwingsmt dkwingsmt marked this pull request as ready for review January 7, 2021 01:33
@chinmaygarde chinmaygarde added the platform-web Code specifically for the web engine label Jan 7, 2021
@dkwingsmt dkwingsmt changed the title Hardware keyboard: Web Hardware keyboard: Web, embedder, and dart:ui Jan 8, 2021
@dkwingsmt
Copy link
Contributor Author

cc @gspencergoog

@ferhatb ferhatb requested a review from mdebbar January 8, 2021 20:19
Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect to see tests for the new embedder APIs (i.e., changes in embedder/test/) as part of this.

typedef struct {
/// The size of this struct. Must be sizeof(FlutterKeyEvent).
size_t struct_size;
// Timestamp in microseconds.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should be very clear about the requirements here. E.g., is using a monotonic clock a requirement, or is it okay for later events to have earlier timestamps when there's a time change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the time stamp of key events are defined as FlutterEngineGetCurrentTime. Currently I'm using as much time from native as possible in my PRs, wondering if it might provide extra precision or information to applications with certain requirement. Do you recommend me to switch to FlutterEngineGetCurrentTime?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not if we don't need it; I just think we should be explicit about what is (or isn't required). If we're okay with native event time, we should say that.

Is it the case that Flutter itself will be fine with non-monotonic event times?

uint64_t physical;
// The logical key of the event, usually the effect of the key without
// modifier, but might include modifier if the information is not available.
// Can be 0 for empty.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not obvious what this means exactly; what is the definitive source of numbers for logical keys?

Since this API surface is intended for use by third-party developers as well, it's important not to assume too much context in the comments.

bool _onKeyData(ui.KeyData data) {
bool? result;
EnginePlatformDispatcher.instance.invokeOnKeyData(data,
(bool handled) { result = handled; });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this callback called synchronously? I'm worried that _onKeyData may return before the callback gets a chance to update result.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is supposed to. If the code is returned before the handler is called, result will be null and the code will throw on the ! of the return statement. Let me add a comment to explain it.

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes all LGTM!

@dkwingsmt dkwingsmt added the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Jan 28, 2021
@fluttergithubbot fluttergithubbot merged commit d325ca7 into flutter:master Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 29, 2021
hjfreyer pushed a commit to hjfreyer/engine that referenced this pull request Mar 22, 2021
@dkwingsmt dkwingsmt deleted the keyboard-web branch January 6, 2022 01:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

affects: text input cla: yes platform-ios platform-web Code specifically for the web engine waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants