why

The Unity editor provides system-level menu pop-ups that block messages, freeze rendering, and fail to search, while the Unity editor has its own non-blocking version of pop-ups that are not open to users, such as this interface:

To solve

Copy editor source code, modify a copy:

using System;
using System.Collections;
using System.Globalization;
using UnityEditor;
using UnityEngine;

/// <summary>
///GenericMenu Unity style version
/// </summary>
public class GenericPopupMenu : PopupWindowContent
{
    private class Styles
    {
        public readonly GUIStyle header = "In BigTitle";
        public readonly GUIStyle menuItem = "MenuItem";
        public readonly GUIStyle customTextField = "ToolbarSeachTextField";
        public readonly GUIStyle customTextFieldCancelButton = "ToolbarSeachCancelButton";
        public readonly GUIStyle customTextFieldCancelButtonEmpty = "ToolbarSeachCancelButtonEmpty";
    }

    private class MenuItem
    {
        public GUIContent content;
        public bool separator;
        public bool on;
        public GenericMenu.MenuFunction func;
        public GenericMenu.MenuFunction2 func2;
        public object userData;
        public bool enabled = true;

        public MenuItem(GUIContent _content, bool _separator, bool _on, GenericMenu.MenuFunction _func)
        {
            content = _content;
            separator = _separator;
            on = _on;
            func = _func;
        }

        public MenuItem(GUIContent _content, bool _separator, bool _on, GenericMenu.MenuFunction2 _func, object _userData)
        {
            content = _content;
            separator = _separator;
            on = _on;
            func2 = _func;
            userData = _userData;
        }

        public MenuItem(GUIContent _content, bool _separator, bool _on, bool _enabled)
        {
            content = _content;
            separator = _separator;
            on= _on; enabled = _enabled; }}private static Styles s_Styles;
    private static string s_TextFieldName = "GenericPopupMenuTextField";
    private readonly ArrayList m_MenuItems = new ArrayList();

    private readonly ArrayList m_MenuFilteredItems = new ArrayList();
    private bool m_EnableFiltered = true;
    private string m_FilteredText = string.Empty;
    private int m_SelectedIndex;
    private bool m_FocusText = true;
    private double m_FocusTextTime;

    private Vector2 m_ScrollPos;
    private bool m_IgnoreCase;

    public GenericPopupMenu(bool ignoreCase = false)
    {
        m_IgnoreCase = ignoreCase;
    }

    public void AddItem(GUIContent content, bool on, GenericMenu.MenuFunction func)
    {
        m_MenuItems.Add(new MenuItem(content, false.on, func));
    }

    public void AddItem(GUIContent content, bool on, GenericMenu.MenuFunction2 func, object userData)
    {
        m_MenuItems.Add(new MenuItem(content, false.on, func, userData));
    }

    public void AddDisabledItem(GUIContent content)
    {
        m_MenuItems.Add(new MenuItem(content, false.false.false));
    }

    public void AddSeparator(string path)
    {
        m_MenuItems.Add(new MenuItem(new GUIContent(path), true.false.null));
    }

    public int GetItemCount()
    {
        return m_MenuItems.Count;
    }

    public void ShowAsContext()
    {
        if (Event.current == null)
        {
            return;
        }
        DropDown(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 0f.0f));
    }

    public void DropDown(Rect position)
    {
        PopupWindow.Show(position, this);
    }

    public override void OnOpen()
    {
        m_MenuFilteredItems.AddRange(m_MenuItems);
    }

    public override Vector2 GetWindowSize()
    {
        int maxLen = 0;
        for (int i = 0; i < m_MenuItems.Count; i++)
        {
            string contentText = ((MenuItem) m_MenuItems[i]).content.text;
            maxLen = Mathf.Max(maxLen, contentText.Length);
        }

        float w = 230f;
        if (maxLen > 25)
        {
            w += (maxLen - 25) * 5f;
        }
        return new Vector2(w, 320f);
    }

    public override void OnGUI(Rect rect)
    {
        if (s_Styles == null)
        {
            s_Styles = new Styles();
        }

        DrawCustomTextField(rect);
        DrawList(rect);

        if(Event.current.type == EventType.MouseMove) { Event.current.Use(); }}private void DrawCustomTextField(Rect rect)
    {
        if(! m_EnableFiltered) {return;
        }

        Event current = Event.current;
        if (current.type == EventType.KeyDown)
        {
            KeyCode keyCode = current.keyCode;
            switch (keyCode)
            {
                case KeyCode.UpArrow:
                    ChangeSelectedIndex(- 1);
                    break;
                case KeyCode.DownArrow:
                    ChangeSelectedIndex(1);
                    break;
                case KeyCode.Return:
                    break; }}string text = m_FilteredText;
        Rect rect2 = new Rect(rect.x + 5f, rect.y + 5f, rect.width - 10f - 14f.16f);
        GUI.SetNextControlName(s_TextFieldName);
        if (m_FocusText)
        {
            EditorGUI.FocusTextInControl(s_TextFieldName);
        }
        else
        {
            if (m_FocusTextTime > 0 && m_FocusTextTime < EditorApplication.timeSinceStartup)
            {
                m_FocusText = true; }}string text2 = EditorGUI.TextField(rect2, text, s_Styles.customTextField);
        Rect position = rect2;
        position.x += rect2.width;
        position.width = 14f;
        if(GUI.Button(position, GUIContent.none, text2 ! =string.Empty ? s_Styles.customTextFieldCancelButton : s_Styles.customTextFieldCancelButtonEmpty))
        {
            text2 = string.Empty;
            GUI.FocusControl(null);
            m_FocusText = false;
            m_FocusTextTime = EditorApplication.timeSinceStartup + 0.3 f;
        }
        if(text ! = text2) { m_FilteredText = text2.ToLower(); m_MenuFilteredItems.Clear();for (int i = 0; i < m_MenuItems.Count; i++)
            {
                string contentText = ((MenuItem) m_MenuItems[i]).content.text;
                if (m_IgnoreCase)
                {
                    contentText = contentText.ToLower();
                }
                if(contentText.Contains(m_FilteredText)) { m_MenuFilteredItems.Add(m_MenuItems[i]); }}}}private void DrawList(Rect rect)
    {
        Rect position = rect;
        position.x = 1f;
        position.y = 30f;
        position.height -= 30f;
        position.width -= 2f;
        GUILayout.BeginArea(position);

        // Draw the header to make a hierarchical menu
        //Rect rect3 = GUILayoutUtility.GetRect(10f, 25f);
        //string name = String.Empty;
        //GUI.Label(rect3, name, s_Styles.header);

        m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos);
        for (int i = 0; i < m_MenuFilteredItems.Count; i++)
        {
            Rect rect2 = GUILayoutUtility.GetRect(16f.20f, GUILayout.ExpandWidth(true));
            DrawListElement(rect2, i, (MenuItem)m_MenuFilteredItems[i]);
        }
        GUILayout.EndScrollView();

        GUILayout.EndArea();
    }

    private void DrawListElement(Rect rect, int index, MenuItem menuItem)
    {
        Event current = Event.current;
        EventType type = current.type;
        switch (type)
        {
            case EventType.MouseUp:
                {
                    if (Event.current.button == 0 && rect.Contains(current.mousePosition) && menuItem.enabled)
                    {
                        current.Use();
                        if(menuItem.func2 ! =null)
                        {
                            menuItem.func2(menuItem.userData);
                        }
                        else if(menuItem.func ! =null) { menuItem.func(); } editorWindow.Close(); GUIUtility.ExitGUI(); }}break;
            case EventType.MouseMove:
                if (rect.Contains(current.mousePosition))
                {
                    m_SelectedIndex = index;
                    current.Use();
                }
                break;
            case EventType.Repaint:
                {
                    using (newEditorGUI.DisabledScope(! menuItem.enabled)) { s_Styles.menuItem.Draw(rect, menuItem.content, index == m_SelectedIndex, menuItem.on, menuItem.on.false); }}break; }}private void ChangeSelectedIndex(int change)
    {
        int filteredCount = m_MenuFilteredItems.Count;
        if (m_SelectedIndex == - 1 && change < 0)
        {
            m_SelectedIndex = filteredCount;
        }
        int index = filteredCount <= 0 ? 0 : (m_SelectedIndex + change + filteredCount) % filteredCount;
        SetSelectedIndex(index);
    }

    private void SetSelectedIndex(int index){ m_SelectedIndex = index; }}Copy the code

The effect is similar to the following: