A few questions

Q1. How to focus a panel at runtime?
6150463--671851--upload_2020-7-30_21-28-50.png

Panel A, the toolbar panel panel exists, it has like textfields etc.
Panel B, the console overlay is by default hidden, but can be shown (like above image) at times.

The problem I’m running into is, if the textfield in Panel A is focused when I load the console, it keeps focus in the EventSystem (input), even if the textfield is set to Focus on the new panel (because I’ve realized Focus() appears to be local to panel.)

Reading EventSystem I feel like I could do this with a little reflection by setting focused Panel but as I’m not super experienced with this, I wanted to check before I started hacking away at a solution if there was a better way?

Q2. How do I make a VisualElement stop all events passing through to another panel?
In above example, I can still click on the buttons behind the top panel.
I can kind of stop this by using this extension method

        public static void BlockInputEvents(this VisualElement element)
        {
            element.RegisterCallback<MouseDownEvent>(StopPropagation);
            element.RegisterCallback<MouseUpEvent>(StopPropagation);
            element.RegisterCallback<KeyDownEvent>(StopPropagation);
            element.RegisterCallback<KeyUpEvent>(StopPropagation);
        }

        private static void StopPropagation(EventBase e)
        {
            e.StopPropagation();
        }

//
var root = this.document.rootVisualElement;
root.BlockInputEvents();

But is there a better way?

Q3. How do I prevent a key being sent to a text field?

I thought I could could this by stopping the KeyDownEvent either on the actual TextField or the TextInput but neither worked

this.inputField = root.Q<TextField>(InputName);
this.inputField.RegisterCallback<KeyDownEvent>(evt =>
{
    if (evt.keyCode == CoreSettings.Instance.ShowConsole)
    {
        evt.PreventDefault();
    }
});

this.inputFieldInput = this.inputField.Q(TextField.textInputUssName);
this.inputFieldInput.RegisterCallback<KeyDownEvent>(evt =>
{
    if (evt.keyCode == CoreSettings.Instance.ShowConsole)
    {
        evt.PreventDefault();
    }
});

I kind of hacked this behaviour by setting this.inputField.isReadOnly on keydown, and unsetting it on keyup… seems like a pretty silly workaround though.

Thanks in advanced!

It sounds to me that you’re still using the unreleased and now obsolete com.unity.ui.runtime package. If that’s the case, please uninstall it and install the new com.unity.ui package. More info here:

I think the above issue was solved in the new implementation of runtime, where Panels are now assets (in the form of PanelSettings asset) and what you have in the scene are UIDocument components that can share a Panel. There’s no reason why you should need 2 panels to do a console window on top of another part of your UI. You do all this in the same panel, by just displaying a different subtree of elements on top of the existing elements. Focus would then be handled properly by default.

I am not. I am using “com.unity.ui”: “1.0.0-preview.6”,

They are separate panels because they are separate packages with no knowledge about each other. For ease of use the debug library is designed to be completely standalone with no setup required that we can just import into any project and it just works. Hence it sets itself up on its own panel with a really high sort layer and is stripped in release builds.

You can’t really expect all packages (especially on asset store) to be designed to share the same root panel?

1 Like

I see. Then here’s what we recommend you try:

  1. PanelSettings asset should have a Sort Order setting you can use to make sure your Debug panel is always on top.
  2. Behind all your debug UI, you can have a VisualElement that takes up the entire screen using absolute positioning and left/right/top/bottom set to 0. This “layer” element can prevent all events from passing through the Debug UI. The Panel’s Sort Order should also be the order in which Events are passed from Panel to Panel so if you prevent the propagation of all mouse and keyboard events, they should no longer be received by the Panels behind.