summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scene/gui/popup.cpp68
-rw-r--r--scene/gui/popup.h9
2 files changed, 49 insertions, 28 deletions
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 5fc5f9b669..390ad30c4c 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -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);
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 97c08095d3..3e5b89ccf3 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -33,12 +33,19 @@
#include "scene/main/window.h"
+#include "core/local_vector.h"
+
class Popup : public Window {
GDCLASS(Popup, Window);
- Window *parent_visible;
+ LocalVector<Window *> visible_parents;
+ bool popped_up = false;
void _input_from_window(const Ref<InputEvent> &p_event);
+
+ void _initialize_visible_parents();
+ void _deinitialize_visible_parents();
+
void _parent_focused();
protected: