godotengine / godot

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

`Input.is_mouse_button_pressed` stops updating when focus is lost to another window and does not recover when focus returns #96949

Open gabrieldevsouza opened 1 month ago

gabrieldevsouza commented 1 month ago

Tested versions

Reproducible in 4.3-stable for Windows. "Godot Engine v4.3.stable.official.77dcf97d8"

System information

Windows 10 - Godot v4.3.stable - Compatibility (OpenGL API 3.3.0 NVIDIA 560.81 ) - Using Device: NVIDIA - NVIDIA GeForce RTX 3070

Issue description

When using Input.is_mouse_button_pressed to detect mouse clicks, the state does not update correctly if the user releases the mouse button after game window loses focus. Specifically, if the mouse button is pressed and the window loses focus (e.g., via ALT+TAB), and the button is then released while another window has focus, Input.is_mouse_button_pressed continues to return true even after focus is returned to the game window.

The expected behavior is for Input.is_mouse_button_pressed to return false once the mouse button is released, regardless of the window's focus. If the intended behavior is to avoid updating is_mouse_button_pressed while the window is not focused, it should at least update correctly when the window regains focus. However, I believe that Input.is_mouse_button_pressed should accurately reflect the state of the mouse button press, regardless of the game window's focus state.

Recording of the bug reproduction in the video:

https://github.com/user-attachments/assets/2f37aa4e-fe6e-4363-8126-fcc9207b5b73

Steps to reproduce

  1. Create a new Godot project or open an existing one.
  2. Set up a scene that relies on Input.is_mouse_button_pressed to detect mouse clicks.
    • Eg.: Add a Label node and attach the following script to it:
      
      extends Label

func _process(_delta: float) -> void: text = str("is_mouse_button_pressed: ", Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) print("is_mouse_button_pressed: ", Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT))


3. **Prepare another window** (such as a maximized "Windows Explorer" window) capable of overlapping your game window.
4. **Run the project** in the Godot editor or export it as a standalone application.
5. **Click** with the left mouse button within the game window.
6. **Keep** the left mouse button pressed and observe the label printing `true`.
7. While still holding down the left mouse button, **press `ALT+TAB`** to switch focus to another window (e.g., a browser or file explorer).
8. Observe the console, if possible, still printing `true`. You can also use Windows window preview feature to check the game window label without giving it focus.
9. **Release the left mouse button** while the focus is on the other window.
10. Observe that the label continues printing `true`. Here, we would expect the label to print `false` since the mouse button was released.
11. **Press `ALT+TAB`** again to return focus to the game window **without clicking**.
12. Observe the label still printing `true`. Even after regaining focus, Godot does not update the `is_mouse_button_pressed` state.
13. **Click** again within the game window. Now, `is_mouse_button_pressed` will be properly updated while the game is in focus.

### Minimal reproduction project (MRP)

[is_mouse_button_pressed_bug.zip](https://github.com/user-attachments/files/16989538/is_mouse_button_pressed_bug.zip)
AThousandShips commented 1 month ago

Sounds like the same underlying problem as:

gabrieldevsouza commented 1 month ago

Sounds like the same underlying problem as:

Yes, the issues seem related, but that one is more specific as it mentions the behavior with breakpoints. The steps provided here are easier to reproduce and likely to affect more users. I recommend keeping track of both bugs, and once one is fixed, checking if the other still occurs.

Thank you very much for your attention.

AThousandShips commented 1 month ago

I'll keep this open but only because this is specific to mouse events, but otherwise it'd be the same issue and breakpoints matter little