-
-
Notifications
You must be signed in to change notification settings - Fork 22k
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 progress dialog steals focus #97009
Fix progress dialog steals focus #97009
Conversation
fff6c76
to
b0ac658
Compare
Why PanelContainer, not a Control, or MarginContainer if you needed container? |
That's a really good point! The only reason I didn't consider it is because I don't have much experience with the GUI in Godot, and it didn’t cross my mind. I’ll make the adjustment :) |
Also that hack doesn't work, the editor still takes input: godot.windows.editor.dev.x86_64_ka0ROBQKOb.mp4Also2, if a dialog appears while loading (e.g. plugin is disabled due to script errors), it will cover the progress "dialog". |
It should not take focus if |
If we use |
b0ac658
to
08ea351
Compare
I used a
I fixed it by adjusting the node order to ensure the
That’s a limitation of this solution. I don’t think it’s possible to avoid it without using an actual window. One think I did for the "Load errors" in #96830 was to display popup only after progress is gone. Is it really a problem? Maybe that's a way to do it but it could be difficult to find every possible dialog. |
Now mouse input is blocked properly, but as you noted, you can still use shortcuts. Maybe it can be solved by a node that intercepts all input and sets it as handled? |
a08a410
to
1be429a
Compare
Following your suggestion I overrided the |
void EditorNode::input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
// Return early to avoid checking if `progress_dialog` is visible on every event, like mouse motion events. We also can return if it's an echo event, but i guess it may cause issues if the editor nodes are processing the echo events too.
// Maybe we also can use this method to block mouse input instead of using a `Control` node. Just handle them without checking if it's a key input.
if (k.is_null()) {
return;
}
// Prevent all shortcuts while the progress dialog is displayed.
// To simulate an exclusive popup.
if (progress_dialog->is_visible()) {
get_tree()->get_root()->set_input_as_handled();
}
} |
I thought about that, but since the |
You can disable the input completly for the Editor Window when the |
That would be smart :) I'll try it a bit later, thanks! |
Let's just hope that disabling the Input for the the root |
1be429a
to
14ae9ac
Compare
After some testing, For the moment, I only applied some of the suggested refactoring in |
14ae9ac
to
18d64b8
Compare
Tested with I didn't make any other changes to the 4.3 branch. IT WORKS! 😄 I also have forced the cancel button to show, just to make sure I can press it. There's a lag in the video, the buttons are just hovered when the window is not focused, but when i try to press them nothing happens and they can't be hovered again after focusing the window and the shortcut input doesn't work. Input.mp4 |
You tried directly from master? It's normal that it worked because the ProgressDialog in master is another Viewport, it's another Window. You should try the same thing with the code from the PR, when I did the same test, the cancel button did not work because now the ProgressDialog and the EditorNode are in the same Viewport. Which is the hole point to prevent a popup to steal the focus. |
This comment was marked as resolved.
This comment was marked as resolved.
Instead of changing it to a window-focus.mp4 |
I also have found another limitation. Also you will have to disable the input for all the window wrappers too, because if one of them is visible while the To reproduce this issue, make the script editor floating and then remove all the The solution is to keep the Maybe just this line can solve both issues without causing any regression later. |
18d64b8
to
a7d63a5
Compare
This should be fixed now. I added a
Check: #97009 (comment) |
Sorry for the noise, and thanks for fixing this. I have been using it with |
editor/progress_dialog.cpp
Outdated
main->set_offset(SIDE_TOP, style->get_margin(SIDE_TOP)); | ||
main->set_offset(SIDE_BOTTOM, -style->get_margin(SIDE_BOTTOM)); | ||
// Be sure it's always the very last node to prevent user interaction while the dialog is visible. | ||
get_parent()->move_child(this, get_parent()->get_child_count() - 1); |
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.
get_parent()->move_child(this, get_parent()->get_child_count() - 1); | |
get_parent()->move_child(this, -1); |
Found a new problem 🙃 |
a7d63a5
to
2fa29db
Compare
As WhalesState suggested, the solution could be to display the Another idea is to have two types of Do you think this is a good idea? |
A hack for this which may save us from adding a Maybe we will still need the host code for the Yet the This is really complicated, I don't remember i have ever seen the |
Viewport::set_embedding_subwindows: Can't change "gui_embed_subwindows" while a child window is displayed. Consider hiding all child windows before changing this value. We can disable |
Does it mean having two classes? Sounds like lots of code duplication.
tbh the dialog check is unnecessary, just reparent to current Window. Though it won't look good if the parent dialog is too small to show progress (but I think that can't normally happen). |
Any news on this? The issue is so annoying that I'm willing to accept this PR even in the current state. |
Last couple of weeks/months have been really busy for me. Unfortunately, I did not progress on this PR. I'll probably have more time in the next couple of weeks. If you want to accept this PR in it's current state or fix the last issues by yourself or create another PR based on this one, it's all good for me. |
Closing this PR, #99844 completes it. |
This should resolve the issue where the Progress Dialog steals focus while the Godot Editor is not the active window.
Initially, I tried using different window options, but it’s simply not possible to display a new popup without it appearing in front of other windows or taking focus, at least on Windows.
The solution was to replace the use of a
PopupPanel
with a simplePanelContainer
. The advantage here is that it should be faster to show or hide since no new window creation is involved. Additionally, I’ve seen suggestions in other issues/proposals to make the progress dialog less intrusive. With this approach, it could easily be moved to a corner, resized, etc., in the future, or even made non-exclusive.At first, I thought using a
PanelContainer
might cause problems since it’s not exclusive, but since the Progress Dialog is always used on the main thread, the user cannot interact with the editor while it’s displayed. Still, I used a transparent full screenPanelContainer
to prevent interactions with the mouse. The only potential issue I noticed is that a user could enter shortcuts while the progress dialog is visible, and when it closes, all queued shortcuts would be executed. I'm not sure if that could be prevented.There’s also a slight visual difference with the default theme: the progress dialog now has a shadow around it. I don’t think this is a significant issue.
Lastly, I removed a line in
WindowWrapper::WindowWrapper
that I didn’t fully understand. I assume it was intended to display theProgressDialog
centered on the current window, but I’m not sure it was functioning properly. In my tests with theScriptEditor
, even in a floating window, the progress dialog was displayed in the middle of the main editor window.Old progress dialog:

New progress dialog:
