Disabling the Tab Focus System

Hello everyone,

in our project we are using Unity 2022.1.1f1 as well as the UI Toolkit. However, we don’t want the built-in functionality of switching focus between different elements by pressing Tab, as this Key is used for something else. How can we easily disable the tab functionality for all our UI?

I know that setting the tabindex of focusable Visual Elements to -1 prevents them from being focused when tab is pressed, but for us, it is not feasible to manually change this in all current and future uxml files. Is there a more simple way to disable this functionality?

Furthermore, before we upgraded to Unity 2022.1.1f1 from 2021.2.2f1 we didn’t have this problem, as pressing tab didn’t seem to focus TextFields and Scrollers as it does now. Has there been a change to the focusing logic, that I’m not aware of?

1 Like

I have reported this as a bug (1398890) but they closed the ticket and said this:

2 Likes

Thanks for the reply, unfortunately, the solution offered by Unity does not work in my case.
On the one hand, the Direction.Previous and Direction.Next Enum values do no exist, meaning the code does not compile. But even when I remove the direction check and stop the propagation of all events, the code does not help.

Regardless, it is a bit disheartening that a solution like that is even required. I’d be very happy if there was a better solution / working solution for this problem.

Update: I was able to “disable” the tab focus system by putting the following code into the update loop. This works for our use case, but is obviously just a dirty workaround.

if (UnityEngine.Input.GetKey(KeyCode.Tab)) {
  // The workaround basically un-focuses anything that unity could have focused when tab is pressed
  _document.rootVisualElement.focusController.focusedElement?.Blur();
}

You don’t have to do this manually. You could let a python/php/perl script do that for you, or you can do it in the C# code like so:

    public static void disableTAB(VisualElement el)
    {
        el.tabIndex = -1;

        foreach (var child in el.Children())
        {
            disableTAB(child);
        }
    }

Thanks for the suggestions. I thought of a solution like that as well, but I presumed that it wouldn’t work when TemplateContainers with TextFields or TextFields themselves are instantiated and added during runtime.

When I tested a similar snippet of code in my Start() method, it didn’t change anything, probably because of the aforementioned reason: Most of our UI is created during runtime and changes quite often.

Should work.

private IEnumerator Start()
{
 
yield return new WaitForEndOfFrame();

// code here
}

You can also try calling this on GeometryChange event.