Editor Window - How to center a window.

Like the title said, how does one center a popup window for a instance in the Editor?

Using Screen.Width does not work, unless the window is in full screen, and in the primary monitor.

So i guess your actual question is how you can find out the position and size of Unity’s main window? Here you go:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;

public static class Extensions
{
    public static System.Type[] GetAllDerivedTypes(this System.AppDomain aAppDomain, System.Type aType)
    {
        var result = new List<System.Type>();
        var assemblies = aAppDomain.GetAssemblies();
        foreach (var assembly in assemblies)
        {
            var types = assembly.GetTypes();
            foreach (var type in types)
            {
                if (type.IsSubclassOf(aType))
                    result.Add(type);
            }
        }
        return result.ToArray();
    }

    public static Rect GetEditorMainWindowPos()
    {
        var containerWinType = System.AppDomain.CurrentDomain.GetAllDerivedTypes(typeof(ScriptableObject)).Where(t => t.Name == "ContainerWindow").FirstOrDefault();
        if (containerWinType == null)
            throw new System.MissingMemberException("Can't find internal type ContainerWindow. Maybe something has changed inside Unity");
        var showModeField = containerWinType.GetField("m_ShowMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var positionProperty = containerWinType.GetProperty("position", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
        if (showModeField == null || positionProperty == null)
            throw new System.MissingFieldException("Can't find internal fields 'm_ShowMode' or 'position'. Maybe something has changed inside Unity");
        var windows = Resources.FindObjectsOfTypeAll(containerWinType);
        foreach (var win in windows)
        {
            var showmode = (int)showModeField.GetValue(win);
            if (showmode == 4) // main window
            {
                var pos = (Rect)positionProperty.GetValue(win, null);
                return pos;
            }
        }
        throw new System.NotSupportedException("Can't find internal main window. Maybe something has changed inside Unity");
    }

    public static void CenterOnMainWin(this UnityEditor.EditorWindow aWin)
    {
        var main = GetEditorMainWindowPos();
        var pos = aWin.position;
        float w = (main.width - pos.width)*0.5f;
        float h = (main.height - pos.height)*0.5f;
        pos.x = main.x + w;
        pos.y = main.y + h;
        aWin.position = pos;
    }
}

Just use Extensions.GetEditorMainWindowPos() to get back the rect of the main window in screen coordinates.

I’ve also written a simple extension method for the EditorWindow class called “CenterOnMainWin”. So inside yout editor window you can simply call CenterOnMainWin() and the window should positioning itself in the center of the main window.

There is a new method added to Unity 2020: EditorGUIUtility.GetMainWindowPosition().

It acts the same way as GetEditorMainWindowPos() but it’s obviously faster, so you should use only the CenterOnMainWin method from the Bunny83’s answer with the following modification:

public static void CenterOnMainWin(this EditorWindow window)
{
    Rect main = EditorGUIUtility.GetMainWindowPosition();
    Rect pos = window.position;
    float centerWidth = (main.width - pos.width) * 0.5f;
    float centerHeight = (main.height - pos.height) * 0.5f;
    pos.x = main.x + centerWidth;
    pos.y = main.y + centerHeight;
    window.position = pos;
}

Actually the correct answer would rather be:

var window = GetWindow<MyWindow>("Centered Window");
var position = window.position;
position.center = new Rect(0f, 0f, Screen.currentResolution.width, Screen.currentResolution.height).center;
window.position = position;
window.Show();

using Screen.currentResolution.width and Screen.currentResolution.height.

If without 2020, doing this will be much faster

private static Type GetType (this AppDomain aAppDomain, Type aType, string name)
        {
            var        assemblies   = aAppDomain.GetAssemblies ();
            return assemblies.SelectMany (assembly => assembly.GetTypes ()).FirstOrDefault (type => type.IsSubclassOf (aType) && type.Name == name);
        }

var containerWinType =
                AppDomain.CurrentDomain.GetType (typeof (ScriptableObject), "ContainerWindow");

I was having a similar issue and to get Unity’s window center I’m now using:

var windowCenter = EditorGUIUtility.GetMainWindowPosition().center;

I haven’t tested this across multiple setups, but is also working on a recent MacBook which was an issue before.