|
@@ -41,55 +41,71 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Popup::_parent_focused() {
|
|
|
- _close_pressed();
|
|
|
+void Popup::_initialize_visible_parents() {
|
|
|
+ visible_parents.clear();
|
|
|
+
|
|
|
+ Window *parent_window = this;
|
|
|
+ while (parent_window) {
|
|
|
+ parent_window = parent_window->get_parent_visible_window();
|
|
|
+ if (parent_window) {
|
|
|
+ visible_parents.push_back(parent_window);
|
|
|
+ parent_window->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
|
|
|
+ parent_window->connect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Popup::_deinitialize_visible_parents() {
|
|
|
+ for (uint32_t i = 0; i < visible_parents.size(); ++i) {
|
|
|
+ visible_parents[i]->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
|
|
|
+ visible_parents[i]->disconnect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
|
|
|
+ }
|
|
|
+
|
|
|
+ visible_parents.clear();
|
|
|
}
|
|
|
|
|
|
void Popup::_notification(int p_what) {
|
|
|
switch (p_what) {
|
|
|
case NOTIFICATION_VISIBILITY_CHANGED: {
|
|
|
if (is_visible()) {
|
|
|
- parent_visible = get_parent_visible_window();
|
|
|
- if (parent_visible) {
|
|
|
- parent_visible->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
|
|
|
- }
|
|
|
+ _initialize_visible_parents();
|
|
|
} else {
|
|
|
- if (parent_visible) {
|
|
|
- parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
|
|
|
- parent_visible = nullptr;
|
|
|
- }
|
|
|
-
|
|
|
+ _deinitialize_visible_parents();
|
|
|
emit_signal("popup_hide");
|
|
|
}
|
|
|
|
|
|
} break;
|
|
|
- case NOTIFICATION_EXIT_TREE: {
|
|
|
- if (parent_visible) {
|
|
|
- parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
|
|
|
- parent_visible = nullptr;
|
|
|
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
|
|
|
+ if (has_focus()) {
|
|
|
+ popped_up = true;
|
|
|
}
|
|
|
} break;
|
|
|
+ case NOTIFICATION_EXIT_TREE: {
|
|
|
+ _deinitialize_visible_parents();
|
|
|
+ } break;
|
|
|
case NOTIFICATION_WM_CLOSE_REQUEST: {
|
|
|
_close_pressed();
|
|
|
-
|
|
|
+ } break;
|
|
|
+ case NOTIFICATION_APPLICATION_FOCUS_OUT: {
|
|
|
+ _close_pressed();
|
|
|
} break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Popup::_close_pressed() {
|
|
|
- Window *parent_window = parent_visible;
|
|
|
- if (parent_visible) {
|
|
|
- parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
|
|
|
- parent_visible = nullptr;
|
|
|
+void Popup::_parent_focused() {
|
|
|
+ if (popped_up) {
|
|
|
+ _close_pressed();
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+void Popup::_close_pressed() {
|
|
|
+ popped_up = false;
|
|
|
+
|
|
|
+ _deinitialize_visible_parents();
|
|
|
|
|
|
call_deferred("hide");
|
|
|
|
|
|
emit_signal("cancelled");
|
|
|
-
|
|
|
- if (parent_window) {
|
|
|
- //parent_window->grab_focus();
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
void Popup::set_as_minsize() {
|
|
@@ -130,8 +146,6 @@ Rect2i Popup::_popup_adjust_rect() const {
|
|
|
}
|
|
|
|
|
|
Popup::Popup() {
|
|
|
- parent_visible = nullptr;
|
|
|
-
|
|
|
set_wrap_controls(true);
|
|
|
set_visible(false);
|
|
|
set_transient(true);
|