flutter / flutter/flutter

[BUG] [WEB] `KeyUpEvent` is synthesized too eagerly when combining the Meta key with multiple non-modifier keys

Open
#182,775 0 comments 3 reactions 0 assignees View on GitHub
a: text input engine P2 team-web triaged-web
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

## Description

While PR #180692 successfully fixed issue #162305 (where the web embedder synthesized key up events too eagerly for normal typing / game control), a limitation remains when the `Meta` key (`Cmd` on Mac) is involved.

Because the key guard mechanism in the web embedder is still required and active when the Meta key is pressed, pressing multiple non-modifier keys simultaneously alongside it causes the guard to misbehave. Only the last pressed non-modifier key sends repeated events, which leads the framework to eventually (and incorrectly) synthesize key up events for the other physically held non-modifier keys.

*Note: This specific behavior was isolated to the `Meta` key during debugging in the PR, rather than all modifier keys.*

## Steps to reproduce

Using the `KeyboardListener` or `Focus.onKeyEvent` APIs on a Web build (JS or WASM):

1. Press and hold the `Cmd` (Meta) key.
2. Press and hold `[j]`.
3. Press and hold `[k]`.
4. Wait for over 1.5 seconds (or `> _kKeydownCancelDurationMac`).

You may use the sample app from the linked issue to debug this too.

## Expected results

The framework should recognize that `Cmd`, `j`, and `k` are all still actively pressed. No `KeyUpEvent` should be fired until the user physically releases the keys.

* Expected event stream: `Cmd down`, `j down`, `k down`

## Actual results

The web embedder synthesizes a premature key up event for the first non-modifier key (`j`), even though the user is still physically holding the key down.

* Actual event stream: `Cmd down`, `j down`, `k down`, **`j up` (synthesized)**

## Context and Related Issues

* This is a known limitation documented during the review of **PR #180692**: [[Fix issue where web embedder is synthesizing key up events too eagerly](https://github.com/flutter/flutter/pull/180692)](https://github.com/flutter/flutter/pull/180692).
* Related to the original **Issue #162305**: [[BUG] [WEB] `KeyboardListener`'s and `Focus.onKeyEvent`'s `KeyUpEvent` do not work correctly in JS and WASM builds](https://www.google.com/search?q=%5Bhttps://github.com/flutter/flutter/issues/162305%5D(https://github.com/flutter/flutter/issues/162305)).

A potential workaround discussed was to delay the synthesizing of non-modifier keys until the meta-key is released entirely, but this risks keeping the framework out of sync for non-modifier keys until the modifier is released. Another suggested idea was discussed where receiving repeated key-up events for *any* non-modifier key would also delay (reset guards) the synthesizing of *all* non-modifier key-up events. Both ideas are only slightly better than the current behavior, as its impossible to get a "perfect" solutions (because browser is not sending the key-up events at all when meta key is involved).

Contributor guide

Open the contributing guide

Research direction

Start with the web embedder key-guard handling used by KeyboardListener and Focus.onKeyEvent, then reproduce the Cmd+j+k sequence in a JS or WASM Web build, using the sample app if available. Compare the event stream after the keydown cancellation duration with the expected Cmd down, j down, k down sequence; done means no premature j KeyUpEvent while the keys remain held.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, javascript, wasm
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.