-
Notifications
You must be signed in to change notification settings - Fork 6k
[Web] Synthesize key events for modifier keys on pointer events. #36724
[Web] Synthesize key events for modifier keys on pointer events. #36724
Conversation
Hey @dkwingsmt !
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job! Everything so far looks great. Thank you for working on it.
Another task is to support all 3 event adapters: PointerEvent
, MouseEvent
, and TouchEvent
. For now you only supported the first.
The MouseEvent
and PointerEvent
are basically the same since the latter inherits the former. However, TouchEvent
uses the traditional xxxKey
methods. Combining with my suggestion of making a universal interface for KeyboardBinding
, maybe consider creating an interface class called KeyboardSynchronizingDelegate
.
timeStamp: Duration.zero, | ||
type: type, | ||
physical: kWebToPhysicalKey['ShiftLeft']!, | ||
logical: _kLogicalShiftLeft, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This magic value is concerning, but for now we don't have other ways than keeping a static map from physical keys to logical keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added _kPhysicalxxx
variables (similar to the _kLogicalxxx
ones) to centralize those magic values.
Maybe adding a generated enum in key_map.g.dart
could help to not dissiminate those magic values and might make it possible to rely on const variables?
@@ -152,6 +152,35 @@ class KeyboardBinding { | |||
_converter = KeyboardConverter(_onKeyData, onMacOs: operatingSystem == OperatingSystem.macOs); | |||
} | |||
|
|||
// Synthesize shift key up or down event only when the known pressing state is different. | |||
void synthesizeShiftKeyIfNeeded(ui.KeyEventType type) { | |||
// TODO(bleroux): should we take care of shift left AND shift right? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
Let's use a "least event dispatched" strategy:
- If the true state is pressed, and neither key is pressed, press the left key.
- If the true state is not pressed, and any key is pressed, release these keys.
- Otherwise, dispatch no events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -152,6 +152,35 @@ class KeyboardBinding { | |||
_converter = KeyboardConverter(_onKeyData, onMacOs: operatingSystem == OperatingSystem.macOs); | |||
} | |||
|
|||
// Synthesize shift key up or down event only when the known pressing state is different. | |||
void synthesizeShiftKeyIfNeeded(ui.KeyEventType type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make KeyboardBinding
's new public method handle all four modifiers? (Also see my review comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make KeyboardBinding's new public method handle all four modifiers? (Also see my #36724 (review))
I replaced it with synthesizeModifiersIfNeeded
with 4 bool parameters. I wanted to use something more generic but those bools make it clear which modifiers are supported for the moment.
While writing this I realize that this public method could be considered as a new API and updating it later might be a breaking change, is it? If yes, is what you suggested it to define an interface that will make it possible for this method to query the modifier state instead of receiving them?
18cd182
to
9ab52b6
Compare
Thanks!
While implementing this, I noticed that |
9ab52b6
to
df6220d
Compare
df6220d
to
14820cc
Compare
@dkwingsmt To make testing easier and make the dependence between |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for working on this!
…113847) * e27e1964f Add touch-input-test to test_suites.yaml (flutter/engine#36900) * b923707a3 [Impeller] remove solid stroke contents and allow strokes/vertices to use color sources (flutter/engine#36896) * 85e4fa84d Roll Dart SDK from e06db8e1b620 to 1d418b40d8bd (1 revision) (flutter/engine#36902) * 0b57b1cab Roll buildroot to a680bb1. (flutter/engine#36901) * f1634aa30 Roll Fuchsia Mac SDK from IdQEnRNQNY7ZrLZ04... to jB4jUAxe89I2A-yqv... (flutter/engine#36904) * f24ea1a04 Roll Fuchsia Linux SDK from g6-kU8so3PDiR1106... to mdl-0MUwR6uuQdKIm... (flutter/engine#36905) * 04fa86e1b Added integration test for platform channels on windows. (flutter/engine#36853) * 1dbf3ff76 Convert the executable directory path to UTF-8 on Windows (flutter/engine#36908) * c3d4fc953 Roll Dart SDK from 1d418b40d8bd to f1d4c7c808bd (2 revisions) (flutter/engine#36913) * 51b66c968 [Web] Synthesize key events for shift key on pointer events. (flutter/engine#36724) * 584fffb67 Roll Fuchsia Mac SDK from jB4jUAxe89I2A-yqv... to fcFu9Z2KJH6oQvHnG... (flutter/engine#36919) * 4369421b8 Roll Fuchsia Linux SDK from mdl-0MUwR6uuQdKIm... to NqPnoRHl3WYqH3SrC... (flutter/engine#36920) * d6d38abb2 [Impeller] fix null geometry (flutter/engine#36922) * d7f987ee3 [Impeller] Eliminate unused shader output (flutter/engine#36923) * c255470e7 Roll Dart SDK from f1d4c7c808bd to eafe0119c9f5 (2 revisions) (flutter/engine#36925) * 224a3def0 Restore support for building the web SDK without a prebuilt Dart SDK (flutter/engine#36926) * c7c21e56f Re-landing Robolectric 4.8.1 (flutter/engine#34272) * ab9802379 Roll libtess2 to 725e5e08ec8751477565f1d603fd7eb9058c277c (flutter/engine#36928) * 95e937a44 Revert "Roll libtess2 to 725e5e08ec8751477565f1d603fd7eb9058c277c (#36928)" (flutter/engine#36932) * 83092c04c Revert Dart SDK to 2.19.0-324.0.dev (flutter/engine#36930)
Description
This PR implements a way to synchronize modifier keys state based on pointer data.
This is a web only implementation to discuss the implementation choice. It might leads to non-WIP PRs for each platforms.
What problem does it solve?
Engine and framework communicate to maintain information about the current keyboard state.
When a Flutter window lost the main focus, it has no way to be notified of modifier keys state changes which leads to possible bugs such as flutter/flutter#112488.
Implementation
The implementation is based on @dkwingsmt insights from flutter/flutter#112488 (comment) :
"
Notes:
"
Related Issue
Fixes flutter/flutter#112488
flutter/flutter#115066
Tests
Adds 4 tests to validate that key up and key down events are synthesized if needed for the main modifiers (Alt, Ctrl, Meta, Shift).