How to stop tab from losing focus on TextField?

How do I stop TAB from losing focus on my TextField and jumping to another element with input system and UI Toolkit?

The recommended code by Unity themselves doesn’t work:

uiDocument.rootVisualElement.RegisterCallback<NavigationMoveEvent>(e =>
                {
                    if (
                        e.direction == NavigationMoveEvent.Direction.Next
                        || e.direction == NavigationMoveEvent.Direction.Previous
                    )
                    {
                        e.StopImmediatePropagation(); // Doesn't work
                        e.StopPropagation(); // Doesn't work
                        e.PreventDefault(); // Doesn't work
                    }
                });

According to the docs, TAB isn’t included in the keys that trigger a move event.

In any case you need to stop propagating the event as it trickles down throught the visual element tree. The default value of the TrickleDown parameter is NoTrickleDown, meaning it will recieve the events as they bubble up, which is too late for your use case.

This works for me:

[UxmlElement]
public partial class ExampleVisualElement : VisualElement
{
	#region Constructors

	public ExampleVisualElement() : base()
	{
		_textField = new()
		{
			label = "Text Field:"
		};
		
		Add(_textField);

		this.RegisterCallback<KeyDownEvent>(HandleKeyDownEvent, TrickleDown.TrickleDown);
	}

	#endregion

	#region Internal Members

	private readonly TextField _textField;

	#endregion

	#region Internal Methods

	private void HandleKeyDownEvent(KeyDownEvent evt)
	{
		Debug.Log(evt.keyCode);
		if (evt.keyCode == KeyCode.Tab)
		{
			evt.StopImmediatePropagation();
		}
	}

	#endregion
}

You want to be registering it on a parent element to the text field, of course.

Thanks. That is weird because my code actually did fire if I log to console, but the propagation was not stopped.

Like I said, you were getting the callback as it was bubbling up, so well after the focused element had changed from hitting tab, and where stopping propagation would only stop it from further bubbling up.

Important to understand how events work: Unity - Manual: Dispatch events

1 Like