Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_gui_input method doesn't take z_index into account #85305

Closed
andrueandersoncs opened this issue Nov 24, 2023 · 8 comments
Closed

_gui_input method doesn't take z_index into account #85305

andrueandersoncs opened this issue Nov 24, 2023 · 8 comments

Comments

@andrueandersoncs
Copy link

Godot version

v4.1.3 (f06b6836a)

System information

Godot v4.1.3.stable - macOS 13.3.1 - Vulkan (Forward+) - integrated Apple M1 - Apple M1 (8 Threads)

Issue description

Control nodes don't seem to take z_index into account when calculating mouse interactions. For example, if a child extends outside its parent, it can be covered by a sibling of the parent. Setting the z_index of the child fixes this, causing the child to render above the parent's sibling once again. However, the part of the child that extends outside the parent (the part that would otherwise be obscured if not for z_index) does not receive input events.

Steps to reproduce

Implement a basic scene with the following:

  1. A control to act as a grid cell with a fixed, square, custom minimum size, e.g. 50x50
  2. A GridContainer with at least 2 rows of the cells
  3. A control to receive input events with a fixed custom minimum size taller than the grid cells, e.g. 50x100 and a z_index of 2 or more
  4. The control to receive input events added as a child to a grid cell on the top row

Notice that the input event receiver renders above the grid cells on the second row but does not receive input events over the lower half of the control. It is not draggable from the lower half, it does not receive method calls to _gui_input() over the lower half.

Minimal reproduction project

N/A

@YuriSizov
Copy link
Contributor

Hi! Yes, this is expected. This is why when you change z-index on a control node, you get a configuration warning stating "Changing the Z index of a control only affects the drawing order, not the input event handling order."

@Sauermann
Copy link
Contributor

When introducing the Z index to Control nodes, this topic was discussed and at the time. See for reference #68070 and godotengine/godot-proposals#839.

@andrueandersoncs
Copy link
Author

andrueandersoncs commented Nov 25, 2023

Hi! Yes, this is expected. This is why when you change z-index on a control node, you get a configuration warning stating "Changing the Z index of a control only affects the drawing order, not the input event handling order."

Hey YuriSizov, thanks for the reply. I'm glad this is already known but that doesn't help me solve the problem?

Also, the configuration warning would only be applicable if the user is changing it in the editor. When changing it in code, no such warning exists, it just seems like a bug

@andrueandersoncs
Copy link
Author

When introducing the Z index to Control nodes, this topic was discussed and at the time. See for reference #68070 and godotengine/godot-proposals#839.

Thanks for this reply, I don't see anything in that thread discussing a way to solve this issue?

@andrueandersoncs
Copy link
Author

Also we should probably change the documentation reading:

The event won't trigger if:

  • control is obstructed by another Control on top of it, which doesn't have mouse_filter set to MOUSE_FILTER_IGNORE;

Because there's no way to know what "on top of" means for this edge case

@YuriSizov
Copy link
Contributor

YuriSizov commented Nov 26, 2023

@andrueandersoncs There is no suggestion on how to solve this because it's not an issue or a bug, it's a limitation. Z-index only changes the drawing order. Input order does not recognize the z-index property. This is done for performance reasons, and if you need to change the input order you need to move nodes in the tree rather than change the z-index.

Also, the configuration warning would only be applicable if the user is changing it in the editor. When changing it in code, no such warning exists, it just seems like a bug

This information is also available in the documentation: https://docs.godotengine.org/en/stable/classes/class_canvasitem.html#class-canvasitem-property-z-index.

But yes, we don't show configuration warnings during the runtime, it's an editor-only feature. There is a PR that tries to resolve this though, for all nodes.

@andrueandersoncs
Copy link
Author

There is no suggestion on how to solve this because it's not an issue or a bug, it's a limitation.

I appreciate the time you're taking to respond, as a software engineer I can sympathize with how exhausting it is to have to interact with users given the contextual gap. That being said, I do consider this a semantic bug. It contradicts the meaning of "on top of". How hard do you have to squint to make it make sense? is a pretty good heuristic to go by in my experience when trying to identify bugs in semantics. Even worse, their impact can be hard to quantify. Users can end up leaving without saying a word. If only there were crash reports and telemetry for "confusion" 😆

if you need to change the input order you need to move nodes in the tree rather than change the z-index

This is great for reference and I apologize for not making the context of my issue more explicit. As was noted in the previously linked issue's thread, the order of the nodes in the tree also dictates the layout of the nodes. For my situation I need the layout to stay the same. It sounds like this isn't possible as such.. I'll keep searching for a workaround, cheers and happy Monday!

@YuriSizov
Copy link
Contributor

For my situation I need the layout to stay the same.

For UI where you want to preserve the same layout you would likely need to add an extra control to capture input on top of the highlighted element, a control which is not a child of your container, but is on top of it using the tree order. It can be totally invisible and only catch input, you just need to sync its position and size with the active element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants