MicrosoftEdge / MicrosoftEdge/WebView2Feedback
[Problem/Bug]: KeyboardEvent repeat is false initially when holding down a key (and handling the first one in the desktop app)
@bradp0721 is already working on this.
Since Sep 26, 2024.
- Dominant language
- PowerShell
- Stars
- 526
- Forks
- 67
- PR merge metrics
- No merged PRs in 30d
Description
What happened?
My app handles KeyDown/KeyUp events. If it detects a key like F10, say, it sets e.Handled = true. If it detects that the key is being held down, it keeps Handled false.
When Handled is false, the webapp gets the keydown events, but the first handle that's called has e.repeat set to false for some reason. All subsequent logs due to the held down key have repeat correctly set to true.
This doesn't happen in my Electron app.
Importance
Moderate. My app's user experience is affected, but still usable.
Runtime Channel
Stable release (WebView2 Runtime)
Runtime Version
128.0.2739.67
SDK Version
1.0.2535.41
Framework
Winforms
Operating System
Windows 11
OS Version
22631.4037
Repro steps
If you open this Electron gist:
- hold down F10
- in the devtools, you'll see the capture and bubble handlers firing with logs indicating that
e.repeatis true. - In the WebView2 app, the first bubble/capture handlers have
e.repeatoffalseand then it gets set to true.
I can kind of repro in Edge when holding down the Space key on google.com:
execute this code in devtools:
window.document.body.addEventListener("keydown", (e) =>
{
handler(e, true);
}, true)
window.document.body.addEventListener("keydown", (e) =>
{
handler(e, false);
}, false)
function handler(e, isCapture)
{
console.log(`${Date.now()}: ${(isCapture ? "capture" : "bubble")} handler: ${e.key} ${e.type} repeat: ${e.repeat}`);
}
and see logs:
1726256395642: capture handler: keydown repeat: false
1726256395642: bubble handler: keydown repeat: false
1726256396144: capture handler: keydown repeat: true
1726256396144: bubble handler: keydown repeat: true
but the difference is that the desktop app is presumably not handling that first key press which is why repeat is false. In my app, I handle the first key press and only subsequent, repeated pressed I don't handle, so I'd expect the devtools in my app to say repeat is always true.
To repro:
- open WinForms sample app
- add this to AppStartPage.js:
window.document.body.addEventListener("keydown", (e) =>
{
handler(e, true);
}, true)
window.document.body.addEventListener("keydown", (e) =>
{
handler(e, false);
}, false)
function handler(e, isCapture)
{
console.log(`${Date.now()}: ${(isCapture ? "capture" : "bubble")} handler: ${e.key} ${e.type} repeat: ${e.repeat}`);
}
In BrowserForm.cs, since we don't have a built in way to tell if a key is held down, I had to add the following logic. Copy this code in:
private readonly Dictionary<Keys, bool> _keysDown = new Dictionary<Keys, bool>();
[LibraryImport("user32.dll")]
private static partial short GetKeyState(int key);
private void UpdateKeyStates()
{
foreach (KeyValuePair<Keys, bool> entry in _keysDown)
{
Keys key = entry.Key;
if (!IsKeyPressed(key))
{
_keysDown.Remove(key);
}
}
}
private bool IsKeyPressed(Keys key)
{
short state = GetKeyState((int)key);
return state < 0; // the high-order bit being one means the key is pressed
}
(also updated the project to use .net 8.0)
In the KeyUp handler, call UpdateKeyStates();
In the KeyDown handler, also call UpdateKeyStates(); and then do:
bool isKeyHeldDown = !_keysDown.TryAdd(e.KeyCode, true);
if (e.KeyCode == Keys.F10 && !isKeyHeldDown)
{
e.Handled = true;
}
- start the app
- open devtools
- hold down F10
- first capture/bubble handler logs in devtools show that
repeatis false. - I added tracepoints in the keydown handler to log
DateTimeOffset.Now.ToUnixTimeMilliseconds()andisKeyHeldDown. This shows that therepeat=falselog happens after the repeated key that we don't handle.
Repros in Edge Browser
No, issue does not reproduce in the corresponding Edge version
Regression
No, this never worked
Last working version (if regression)
No response
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.