-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Input system breaks if the game window loses focus when there's a mouse button down #33928
Comments
Can confirm on Windows 10 64 bits. I held a mouse button anywhere in my game (a spot without anything special), alt-tabbed, went back, could drag the title bar once but then it got stuck afterwards. The whole window decoration doesn't respond. I had a similar symptom a while back with different conditions: #15833 (comment) |
It's the same thing being discussed in that issue, it's just that the OP didn't knew what was causing it. I found out what it was because I was deliberately trying to break my UI and inputs in any possible way that could happen in real-usage cases, but if you're just using the editor you won't notice if some other window got the focus between your button down and up. Could that be the "different conditions" when it was happening to you, were you using any other software that would put its window to foreground at "random" times? |
@guineapenguin I don't remember tbh, all trace I have is the video in my comment |
@capnm but in the present case there is no way to handle what happens, isn't it? Window decorations is something pretty OS-related, games usually don't touch/use that |
@Zylann In the callback, when the window loses or gains the focus, I can stop the handling of unwanted (or try to fix-up broken) input events. In this case I think the app newer receives the mouse-button-up event. I had similar problems in glfw with modal keys. IIRC they fixed that with some heuristics. |
The issue about the gamepad is not a bug by definition, not at the process level, because (as partially explained there) the game's window isn't being sent the gamepad input events by the OS, it is instead just checking the gamepad's buttons status. Mouse position is polled the same way, even when the window isn't focused the game will know it. And you can still poll mouse and keyboard buttons statuses when the window isn't focused, it's just that the OS is "locking" and sending those input events to the focused window only, for obvious reasons. It can be considered a bug for your game but it is also something that you may want to happen, so it's more like having locked FPS by default, it only sucks when you can't unlock them, but you may also want them to be locked even if they come unlocked out of the box (and if you can't that may suck, too, because you may want the game not to use 100% of one or more cores/threads when it's not needed). For example you may want your game to process mouse movement events even when it's not focused, most processes will do so, you may want to open/view a tooltip in your browser or your game while you're doing something else in another window, without the need to click or alt-tab to the other process and back.
It's not the OS window decoration that breaks but the game window's child HWND (the game area) that gets the focus when you click on it and somehow it "locks" the mouse button as pressed on it until the focus goes to another process' window. The title bar stops receiving any kind of mouse events after you click once on the game's area (notice that the bar's control buttons just don't get mouse enter/exit events anymore, that's the same thing that happens if the mouse button is actually pressed when you move it), and Godot's control nodes stop working, too. I've never seen a process do something like this and have no idea about what Windows actually does when it's sending inputs to the HWND which has focus, but it seems to be Godot doing that at the "OS-to-process" level and nothing you can fix by managing the events that the Godot's process "outputs" to the game after that, which are the ones you have access to; you can't even work around that by making your own input system from scratch and bypassing Godot's because of the level at which the process breaks it. [Edit: I can't see any reason for wanting to process gamepad events when not focused, for the same reason you don't want keyboard events to be processed, too. It's just that this bug here just breaks the app/process and there seems to be no workaround for it. All I wrote in the first part isn't really needed for this issue and I'm aware that you guys already know these things, but I wrote it because someone may end up here from other issues and it could be helpful for them.] |
What you describe sounds similar to the linux Godot editor 'frozen' state in #29521 #27669 ... extends Node
func _notification(what):
match what:
NOTIFICATION_WM_FOCUS_IN:
print("NOTIFICATION_WM_FOCUS_IN")
NOTIFICATION_WM_FOCUS_OUT:
print("NOTIFICATION_WM_FOCUS_OUT\n")
NOTIFICATION_WM_QUIT_REQUEST:
print("NOTIFICATION_WM_QUIT_REQUEST")
NOTIFICATION_WM_MOUSE_ENTER:
print("NOTIFICATION_WM_MOUSE_ENTER")
NOTIFICATION_WM_MOUSE_EXIT:
print("NOTIFICATION_WM_MOUSE_EXIT") |
All those notifications work fine, but IsMouseButtonPressed(1) returns true when the game window gains focus again (after alt-tabbing while it was pressed and releasing it before going back to Godot). This is all I've tested today. I remember doing some more testing when I first met this bug a while ago, and even manually setting the inputs as released when the window loses focus doesn't fix it (nor does it make control nodes work again, so what's broken on the process will keep breaking stuff in the editor/game). The problem isn't caused by the alt-tabbing itself because I had also tested it by having another process get the focus while the mouse button is down and the same thing happens. |
This makes it possible to know whether the window is focused at a given time, without having to track the focus state manually using `NOTIFICATION_WM_FOCUS_IN` and `NOTIFICATION_WM_FOCUS_OUT`. This partially addresses godotengine#33928.
That doesn't happen in Linux: NOTIFICATION_WM_MOUSE_ENTER:
g.info("NOTIFICATION_WM_MOUSE_ENTER")
print("is_mouse_button_pressed(1):", Input.is_mouse_button_pressed(1)) hold LMB
cmd+tab to another os window
release LMB
cmd-tab back to godot app
click on LMB
|
Still happens in Godot 3.2 beta 5, had it during a GDScript debugging session, as the debugger kicked in when I click on something. |
I am not too familiar with Godot internals but am working on a fix for this in another engine. Here's some tips about what you guys are experiencing.
|
Please remember the appropriate time to release the capture is when all mouse buttons are released, you can verify this in other applications. A way to do this is to check the wParam of the UP mouse messages in Win32 or by checking that |
Just reporting that this is still happening in latest Godot 3.3.2 |
Still reproducible in Godot 3.3.3 on Windows 10 |
Still a problem in 3.4 and 3.5. Try holding down a mouse button and then tab away to another window and release the mouse button there. When you return to the game it still sees the mouse button as being down, even when it's not. It's a big problem in an html5 game, where just leaving the game div results in the same behavior. So a drag motion outside the div where the button is then released, will mean the game sees the mouse as still down when it returns to the div. There need to be some new method of polling button status, which report the correct result always. |
In the browser you need to use Edit: I don't know what this is but it looks like there might be a setting to enable mouse capture mode?
|
Ok, upon reading the docs it looks like this is maybe a user issue. You are expected to set the mouse to captured on your own. What you can do is handle a button press in your game, and call set mouse mode with captured. Then on button release you should set the mouse mode to not captured. That's how most SDL examples handle it online. However, Godot could probably handle a little more the mouse capturing transparently under the hood like other engines do. Especially with respect to some UI controls. https://docs.godotengine.org/en/stable/classes/class_input.html#class-input-method-set-mouse-mode |
Hello. I've already had this happening when I was using 3.1 mono on Windows 7 x64, I've tried 3.1.1 and 3.2 beta2 and it's still happening.
I'll copy/paste the details from a post I made on Reddit to ask if anyone else was experiencing this.
It does happen even with an empty project, so it shouldn't be my code. Also, when I go back to the game, the window's bar doesn't work anymore, can't drag it and its buttons don't work. They start working again if I click somewhere else (outside of the game window). Then they stop working again if I click anything within the game window, and notifications like mouse_entered and mouse_exited don't work anymore if I press a mouse button and release it after moving it.
It only happens with Godot, other programs work fine, and I've tried it on different PCs and it does that on all them. There's a few issues on GitHub about input actions not being released when the window loses focus, and the workaround for that is to check for them and release them via code. But even doing that doesn't fix this problem, the only fix for it is to restart the game.
To reproduce: run any project, even a new empty one, hold mouse button down anywhere on the game window, alt-tab, go back to the game window either by alt-tabbing or by clicking on it. Click anywhere and the window's bar will stop working, if there's any control node in the project they won't be working anymore.
The text was updated successfully, but these errors were encountered: