godotengine / godot

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

`NOTIFICATION_APPLICATION_FOCUS_IN / OUT` doesn't trigger with Alt + Tab when a popup is open #63405

Open YeldhamDev opened 1 year ago

YeldhamDev commented 1 year ago

Godot version

4.0.dev (887a606)

System information

Kubuntu GNU/Linux, X11

Issue description

When unfocusing the window (be it in-game on in-editor) while a popup is open using Alt + Tab, the NOTIFICATION_APPLICATION_FOCUS_IN/OUT notification isn't sent. This can cause bugs like the popup not hiding until you click on something.

Steps to reproduce

Notice how the popup will still be opened.

Minimal reproduction project

No response

YuriSizov commented 1 year ago

Am I doing it right? If so, can't reproduce it with the current master (3bd74cd) on Windows.

https://user-images.githubusercontent.com/11782833/180793812-ee93a921-70aa-4a6d-94cf-56001fecb9ff.mp4

YeldhamDev commented 1 year ago

Am I doing it right? If so, can't reproduce it with the current master (https://github.com/godotengine/godot/commit/3bd74cd67bfc5484b3f5d4b47da66c55457474c7) on Windows.

Could be a specific problem on Godot's X11 code, which is still quite buggy.

MatthewZelriche commented 1 year ago

Note: I haven't used X11's override_redirect functionality much in the past, so I hope this information is correct.

I believe the reason this occurs has to do with how popup windows are handled by DisplayServerX11:

https://github.com/godotengine/godot/blob/58f8f3a40e8b068b9f7b92cae21e0cabb406dd07/platform/linuxbsd/display_server_x11.cpp#L4420-L4429

Popup windows are set here to have the override_redirect flag. In X11, this means that we are requesting the window manager to not interfere with our window at all, to allow for greater control. As a result, popup windows never trigger FocusIn or FocusOut X11 events. This is important because WindowData is initialized with focused = true, so the display server believes that popup windows are always focused, when in fact they never are. As a result, the following code that checks whether any of the application's windows have focus:

https://github.com/godotengine/godot/blob/58f8f3a40e8b068b9f7b92cae21e0cabb406dd07/platform/linuxbsd/display_server_x11.cpp#L3413-L3421

will fail to recognize that the application has lost focus, and the NOTIFICATION_APPLICATION_FOCUS_OUT is never sent for as long as a popup window exists.

The solution is trivial or possibly complex, depending on the intended behavior of Godot's popup windows. If popup windows indeed are never meant to have focus, the fix is trivial. If, however, popup windows are supposed to take focus and generate focus events, the fix may become complex, due to the nature of override_redirect windows. I am not sure how such a thing would be accomplished.

hakro commented 1 month ago

Also happening on Wayland, and by switching to another window by clicking on it on the KDE task bar, instead of Alt + tab

Screencast_20240507_205741.webm

My specs : Godot v4.3.dev (55b8724bd) - TUXEDO OS 3 22.04.4 - Wayland - GLES3 (Compatibility) - Mesa Intel(R) Graphics (RPL-P) () - 13th Gen Intel(R) Core(TM) i7-13700H (20 Threads)