Reputation: 1399
I have a game app that is rendered on a Canvas, with an interface rendered in a WebView.
All the pre-game menus happen in the WebView. When the game starts I switch the WebView to a page with a transparent background so you can see the game Canvas through it, but I can still overlay some interface elements.
This all works fine graphically, and I can see my game clearly with the WebView interface overlayed. I can communicate between the game and the interface quite happily.
The problem I have is getting the WebView to give up the keyboard, so I can use the keys to control the game.
My keyboard listener is triggered on the (theoretically) global event Window.Current.CoreWindow.KeyDown, so it should get keyboard events whatever has the focus.
If I hide the WebView everything works fine, the keyboard events are picked up and the game is controllable. Obviously though I can't see the overlayed elements.
Is there some way to let me receive the keyboard events when the WebView is visible?
This is a Win 10/UWP app written in XAML/C++. Target platform is Win 10 10.0.14393.0/ minimum 10.0.10586.0 Tested on Surface Book running Windows 10 v1703 15063.674
Upvotes: 1
Views: 1538
Reputation: 81
We have a Webview that must be interactive in our game at all times. The least ugly workaround that I have found so far is injecting a global event listener into the javascript to hook keyboard input, and relaying this back to the app via notify()
function onKeyDown(ev: KeyboardEvent) {
let wrapper = { keyDown: ev }
window['external']['notify'](JSON.stringify(wrapper));
}
function onKeyUp(ev: KeyboardEvent) {
let wrapper = { keyUp: ev }
window['external']['notify'](JSON.stringify(wrapper));
}
...
let options: AddEventListenerOptions = { capture: true, passive:true,once:false }
document.addEventListener("keydown", onKeyDown, options);
document.addEventListener("keyup", onKeyUp, options);
Upvotes: 0
Reputation: 330
Had a similar problem but managed to fix it with this trick based on Andy's answer:
DispatcherTimer timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(100)
};
timer.Tick += (s, e) =>
{
if (FocusManager.GetFocusedElement() is WebView webView)
{
webView.Visibility = Visibility.Collapsed;
webView.Visibility = Visibility.Visible;
}
};
timer.Start();
Upvotes: 0
Reputation: 1399
It is possible to release the focus from the WebView by hiding and then showing it again immediately.
webView->Visibility = Visibility::Collapsed;
webView->Visibility = Visibility::Visible;
Even if there's nowhere else for the focus to go -
after this operation, FocusManager::GetFocusedElement()
will return null.
The webview will remain visible, but keyboard events can now be received via Window.Current.CoreWindow.KeyDown
.
Note however that any interaction with the webview (eg. touch, navigation) will cause it to regain focus and you will stop receiving keyboard events.
This isn't a very satisfactory solution, but it sort-of fulfills the requirement to see the webview but also receive keyboard events.
Upvotes: 2