- 
                Notifications
    You must be signed in to change notification settings 
- Fork 62
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