input: accept_event in parent node breaks input in child node

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By mkx

I am observing odd behavior in Godot 3.5.1 with regards to input event propagation and accept_event. It does not seem to behave in the documented way.

Here is a simplified version of my node tree:

root
    \-- GameWorld
        \-- GameView
    \-- GameUi
        \-- ViewWithButton

According to Using InputEvent — Godot Engine (3.5) documentation in English, the way the event should propagate is:

  1. ViewWithButton
  2. GameUi
  3. GameView
  4. GameWorld
  5. root

That is indeed what happens. What does not seem to be correct, however, is the following:

I have an _input handler in GameView, which does the following:

func _input(event):
	if _should_handle_event(event):
		accept_event()

Because on this view I animate text, I allow the user to skip this animation when tapping the screen, and this should stop the event from bubbling up further. This works fine, however, as soon as I call accept_event to consume this event, not only don’t parent nodes to GameView stop receiving it, it also breaks the ViewWithButton in the node that is further down the tree, despite it still receiving it before this handler is called.

This is not a problem with the order in which _input is dispatched as I mention above; these handlers are called in the correct order with the UI view receiving the event before the game view does, but just by virtue of accepting the event, the first button click is somehow ignored by Godot until _should_handle_event(event) does not return true anymore.

This seems to imply that calling accept_event in a node higher up the tree, even if it receives the event after a node further down the tree, can break input on views further down the tree.

This makes no sense to me and I am not sure how to debug this. I tried using the Clicked Control tab in the debugger, but it’s not helpful because the click simply never arrives at the button in the UI until after _should_handle_event returns false.

I also played around with various focus on mouse_mode settings but nothing helped.

Any ideas what’s going on here?

Could this be related to focus somehow? However, the docs suggest that focus is only relevant for keyboard events, not mouse events. I also tried using different focus modes and nothing helped.

mkx | 2023-04-02 08:47

I noticed another piece of documentation that seems counter to how event propagation is documented otherwise: in _gui_input, it says: “The event won’t trigger if: […] control’s parent has mouse_filter set to MOUSE_FILTER_STOP or has accepted the event”.

I do not currently use _gui_input, but this also seems to suggest that accepting events in a node higher up the tree impacts event processing further down the tree, which is not what is document for how events propagate (children first, then parents?) How would it even be possible for a parent to first accept the event if it reaches the child first? This makes no sense to me.

mkx | 2023-04-02 09:01

I ended up circumventing the problem by pauseing the entire GameWorld node tree whenever the UI is open, which pauses animations and input events, and resume it when the UI closes. This is actually nice, because that prevents these problems from happening to begin with, but I’m still interested in understanding why it works the way it does.

mkx | 2023-04-02 13:00