- Home /
A way to detect when the Editor Application is focused
I'm doing an Editor extension and I want to update an application wide state once the Editor has gained focus. For example once the user Alt+Tabs into another window and then returns back to the Editor.
Answer by Simeon · Jan 10, 2018 at 07:08 PM
I Found a cheaty way. Apparently the EditorWindow
has a private property called hasFocus
. I just use reflection to access it. This will give delegate:
Delegate.CreateDelegate(typeof(Func<EditorWindow,bool>),typeof(EditorWindow).GetProperty("hasFocus", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true));
How would you go about subscribing to this event? Or just getting the value.
@AntonLind the method i provided returns a func delegate you can call. You just need to provide it a window argument.
Can you share any more info about this?
From what I've been able to get working, I assume I should be using this in some "EditorWindow" Class correct? Like this :
using System;
using System.Reflection;
using UnityEngine;
using UnityEditor;
public class $$anonymous$$yDebugWindow : EditorWindow
{
Func<EditorWindow, bool> isWindowFocused = (Func<EditorWindow, bool>)Delegate.CreateDelegate( typeof( Func<EditorWindow, bool> ), typeof( EditorWindow ).GetProperty( "hasFocus", BindingFlags.NonPublic | BindingFlags.Instance ).GetGet$$anonymous$$ethod( true ) );
public void OnGUI()
{
if ( isWindowFocused( GetWindow<EditorWindow>() ) )
doSomething();
}
}
And then you say "You just need to provide it a window argument" so I tried "GetWindow()"
The issue is that it seems like it FORCES Unity to be focused when ever I call the function "isWindowFocused", I need to actually close the "$$anonymous$$yDebugWindow" to focus on any other application.
So where did I go wrong? Should this be a $$anonymous$$onoBehavior? or and Editor class? or some static class?
Thanks!
just use the instance of the window. In your case isWindowFocused(this)
Answer by llMarty · Apr 16, 2019 at 06:35 PM
UnityEditorInternal.InternalEditorUtility.isApplicationActive
will return true, if the Editor window is focused in any way. Was pretty hard to find, because it's not documented, but InternalEditorUtility
is a gem, there is much to discover. ;)
Answer by Nikolay-Lezhnev · May 29, 2019 at 10:12 AM
You can also add this script to Assets/Editor:
using System;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class EditorWindowFocusUtility
{
public static event Action<bool> OnUnityEditorFocus = (focus) => { };
private static bool _appFocused;
static EditorWindowFocusUtility()
{
EditorApplication.update += Update;
}
private static void Update()
{
if (!_appFocused && UnityEditorInternal.InternalEditorUtility.isApplicationActive)
{
_appFocused = UnityEditorInternal.InternalEditorUtility.isApplicationActive;
OnUnityEditorFocus(true);
Debug.Log("On focus window!");
}
else if (_appFocused && !UnityEditorInternal.InternalEditorUtility.isApplicationActive)
{
_appFocused = UnityEditorInternal.InternalEditorUtility.isApplicationActive;
OnUnityEditorFocus(false);
Debug.Log("On lost focus");
}
}
}
and you can subscribe in any place on event:
EditorWindowFocusUtility.OnUnityEditorFocus += (focus) => {/*do something*/}
Answer by aurelioprovedo · Feb 12 at 02:01 AM
The solutions proposed in other answers (@Nikolay-Lezhnev & @llMarty) already work correctly, but let me suggest an alternative method.
Using reflection, we can access the exact same event that Unity uses internally.
public static Action<bool> UnityEditorFocusChanged
{
get
{
var fieldInfo = typeof(EditorApplication).GetField("focusChanged",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
return (Action<bool>)fieldInfo.GetValue(null);
}
set
{
var fieldInfo = typeof(EditorApplication).GetField("focusChanged",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
fieldInfo.SetValue(null, value);
}
}
You can then register to the event like you would with any delegate:
UnityEditorFocusChanged += OnEditorFocusChanged;
And the signature for your callbacks must be as follows:
private static void OnEditorFocusChanged(bool hasFocus)
{
if (hasFocus)
{
EditorWindow.focusedWindow?.ShowNotification(new GUIContent("Welcome back! ^_^"));
}
}
Nicely done. I love when I google something and find an elegant solution posted 5 days ago, to a question posted 5 1/2 years ago.
Answer by electric_jesus · Jul 13, 2018 at 11:20 AM
Here is what I use:
public static bool IsUnityEditorFocused() {
return EditorWindow.mouseOverWindow != null;
}
If the user switches to the editor using Alt/C$$anonymous$$D-Tab, or using Taskbar/Dock then the mouse may not be over the window but still be focused, this example function would return false.