Mouse input possible from different tab

Discussion in 'Unity Support' started by Paul Usul, Jul 30, 2009.

  1. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    Hi, I hope you guy's and gals can help me, please bear with me I'm new.

    The problem:
    The web player listens to the mouse even if the browser is on a different tab.

    Ocurs:
    Windows - FireFox
    Windows - IE 8
    Windows - Chrome

    Reproduce problem:
    1. Open the tropical paradise demo, let it load and click to explore.
    2. Open a new tab.
    3. Return to the demo tab.
    4. Move your mouse to the tab you opened in step 2. now note the view direction of the camera.
    5. Click the tab, now move you mouse back to the demo tab, click it.
    6. Compare current view to view from step 4.

    comment: even thou you where on a different tab, the tropical paradise demo still registered your mouse movement and reacted. This also happens with scroll and even clicks.

    I have attached a project that hides the cursor(so it is possible to use custom mouse cursors as described in the documentation here). But the side effect is that the web player hides the cursor on all tabs! I have also attached an already buildt web player, open it and some other tabs and watch your mouse dissapear.

    Attached Files:

  2. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    If you use a web player, You are affected by this! I have now reported a bug, so I hope that helps.

    I have made a new project, that logs mouse clicks.
    Open the web player, open a new tab, click around the empty tab and now go back to the web player, there will be a masssive log :/

    does this look okay?
    http://intra.unity3d.com/fogbugz/default.asp?271462_3jg9tbng
    Code (csharp):
    1. Unity web player mouse input ignores that user is on different tab!
    2.  
    3. Dear Sam
    4. I have a huge problem, if this bug report is in any way lacking please contact me. We are close to launching and it is impossible to have the web player open and use any other tab.
    5.  
    6. The problem:
    7. We hide the mouse and use a custom cursor, but the mouse is hidden in all other tabs. Open the attached project, run a web player and open some tabs, the mouse will disapear on the other tabs.
    8.  
    9. Unity web player always listens an reactes to the mouse, even if the user is on another tab. Mouse movement, clicks and scrolling all go directly to the web player, with no exeption!
    10.  
    11. In the attached project I made just for you :) you can build a web player, open some tabs and click around, the web player logs all you clicks, from the other tabs
    12.  
    13. I really hope you can fix this bug or in any other way help
    14.  
    15. Best Regards
    16.   Paul Usul Fluegel

    Attached Files:

  3. AtomicTroop

    AtomicTroop

    New Member

    Joined:
    Aug 3, 2009
    Messages:
    11
    Hi, I'm not completely sure about this but I think that you could check if the mouse is inside the game screen. So if it goes outside the game frame you could just make it autopause and bring the mouse back up, then when you continue the game just switch the mouse back to the gamemouse again and unpause it. As for the technical side of doing this... Try digging into the documentation. As I said though, I'm not completely sure about this.
  4. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    Hi, thanks for the post.

    I hadn't thought of pausing, but disabling scripts. But I have tried from the browser side to call unity on onfocus/onblur.

    But to no avail, input is not affected by Time.timeScale or Time.fixedDeltaTime

    :(
  5. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    Okay I have been working on this for a couple of days now, and have come up with the cleanest dirty hack I could.

    The idea is to have the browser tell unity when it's focus:

    Code (csharp):
    1.  
    2. <script language="javascript1.1" type="text/javascript">
    3.       function onBlur()
    4.       {
    5.       GetUnity().SendMessage("BrowserWindow", "WindowFocusOut", " ");
    6.       }
    7.  
    8.       function onFocus()
    9.       {
    10.       GetUnity().SendMessage("BrowserWindow", "WindowFocusIn", " ");
    11.       }
    12.  
    13.       // check for Internet Explorer
    14.       if (navigator.appName == "Microsoft Internet Explorer")
    15.       {
    16.       document.onfocusin = onFocus;
    17.       document.onfocusout = onBlur;
    18.       }
    19.       else
    20.       {
    21.       document.onfocus = onFocus;
    22.       document.onblur = onBlur;
    23.       }
    24.     </script>
    25.  
    Now we have to have a game object named BrowserWindow, with a script with methods called WindowFocusIn and WindowFocusOut that take a string.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class BrowserWindow : MonoBehaviour
    6. {
    7.     //gameobjects to get the scripts that need disabling!
    8.     public GameObject gameobject;
    9.  
    10.     private fooBarScript;
    11.  
    12.     private bool focus;
    13.     private bool debug;
    14.     private string logText;
    15.  
    16.     public bool Focus { get { return focus; } set { focus = value; } }
    17.  
    18.     // Use this for initialization
    19.     void Start()
    20.     {
    21.         focus = true;
    22.         debug = false;
    23.  
    24.         fooBarScript= (fooBarScript)gameObject.GetComponent(typeof(fooBarScript));
    25.  
    26.         // to test that we actualy have something, for editor testing
    27.         fooBarScript.enabled = true;
    28.     }
    29.  
    30.     // OnGUI is called once per event
    31.     void OnGUI()
    32.     {
    33.         if (!focus)
    34.         {
    35.             //Gui magic to avoid gui events
    36.             GUI.depth = 0;
    37.             GUI.backgroundColor = new Color(1f, 1f, 1f, 0.25f);
    38.             GUI.color = Color.black;
    39.             GUI.Button(new Rect(0, 0, Screen.width, Screen.height), "Pause..");
    40.         }
    41.  
    42.         if (Debug)
    43.         {
    44.             GUI.Label(new Rect(0, 5, 140, Screen.height - 200), logText, "button");
    45.         }
    46.     }
    47.  
    48.     //this is called when the window we are in looses focus, but the window can loose focus to us the webplayer.
    49.     public void WindowFocusOut(string arg)
    50.     {
    51.         //if the mouse cords are inside us, and the window lost focus, we have the focus
    52.         if (new Rect(0, 0, Screen.width, Screen.height).Contains(new Vector2(Input.mousePosition.x, Input.mousePosition.y)))
    53.         {
    54.             WindowFocusIn(arg);
    55.             return;
    56.         }
    57.         logText += "Out\n";
    58.  
    59.         focus = false;
    60.  
    61.         //disable all your scripts.
    62.         foobarScript.enabled = false;
    63.     }
    64.  
    65.     public void WindowFocusIn(string arg)
    66.     {
    67.         logText += "In\n";
    68.  
    69.         focus = true;
    70.  
    71.         //enable all your scripts.
    72.         foobarScript.enabled = true;
    73.     }
    74. }
    75.  
    tried to generalise the code, so it's useable by whom ever :)

    Now we just disable every thing that needs to be disabled, and no more shooting friends while in another tab :p

    But still, UT I really hope you come with a proper fix, keyboard kontrol trough tabs are fine, mouse should be to :D
  6. Quietus2

    Quietus2

    New Member

    Joined:
    Mar 28, 2008
    Messages:
    2,061
    Time.timeScale and the like only affect the physics engine. The rest, you have to either disable or simply bypass yourself appropriately when losing focus. So you're on the right track.

    Depending on how your game is set up, it might be just a matter of setting a bool to early exit OnGUI() and other routines where you're using mouse/keyboard input.

    *Edit : you beat me to it! Glad to see you figured it out.
  7. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    Sad to say this does not fix the problem entirely. The bug still exists in some cases where the web player has focus and does not let it go to another tab :(

    Will post more when I find a fix.
  8. Dreamora

    Dreamora

    Member

    Joined:
    Apr 5, 2008
    Messages:
    26,586
    Disclaimer: Not tested
    But have you ensured that you disabled the "run in background" checkbox in the player settings / didn't enable it through script
    Because with run in background it won't care about not beeing the active tab, its enough for the browser window to be active for it to receive input as thats how plugins work in browsers.
  9. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    Ya I have experimented with Run in background. But because the browser is still active(just in another tab), the web player still receives mouse activity, I'm guessing.

    Right now I'm experimenting with onmouseover/mouseout instead of onfocus events, because the latter really lacks cross browser compatibility.

    Thanks for all the posted ideas, they really do help inspire me to look in new places! :D
  10. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    Okay this is a updated copy paste of my earlier post, this is the best possible solution I have got working. onfocus has been replaced with mouse over events and a single onfocus, so it's possible to click the web player to gain focus no matter what.

    [Edit] updated code to run with chrome+more
    Code (csharp):
    1.  
    2. <script language="javascript1.1" type="text/javascript">
    3.     function onBlur()
    4.     {
    5.         GetUnity().SendMessage("BrowserWindow", "WindowFocusOut", " ");
    6.     }
    7.  
    8.     function onFocus()
    9.     {
    10.         GetUnity().SendMessage("BrowserWindow", "WindowFocusIn", " ");
    11.     }
    12.  
    13.     // check for Internet Explorer, boo
    14.     if (navigator.appName == "Microsoft Internet Explorer")
    15.     {
    16.         // Internet Explorer
    17.         GetUnity().attachEvent('onmouseover', onFocus, false);
    18.         GetUnity().attachEvent('onfocusin', onFocus, false);
    19.         GetUnity().attachEvent('onmouseout', onBlur, false);
    20.     }
    21.     else
    22.     {
    23.         // Netscape, Firefox, Mozilla, Chrome and Safari.
    24.         GetUnity().addEventListener('mouseover', onFocus, false);
    25.         GetUnity().addEventListener('focus', onFocus, false);
    26.         GetUnity().addEventListener('mouseout', onBlur, false);
    27.     }
    28. </script>
    29.  
    Now we have to have a game object named BrowserWindow, with a script with methods called WindowFocusIn and WindowFocusOut that take a string.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class BrowserWindow : MonoBehaviour
    6. {
    7.     //gameobjects to get the scripts that need disabling!
    8.     public GameObject gameobject;
    9.  
    10.     private fooBarScript;
    11.  
    12.     // Use this for initialization
    13.     void Start()
    14.     {
    15.         fooBarScript= (fooBarScript)gameObject.GetComponent(typeof(fooBarScript));
    16.  
    17.         // to test that we actualy have something, for editor testing
    18.         if (fooBarScript == null)
    19.         {
    20.             Debug.LogError("fooBarScript was null!");
    21.         }
    22.  
    23.         //so if the user opens the player and changes tab, with out any focus change
    24.         WindowFocusOut("");
    25.     }
    26.  
    27.     public void WindowFocusOut(string arg)
    28.     {
    29.         Screen.showCursor = true;
    30.         //disable all your scripts.
    31.         foobarScript.enabled = false;
    32.     }
    33.  
    34.     public void WindowFocusIn(string arg)
    35.     {
    36.         //enable all your scripts.
    37.         foobarScript.enabled = true;
    38.     }
    39. }
    40.  
    I have removed all the debuggin to unclutter the code, hope this helps some one :)
  11. jerome

    jerome

    New Member

    Joined:
    Oct 13, 2008
    Messages:
    52
    I carefully read this read and the solution you give globaly work.
    But in my case I need to get an event when a user click outside the unity object and not when the mouse is outside (not over)
    So I added the blur event (GetUnity().addEventListener('blur', onBlur, false)
    which does exactly that but the result is very strange.

    I don't receive the message in unity (I mean BrowserWindow/WindowFocusOut is not called) at the instant where the event occur but later when the object regain focus. So when i enter focus I get two event, the focus In and then the focus out i didn't have when it effectively occur ...
    Do you have the same trouble with this event, that maybe why he don't appear in you example ?

    Best Regards
    Jérôme Foucher
  12. Paul Usul

    Paul Usul

    New Member

    Joined:
    Jul 30, 2009
    Messages:
    49
    I know this sounds a bit weird, but have you checked run in background? since the window is not in focus, it could be that unity can't process the events. But all the browsers really suck at event propagation, but hope you get it working :)
  13. jerome

    jerome

    New Member

    Joined:
    Oct 13, 2008
    Messages:
    52
    yes run in background is active.

    I just find strange that the mouseOut event work and not the blur event ...

    Does it work for you ?
  14. monark

    monark

    Member

    Joined:
    May 2, 2008
    Messages:
    1,106
    Anyone know how to fix this same issue with the standalone app? On windows if you open another app on top of the unity one you can still click through, but in that situation there is no browser to send the message.
  15. monark

    monark

    Member

    Joined:
    May 2, 2008
    Messages:
    1,106
    Has anyone got the mouseout event to work in firefox on windows?
    It works in firefox on the mac fine.