Skip to content
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

Close focused Popup when the main window loses focus #91455

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

francoa
Copy link

@francoa francoa commented May 2, 2024

Fixes 91450

Important Note: I've just started checking out Godot's code like a week ago, so it's totally possible that I've failed to notice some unintended consequences of this change proposal. My idea was to close the top-most focused popup whenever the window loses focus.

@francoa francoa requested a review from a team as a code owner May 2, 2024 11:58
@Chaosus Chaosus added this to the 4.3 milestone May 2, 2024
@AThousandShips
Copy link
Member

Your commit seems not to be linked to your GitHub account. See: Why are my commits linked to the wrong user? for more info.

@francoa francoa force-pushed the fix_x11_overlaying_popupmenu branch from dfc8503 to d32810f Compare May 2, 2024 12:58
@AThousandShips
Copy link
Member

AThousandShips commented May 2, 2024

This is supposed to be handled in Popup itself, so I think the error here is that the display server doesn't properly deliver the NOTIFICATION_APPLICATION_FOCUS_OUT notification

godot/scene/gui/popup.cpp

Lines 107 to 111 in 06d105e

case NOTIFICATION_APPLICATION_FOCUS_OUT: {
if (!is_in_edited_scene_root() && get_flag(FLAG_POPUP)) {
_close_pressed();
}
} break;

It also works correctly on Windows, and I can't find any dedicated code like this on Windows

@francoa francoa force-pushed the fix_x11_overlaying_popupmenu branch from d32810f to 5bb8b92 Compare May 2, 2024 13:07
@francoa
Copy link
Author

francoa commented May 2, 2024

Your commit seems not to be linked to your GitHub account.

@AThousandShips Thanks for noticing! Email modified and commit signed!

This is supposed to be handled in Popup itself, so I think the error here is that the display server doesn't properly deliver the NOTIFICATION_APPLICATION_FOCUS_OUT notification

Yeah, sounds logical. I tried to follow that route at first, but didn't reach to any conclusion. I'll give it another go

@AThousandShips
Copy link
Member

AThousandShips commented May 2, 2024

This is indeed the necessary fix, this change would be breaking other things potentially, notice that this:

if (!app_focused) {
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
}
app_focused = true;
}

Has no equivalent in FocusOut so that's probably what's missing

Probably something in this code that's broken:

if (app_focused) {
//verify that one of the windows has focus, else send focus out notification
bool focus_found = false;
for (const KeyValue<WindowID, WindowData> &E : windows) {
if (E.value.focused) {
focus_found = true;
break;
}
}
if (!focus_found) {
uint64_t delta = OS::get_singleton()->get_ticks_msec() - time_since_no_focus;
if (delta > 250) {
//X11 can go between windows and have no focus for a while, when creating them or something else. Use this as safety to avoid unnecessary focus in/outs.
if (OS::get_singleton()->get_main_loop()) {
DEBUG_LOG_X11("All focus lost, triggering NOTIFICATION_APPLICATION_FOCUS_OUT\n");
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
}
app_focused = false;
}
} else {
time_since_no_focus = OS::get_singleton()->get_ticks_msec();
}
}

Possibly related:

@Sauermann
Copy link
Contributor

Related to: #68447

@@ -380,6 +380,7 @@ class DisplayServerX11 : public DisplayServer {
void _window_changed(XEvent *event);

public:
bool close_top_popup();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't need to be public, so it would be better to make it private.
Private functions in this C++ code base are supposed to start with an underscore "_".

Since the return value is not used, the function definition should be void instead of bool.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current solution is almost certainly not the right one so don't think this detail is something to fix at the moment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Popup window remains visible after alt+tab from editor in x11
4 participants