question

dmitc-MSFT avatar image
0 Votes"
dmitc-MSFT asked ·

[UWP][Xbox] WebView focus issue when using SeparateProcess mode

Hey folks,
I've encountered an issue with WebView UWP control on Xbox One that I can't seem to solve or even find any possible workaround.

In a nutshell, normal behavior for the WebView on Xbox looks something like this:

  • Focus on the whole WebView control

  • Press A to engage the focus within the control

  • Now the focus is trapped and you can interact with the page

  • Scroll the page, navigate to different links, etc...

  • Press B to give up the focus back to the page

  • Succeed and continue interacting with the app

However, when setting SeparateProcess as the execution mode for the WebView:

  • Focus on the whole WebView control

  • Press A to engage the focus within the control

  • Now the focus is trapped and you can interact with the page

  • Scroll the page, navigate to different links, etc...

  • Press B to give up the focus back to the page

  • Observe how B gets treated as a Tab button and focus doesn't leave the WebView

  • Since WebView doesn't respond to key/pointer events, the user is now stuck forever

The simplest reproduceable version of this can be found in "Sample project" field above.

I'd appreciate if someone could look into this, as I haven't found any ways at all to circumvent this issue. It's important that we use SeparateProcess execution mode since it provides a sizeable performance gain on an Xbox One, where UWP apps run in a very limited sandbox.

Please let me know if there are any questions and I'd be glad to clarify!

Best regards,
Dmitrii.



windows-uwpwindows-uwp-xaml
· 2
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Some things I tried:

  • Listen to (Preview)KeyDown events to switch the focus manually on B button. No luck since WebView doesn't respond to those.

  • Listen to PointerMoved event to switch the focus when the pointer reached the end of the screen. Similarly, no luck as those events stop arriving at some point.

  • Using AddWebAllowedObject and an injected JS event handler notify the app when the Tab button was pressed. This logic worked, however when attempting to switch focus (using both Focus method and FocusManager) nothing happens.

  • Switching execution mode to SeparateThread. That does fix the issue but doesn't give us any additional performance gains that SeparateProcess does.


0 Votes 0 ·

I've sent the email to the team but haven't got a response yet. There might be some time delay.

1 Vote 1 ·
dmitc-MSFT avatar image
0 Votes"
dmitc-MSFT answered ·

While there is still a legitimate bug present, we were able to find a temporary workaround:

 // This JS snippet helps to avoid the WebView focus trap issue with the SeparateProcess execution mode. It listens for the Tab keypress (on <B>) and suppresses that event while asking window to give up the focus. Normally this is intercepted by the app, but due to the bug in WWAHost, it gets interpreted as normal keyboard Tab in this mode. This approach does NOT work when the focus is within the iframe due to Cross-Origin security requirements
 public static async Task<string> AddTabHandler(this WebView webView)
 {
     if (webView == null)
     {
         return null;
     }
    
     // Even though we are suppressing the key event, there is a chance of race with other logic (typically handing outline styles). As a workaround (and given Tab button will always give up the focus), hide all of the outlines for consistency
     await webView.AddStyleAsync("* { outline: 0 !important; }");
    
     var focusHandlerJs = "document.addEventListener('keydown', function(e) { if (e.keyCode == 9) { e.preventDefault(); e.stopPropagation(); window.departFocus('up', { originLeft: 0, originTop: 0, originWidth: 0, originHeight: 0 }); } }, true);";
    
     return await webView.ExecuteAsync(focusHandlerJs);
 }
    
 public static async Task<string> ExecuteAsync(this WebView webView, string js)
 {
     if (webView == null || string.IsNullOrEmpty(js))
     {
         return null;
     }
    
     return await webView.InvokeScriptAsync("eval", new string[] { js });
 }
    
 public static async Task<string> AddStyleAsync(this WebView webView, string css)
 {
     if (webView == null || string.IsNullOrEmpty(css))
     {
         return null;
     }
    
     var injectStyleJs =
         $"var css = '{css}';" +
         "var style = document.createElement('style');" +
         "document.head.appendChild(style);" +
         "style.type = 'text/css';" +
         "style.appendChild(document.createTextNode(css));";
    
     return await webView.ExecuteAsync(injectStyleJs);
 }
·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RoyLi-MSFT avatar image
1 Vote"
RoyLi-MSFT answered ·

Hello,

Welcome to Microsoft Q&A!

I'm sorry to say that currently, our team doesn't have an Xbox to test here. So I'm going to ask other engineers about this. There might be some time delay.

Thank you!

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.