I'm building a UWP application that uses WebView2 to display a web-based interface. However, I'm running into persistent issues with the handling of Alt and AltGr keys. Here's a summary of the problem:
Current Problem:
Key Events in WebView2:
Expected Behavior:
What I’ve Tried:
WebView2 Settings:
Global Key Handling:
JavaScript Listeners:
Focus Management:
What I’ve Observed:
Sometimes the KeyUp and KeyDown events subscribed from:
if (Window.Current != null && Window.Current.CoreWindow != null)
{
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
Debug.WriteLine("KeyDown and KeyUp event handlers registered.");
}
are not being called while typing in webview2.
Left Alt:
-keydown works but keyup is frequently missed. Once the key is "stuck," subsequent unrelated key presses (e.g., Ctrl) cause the cached keyup to be processed.
AltGr:
-Similar to Left Alt, keydown is often misinterpreted as Ctrl or Alt. The behavior is inconsistent and varies depending on other keys pressed afterward.
Question:
How can I reliably handle Alt and AltGr key events in WebView2 or WebView within a UWP application? Specifically:
Additional Context:
I’m aware that WebView2 is not officially supported in UWP, and I have also tested this with the legacy WebView control. If someone has a reliable solution for WebView, I’m happy to switch back to it. I’ve explored solutions involving global key hooks, focus management, and JavaScript injection, but none of them completely solved the problem.
Code
Global Key Handlers:
private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args)
{
Debug.WriteLine($"Global KeyDown: {args.VirtualKey}");
if (args.VirtualKey == VirtualKey.Menu) // Left Alt
{
Debug.WriteLine("Alt detected, resetting focus to WebView2.");
args.Handled = true; // Prevent default behavior
ExamBrowser.Focus(FocusState.Programmatic); // Refocus WebView2
}
}
private void CoreWindow_KeyUp(CoreWindow sender, KeyEventArgs args)
{
Debug.WriteLine($"Global KeyUp: {args.VirtualKey}");
if (args.VirtualKey == VirtualKey.Menu) // Left Alt
{
Debug.WriteLine("Alt key released.");
args.Handled = true; // Prevent default behavior
}
}
document.addEventListener('keydown', function(event) {
let message = {
type: 'keydown',
key: event.key,
code: event.code,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
shiftKey: event.shiftKey,
metaKey: event.metaKey
};
window.chrome.webview.postMessage(JSON.stringify(message));
});
document.addEventListener('keyup', function(event) {
let message = {
type: 'keyup',
key: event.key,
code: event.code,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
shiftKey: event.shiftKey,
metaKey: event.metaKey
};
window.chrome.webview.postMessage(JSON.stringify(message));
});
Environment
Pressing ALTGR in the Guacamole Keyboard Tester
Pressing Left Alt and ALT GR (The Key Up for Left alt only shows up when pressing ALT GR again / Same behaviour when pressing Left control instead of ALT GR)
Any help is much appreciated!
Update:
When implementing the answer and switching back to Webview I managed to get these results:
Which look fine to me. But my problem is that Alt GR does not appear, which leads to my initial problem that inputs like {[]} are not working inside a guacamole rdp session. Used code:
private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
bool isAltPressed = args.KeyStatus.IsMenuKeyDown;
bool isCtrlPressed = (args.VirtualKey == VirtualKey.Control);
Debug.WriteLine($"Accelerator Key: {args.VirtualKey}, IsAltPressed: {isAltPressed}, IsCtrlPressed: {isCtrlPressed}");
if (args.VirtualKey == VirtualKey.Menu && !isCtrlPressed)
{
Debug.WriteLine("Blocking Left Alt and refocusing WebView2.");
args.Handled = true;
ExamBrowser.Focus(FocusState.Programmatic);
}
else if (isAltPressed && isCtrlPressed)
{
Debug.WriteLine("AltGr detected, allowing input.");
}
}
Pulling heavily from this other SO question, I would suggest trying to use Dispatcher.AcceleratorKeyActivated
instead of or in conjunction with KeyDown
and KeyUp
. I didn't have a chance to test this with your specific configuration, but for example, attaching your event:
if (Window.Current != null && Window.Current.CoreWindow != null)
{
Window.Current.CoreWindow.GetForCurrentThread().Dispatcher.AcceleratorKeyActivated += Dispatcher_AcceleratorKeyActivated;
}
And your code for your event handler may be something like:
private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
if ((args.EventType == CoreAcceleratorKeyEventType.KeyDown || args.EventType == CoreAcceleratorKeyEventType.SystemKeyDown)
&& !args.KeyStatus.WasKeyDown)
{
if(args.KeyStatus.IsMenuKeyDown) Debug.WriteLine("Alt key pressed.");
}
}
Hupefully, that at least helps get you going in the right direction.