godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.26k stars 21.22k forks source link

Control Nodes/_gui_input() do not stop keyboard events (InputEventKey) #54714

Open srivastavaarpit121 opened 3 years ago

srivastavaarpit121 commented 3 years ago

Godot version

3.3.4.stable, 3.4.stable

System information

Windows 10 64-bit, GLES3, Nvidia GTX 1650

Issue description

My project structure is like this (included project files with more examples) -

On Main node, I have a script Main.gd. On which I use _unhandled_input(event) -

func _ready() -> void:
    $Menu.visible = false

func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_SPACE:
            $Sprite.global_position.x += 10

    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_ESCAPE:
            $Menu.visible = true

When running the game, sprite moves if I press the Space key. Which is fine. But when I press the Escape key and open up the Menu (ColorRect) node. Then pressing Space should not move the Sprite. But it does.

To be extra sure, I added a script to ColorRect and stopped event propogation manually -

func _gui_input(event: InputEvent) -> void:
    accept_event()

And even then the Sprite moved.

Note On the contrary, this does not happen if I use InputEventMouseButton/Motion instead. Everything works fine then.

Steps to reproduce

The project file I uploaded, has 3 scenes.


First scene is for demonstrating everything works fine with mouse inputs.

Only 2nd and 3rd scenes are for reproducing the bug. The steps are same in both -

  1. Run the scene.
  2. Press space to move the sprite.
  3. Sprite moves. It works.
  4. Now press escape to turn on the ColorRect node.
  5. Press space again.
  6. Sprite still moves. Which should not happen.

Minimal reproduction project

GUI Input BUG.zip

timothyqiu commented 3 years ago

_gui_input() is only for mouse input if I remember correctly. See later posts. You may call get_tree().set_input_as_handled() when the ColorRect is visible inside _input() or _unhandled_input() instead.

srivastavaarpit121 commented 3 years ago

_gui_input() is only for mouse input if I remember correctly. You may call get_tree().set_input_as_handled() when the ColorRect is visible inside _input() or _unhandled_input() instead.

I see then. So _gui_input() only receives mouse events. I think this is something not mentioned in the docs. Btw the alternative you said about stopping key events does work. Thanks! :)

Sauermann commented 2 years ago

For posterity: _gui_input() receives all InputEvents, mouse events and other events.

timothyqiu commented 2 years ago

Yeah, I understand it now. The catch is that MOUSE_FILTER_STOP only automatically stops mouse events, one still have to stop key events manually.

Zireael07 commented 2 years ago

yh, it's named MOUSE_FILTER_STOP after all, why are you expecting it to stop key events? Working as designed, or otherwise a candidate for a proposal imo

timothyqiu commented 2 years ago

In the documentation:

Use the Control.mouse_filter property to control whether a Control is notified of mouse events via Control._gui_input() callback

So I thought _gui_input() is only related to mouse events :(

Tichau commented 7 months ago

I don't receive any keyboard event in _gui_input do I need to configure it in some way ?

saierXP commented 3 months ago

I don't receive any keyboard event in _gui_input do I need to configure it in some way ?

@Tichau The control node needs to get focus in order to process keyboard input. The focus mode can be selected from none, click or all, and the grab_focus method can be used to enable a Control to process keyboard input.

The focus_mode document describes that only when focus is obtained can keyboard and gamepad input be processed.But gui_input doesn't point that out.

The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard, gamepad, and mouse signals.