Search Unity

Unity 5.4.1f1 - No keyboard input for native UWP element (WebView)

Discussion in 'Windows' started by Maisey, Sep 22, 2016.

  1. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Hello!

    I upgraded to Unity 5.4.1f1 yesterday, and among a lot of other bugs (or breaking changes), I stumbled upon this one.

    I'm using the winfbsdk (Microsofts offical Facebook SDK for UWP apps) for use of Facebook inside my UWP app. It worked as it should in Unity 5.3.2. But now:

    After upgrading to Unity 5.4.1f1 and testing the app again (in the same environment) the login window (which is a WebView-element that pops up in front of the "Unity-element") doesn't take input for Input-boxes (TextFields). I can tab through the Username/Password field, but I can't enter any characters. I can copy and paste content into the boxes, but I can't manually type anything in them.

    See attached screenshot.

    Any suggestion as to what may cause this? I haven't upgraded the winfbsdk and I haven't really changed anything. The only obvious change i saw when upgrading was that the app now defaults to fullscreen-mode instead of window-mode. Can this cause some issues?

    Thanks!

    EDIT:

    I went through the release-logs and found this:
    • Windows Store: Unity will no longer steal key events when another XAML element (e.g. TextBox) is in focus.
    Which seems to be exactly what's happening. So how can I workaround this, without downgrading to Unity 5.3.2?
     

    Attached Files:

    Last edited: Sep 22, 2016
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Try adding -dontConnectAcceleratorEvent command line argument.
    Regardless of result please report a bug.
     
  3. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Thank you @Aurimas-Cernius it worked!

    Mind explaining what this does and why it stopped working and why these magical flags is not documented anywhere? :O

    And please, can you submit a bug report about this issue? Just wrote an essay-bug report on another issue with Unity 5.4.1, really don't feel like writing another one.
     
  4. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    This will be pointless without your repro project, so please submit a bug.
     
  5. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    We connect to AcceleratorEvent on CoreWindow in order to receive certain keyboard keys that are not available in other events. This flag disables that, which means we don't connect the even and won't handle those keys (F10, Shift, Alt, Ctrl keys should be tested in your app now, some will not be seen by Unity).

    It looks we broke the event handler when fixing issues with touch screen keyboard ('@' was impossible to type in some languages).

    Missing documentation is another bug :(
     
  6. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Thanks for the information @Aurimas-Cernius !

    It's reproducible in an empty Unity-project. Build Universal App without C#-projects. Inside MainPage.xaml.cs: In the end of the constructor for the MainPage-class add the following:

    Code (CSharp):
    1. var simpleWebView = new WebView();
    2. simpleWebView.Source = new Uri("https://google.com");
    3. var someDialog = new ContentDialog();
    4. someDialog.Content = simpleWebView;
    5.  
    6. someDialog.ShowAsync();
    If you try to type something inside the google search-field, it won't be possible (you can however tab through the content). If you replace WebView with a TextBox instead (in the example code) it will work as intended.


    EDIT:
    @Aurimas-Cernius do you know which patch release I can expect this fix in? (I know there's a temporary work-around (command-line-args)), but I would like to avoid doing manual steps while building (when forgetting causes big issues :( )).
     
    Last edited: Sep 26, 2016
  7. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Hey Maisey,

    I've looked at this problem...Sadly the code
    Code (csharp):
    1.  
    2. var simpleWebView = new WebView();
    3. simpleWebView.Source = new Uri("https://google.com");
    4. var someDialog = new ContentDialog();
    5. someDialog.Content = simpleWebView;
    6.  
    7. someDialog.ShowAsync();
    8.  
    doesn't work for me, as in the webpage is never loaded, so I can't reproduce the problem with this script. So I tried adding WebView component directly into MainPage.xaml, where webpage would load correctly, but keyboard input worked correctly there, can you confirm that?

    I am guessing the issue is, Unity doesn't detect that your control has focus, that's why it's intercepting input.
     
  8. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Hello @Tomas1856 ! I can confirm that the issue is only when some content (WebView in this case) is added through the use of ContentDialog (which creates object outside of the DXSwapChainPanel). I don't know why the webpage is never loaded though (firewall maybe (though I doubt it))?). Did you try this on Desktop and did you make sure you have Internet Capabilties checked in the manifest?

    EDIT:
    Did just see that you wrote that it worked when added to the main view. Hmm, weird.

    It works to tab, copy-paste stuff into the fields etc. But typing anything does not work. So Unity doesn't steal all focus somehow.
     
    Last edited: Sep 27, 2016
  9. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    It simply means Unity didn't care about those input events and didn't handle them, that's why WebView was able to handle them instead. But Unity does handle all key events except when it's aware that XAML element (which is a child of SwapChainPanel) is focused, in that case Unity will let that XAML element to handle those.

    Now the issue with ContentDialog, it's not a part of MainPage XAML tree view, by the looks of it, it's a child of a Popup element, thus Unity is not aware that it's focused and wants key input events.

    Still looking what would be the proper way of handling this.

    Stay tuned.
     
  10. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    What if you call UnityPlayer.AppCallbacks.Instance.UnitySetInput(false); before showing that popup window, and then restoring UnityPlayer.AppCallbacks.Instance.UnitySetInput(true) after that window is closed, does that work for you then?
     
  11. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Calling UnityPlayer.AppCallbacks.Instance.UnitySetInput(false); wont do any difference (it won't receive text input).

    This wasn't an issue in Unity 5.3.3 (not sure in what version it stopped working).

    Not sure if it helps you. But if I type something the moment I see the dialog with Google in it, it will work. But then _very_ soon after, it will not work.
     
    Last edited: Sep 27, 2016
  12. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Hmph, it should have worked... because it effectively makes Unity unsubscribe from AcceleratorKeyActivated event, which causing the issue.

    I think in older versions, there was an opposite effect, while it may worked in this case, the input would also leak to Unity's text field.

    Do you have a repro project with winfbsdk involved, because like I said above code doesn't work for me.
     
  13. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    It didn't work, but as I mentioned adding the CommandLineArg however does fix the issue. When I'm trying things you are suggesting, I'm trying them in an empty project built with Unity and only added the lines I suggested.

    See below for a Visual Studio project (empty Unity project built with added WebView/Dialog). If the WebView doesn't load, there must be an issue on your end, or having an old version of Visual Studio/XAML SDK (or new un-working version for that matter).

    VS-project:
    https://drive.google.com/file/d/0By8nBliDYJ47ajlWYlhhRUsteGs/view?usp=sharing

    Any news, @Tomas1856 ?
     
    Last edited: Oct 11, 2016
  14. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
  15. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Hey,

    we discussed this problem with Microsoft, on how we can detect that there's a popup window focused, but the workaround was not straightforward, so we're still thinking.

    On the other side, I checked UnitySetInput function and it fixes your problem, I guess you've used UnitySetInput function in MainPage constructor, in that case that's wrong, because Unity was still initializing in the background and at some point overwrites that setting, but if you call this function after Unity is intialized everything should work.
     
  16. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Thank you Tomas for getting back to be, much appreciated!

    You are right, I used UnitySetInput in the MainPage-contructor. I take it there no way to do this on the Unity-side? My only concern is that I have to do this manually until it's fixed inside Unity and this step is very easily forgotten when building.

    Thanks!
     
  17. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Like I said, the problem here is Unity has no straight way of detecting that there's a popup window showing, but even if this fixed, if you use UnitySetInput (for enabling/disabling Unity input handling) function, there's no harm in that.

    Stay tuned
     
  18. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    I think I was a bit unclear. I meant: is there any way to use UnitySetInput from the Unity-side instead of doing it somewhere inside App.xaml.cs or MainPage.xaml.cs?
     
  19. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Oh sorry... but sadly no, that specific function comes from UnityPlayer.winmd file which is not referenced by Assembly-CSharp.dll so you can not directly access it.

    I guess we could expose such function in https://docs.unity3d.com/ScriptReference/WSA.Application.html, but I doubt it will happen in 5.4.x version.
     
  20. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Actually, there may be a way to do this via reflection, will be back in few minutes
     
  21. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,905
    Alright, it's not very pretty, but it works, and can be executed from inside Unity script.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;
    5.  
    6. #if NETFX_CORE
    7. using Windows.UI.Xaml.Controls;
    8. using System.Reflection;
    9. using System.Linq;
    10. using Windows.UI.Xaml.Input;
    11. #endif
    12.  
    13. public class NewBehaviourScript : MonoBehaviour
    14. {
    15.     async void ShowImpl()
    16.     {
    17. #if NETFX_CORE
    18.         UnitySetInput(false);
    19.         var simpleWebView = new WebView();
    20.         simpleWebView.Source = new Uri("https://google.com");
    21.         var someDialog = new ContentDialog();
    22.         someDialog.Content = simpleWebView;
    23.         someDialog.PrimaryButtonText = "Quit";
    24.  
    25.         ContentDialogResult res = await someDialog.ShowAsync();
    26.  
    27.         UnitySetInput(true);
    28. #endif
    29.     }
    30.  
    31.     void OnGUI()
    32.     {
    33.         if (GUILayout.Button("Test"))
    34.         {
    35.             UnityEngine.WSA.Application.InvokeOnUIThread(() =>
    36.             {
    37.                 ShowImpl();
    38.             }, false);
    39.         }
    40.     }
    41.  
    42.     #region Magic
    43. #if NETFX_CORE
    44.     private object m_AppCallbacksObject;
    45.     private MethodInfo m_UnitySetInputMethod;
    46.  
    47.     private void UnitySetInput(bool enabled)
    48.     {
    49.         if (m_AppCallbacksObject == null)
    50.         {
    51.             var app = Windows.UI.Xaml.Application.Current;
    52.             var appCallbacksField = app.GetType().GetTypeInfo().DeclaredFields.Where(f => f.Name == "appCallbacks").FirstOrDefault();
    53.             m_AppCallbacksObject = appCallbacksField.GetValue(app);
    54.             m_UnitySetInputMethod = m_AppCallbacksObject.GetType().GetTypeInfo().DeclaredMethods.Where(m => m.Name == "UnitySetInput").FirstOrDefault();
    55.  
    56.             if (m_UnitySetInputMethod == null)
    57.                 throw new MissingMethodException("Failed to locate UnitySetInput function");
    58.         }
    59.  
    60.         m_UnitySetInputMethod.Invoke(m_AppCallbacksObject, new object[] { enabled });
    61.     }
    62. #endif
    63. #endregion
    64. }
    65.  
    66.  
     
  22. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
  23. TheSofaKing

    TheSofaKing

    Joined:
    Jun 10, 2015
    Posts:
    13
    Hi, I'm having the same issue currently in 5.5.1f1, and I tried using the code provided here, but after calling " m_UnitySetInputMethod.Invoke(m_AppCallbacksObject, new object[] { enabled });" the app freezes without giving any errors, and does not call the next line of code.

    How were you able to get winfbsdk working, If i copy paste in text I can log in, but without keyboard input its not worth doing. Any help would be appreciated.
     
  24. byronm

    byronm

    Joined:
    Jun 27, 2017
    Posts:
    2
    Just as a heads up to anyone reading this is still happening in 2017.1 so I doubt it's going to ever be fixed.
     
  25. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676
    What is the particular issue you're running into? We have no known bug reports open on any related issues as far as I can tell.
     
  26. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    What if add command line argument: -dontConnectAcceleratorEvent

    With this argument some keyboard keys will not be registered by Unity, but if you don't use them, you'll be fine. From memory F7 and some Ctrl or Alt, but better test it, I don't remember exactly.
     
  27. byronm

    byronm

    Joined:
    Jun 27, 2017
    Posts:
    2
    Hey Aurimas-Cernius,

    I currently have an open ticket on Unity's Zendesk (we have a corporate account) with this same discussion. I figured I would forward the information for anyone else trying to develop for the platform. UWP has been a bit of a non-stop roller-coaster :(

    The issue for me is that when you use reflection or use a static delegate to forward the call you get an access violation when it's invoked and Unity hard crashes. We are currently using 2017.1.2p3.

    Unfortunately in the current state our project is unshipable because of this issue.

    I am unaware of how to add a command line argument when building with Visual Studio and running in debug mode.


    ZenDesk Request ID: #485918







     
    Last edited: May 18, 2018
  28. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,676