Search Issue Tracker

By Design

Votes

3

Found in

2020.3.44f1

2021.3.18f1

2022.2.5f1

2023.1.0b2

Issue ID

UUM-26089

Regression

No

“RegisterCallback<KeyUpEvent>” and “RegisterCallback<KeyDownEvent>“ callbacks are not called when pressing keys in a UI Toolkit window

-

How to reproduce:
1. Open the user’s attached “TestJSONImport.zip” project
2. Open Menu > Test > KeyUpEventTest
3. Press the “Q”, “W”, “E”, “R”, “T”, or “Y” key
4. Observe the Console window

Expected result: Pressed key is printed
Actual result: Editor tools (Hand Tool, Move, Rotate) are selected and the pressed key is not printed

Reproducible with: 2020.3.44f1, 2021.3.18f1, 2022.2.5f1, 2023.1.0b2

Reproduced on: macOS 12.4 (Intel)

Note: If focusing on the “Text Field” Input Field and doing the 3rd and 4th steps the key is printed in the Console window

  1. Resolution Note:

    By default a visual element doesn't receive keyboard events.

    Only elements that are focusable and currently being focused will targeted for keyboard events (since keyboard events are trickling down and bubbling up so parent elements of the element can receive them too).

    In short, marking the element "focusable=true" and giving it explicit focus with "element.Focus()" should be enough to start receiving keyboard events.

    In the future we will improve this documentation page to mention this concept.
    https://docs.unity3d.com/2022.2/Documentation/Manual/UIE-Keyboard-Events.html

Comments (3)

  1. _geo__

    Oct 10, 2024 10:39

    For those in need:

    using UnityEngine;
    using UnityEditor;
    using UnityEditor.EditorTools;
    using System;

    namespace Kamgam
    {
    /// <summary>
    /// Thanks to https://forum.unity.com/threads/4-6-editorapplication-modifierkeyschanged-how-to-find-out-which-key-was-pressed.357367/#post-2705846
    /// 7+ years later and we still need this.
    /// </summary>
    [InitializeOnLoad]
    public static class GlobalKeyEventHandler
    {
    public static event Action<Event> OnKeyEvent;
    public static bool RegistrationSucceeded = false;

    static GlobalKeyEventHandler()
    {
    RegistrationSucceeded = false;
    string msg = "";
    try
    {
    System.Reflection.FieldInfo info = typeof(EditorApplication).GetField(
    "globalEventHandler",
    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic
    );
    if (info != null)
    {
    EditorApplication.CallbackFunction value = (EditorApplication.CallbackFunction)info.GetValue(null);

    value -= onKeyPressed;
    value += onKeyPressed;

    info.SetValue(null, value);

    RegistrationSucceeded = true;
    }
    else
    {
    msg = "globalEventHandler not found";
    }
    }
    catch (Exception e)
    {
    msg = e.Message;
    }
    finally
    {
    if (!RegistrationSucceeded)
    {
    Debug.LogWarning("GlobalKeyEventHandler: error while registering for globalEventHandler: " + msg);
    }
    }
    }

    private static void onKeyPressed()
    {
    OnKeyEvent?.Invoke(Event.current);
    }
    }
    }

  2. _geo__

    Sep 24, 2024 20:09

    This design decision is bonkers.

    Example: if you want to make an editor window that uses shortcuts you have to artificially focus and element just to get key events which a very brittle way of doing this due to inputs also requiring (and sometimes stealing) the focus. You should provide and easy way of getting global key events while the user focus is INSIDE the editor window. Not matter what specific element is currently focused.

  3. Dhaegon

    Feb 10, 2023 03:53

    This makes it really hard to create custom editors using UI Toolkit when I can't rely on key events to fire.

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.