Change input handling order for UI elements

Godot Version

4.2.2

Question

I have a custom drop down menu that I’ve made (I’m aware there exists one already but I’ve decided against using it for reasons) and due to the way that vertical box containers work I cannot adjust the child position of the drop down menu to force it to handle inputs before buttons behind the menu without moving the moving the menu itself.

I can change the Z order which will obviously draw the drop down menu over the buttons ‘behind’ it, but I’m unsure how to force Godot to handle inputs with the drop down first so the buttons behind it do not receive mouse input while the panel is in the way.

I feel like I may be missing an obvious solution but any help would be appreciated. I’m still new to using Godot’s control node system.

1 Like

When Z index for CanvasItems was introduced, this was discussed.
Currently the Z index has no influence on input order.
See also the docs of Z-index:

You can tell a Ui elment to be top level wich will cause it to be procesed first.
You will howewer need to use code to keep its position realitive to its parent

Is this a feature we hope to have in the future?

You don’t say whether the idea was rejected on principle (as in “this is a bad idea and we will never implement it”), or was the idea merely postponed “for now” until we hopefully implement it in the future?

We can decouple the rendering order from the scene tree using z_index, and it seems just as logical to decouple the order of input handling from the scene tree somehow.

I understand there are many competing priorities, but I hope we get this feature eventually.

1 Like

When Z index for CanvasItems was introduced, this was discussed.
Currently the Z index has no influence on input order.

Well, you’re right, the documentation says:

Note: Changing the Z index of a Control only affects the drawing order, not the order in which input events are handled.

This is a very odd decision. It means that if two sprites overlap, the order they receive a mouse click depends on the tree not which one is visibly on top.

The documentation gives this example as a reason why this is desirable:

This can be useful to implement certain UI animations, e.g. a menu where hovered items are scaled and should overlap others.

But this doesn’t make sense. If a hovered item is scaled and overlaps other items, then it is both “on top” for drawing and “on top” for clicks, which means this example does not show why the current implementation has any merit. In fact it shows why it’s a bad idea, as the button that’s been scaled and brought to the front to overlap other buttons may not get the click as desired if the user clicks on the overlapping section!

<…some Googling later…>

Apparently to get the frontmost node to get mouse clicks, I have to move it on the tree! I can move a node to the ‘front’ using:

my_node.get_parent().move_child(my_node, -1)

but that’s pretty inelegant. Is there somewhere I can add my vote to making the z-index affect input events as well as drawing order?

1 Like

I made a post about this on Reddit: https://www.reddit.com/r/godot/comments/1e7jfpv/the_scenetree_is_responsible_for_too_much_render/

The SceneTree is responsible for too much I think. There is not enough separation of concerns.

Rendering order is a concern, input handling order is a concern, the order of things as related to game logic is a concern (e.g., which card is first in a stack). These are 3 separate concerns and the design of Godot encourages us to use the SceneTree to manage all 3 concerns. There is not enough separation of concern.

The z_index helps with rendering order. Using the z_index the render order can be disconnected from the SceneTree. But there are still 2 other concerns that the SceneTree must support.

Ideally players could order the SceneTree however they wanted and then use z_index and some other (not yet implemented) property to control input handling order, etc.

4 Likes

totally agree that the way it currently works is very odd. if two buttons are overlapping, 99.9% of the time you would be trying to click on the one you can actually see, not the one that’s hidden beneath it.

maybe there would be benefits to having a separately settable “control level” and “sprite display level” for that 0.1% of cases, but if it’s not going to work like that, having the control level match the display level is almost always going to do what you would want in cases where buttons are overlapping

2 Likes