-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
Fix project manager stealing focus on i3 #96829
Fix project manager stealing focus on i3 #96829
Conversation
I tested this PR and confirmed that it fixes #95824; however, when using F1 to open the Search Help popup, the search bar no longer automatically gets focus. |
Hm. I'm able to reproduce this, but only if the code editor is what is focused when I press F1. If the 2D or 3D viewport is showing, it works fine. I think perhaps the |
e4614cd
to
8333b63
Compare
My latest push adds the same fix to |
The latest modification solved this issue for me as well. |
8333b63
to
b1871cd
Compare
Window focused_window; | ||
int focus_ret_state; | ||
XGetInputFocus(x11_display, &focused_window, &focus_ret_state); | ||
|
||
return wd.x11_window == focused_window; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we update wd.focused
accordingly after doing this synchronous check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My personal inclination would be not to update wd.focused
here.
There's a bunch of other state that changes when the FocusIn
and FocusOut
events are received, and unless we're going to also run all of that, I don't want to just change wd.focused
, which could lead to the internal state of DisplayServerX11
being temporarily inconsistent (temporary, because everything else will get changed when the event finally comes in).
But if other folks who are more expert in this code (ex @bruvzg) think it would be better to update wd.focused
here, I'd be happy to defer to their judgement and update the PR :-)
Thanks! |
Fixes #95824
TL;DR: This fix isn't ideal, but I think it's probably OK.
Here's what's going on in detail:
LineEdit
, onNOTIFICATION_DRAW
(which happens every time the cursor blinks), if theLineEdit
is focused, it will callDisplayServer::window_set_ime_active()
which will grab focus for the window theLineEdit
is inControl::has_focus()
only checks if the control is focused according to Godot and doesn't check if the window is focused, this can steal focus back to Godot as soon as the cursor blinks againDisplayServer::window_is_focused()
FocusOut
event to mark a window as not focused, and these events come in asynchronously, creating a race condition. What happens is focus switches away from the project manager window, but before theFocusOut
event is received,LineEdit
's cursor blinks and it still thinks it's window is focusedDisplayServer::window_is_focused()
to do a synchronous check to see if the window is really focused right nowThis isn't ideal for a couple reasons:
WindowData::focused
flag (which we update in response to the X11FocusIn
andFocusOut
events) which is used in a whole bunch of other places. However, I think this is OK, because those other places don't seem to be sensitive to similar race conditions, and it sort of makes sense that if we callDisplayServer::window_is_focused()
then we probably want the most up-to-date data.display_server_x11.cpp
, it has ventured into theLineEdit
andTextEdit
nodes. But the only possible fix that I could come up with entirely withindisplay_server_x11.cpp
would be to revert PR Fix text editor stealing focus from "Find in Files" dialog on X11 #93682, but that would cause problems with Gnome and KDE. However, I think this fix is OK, because the whole idea of grabbing focus inNOTIFICATION_DRAW
seems a little problematic in the first place - adding some extra protections around that makes sense to me.Please let me know what you think!