Merge pull request #61842 from bruvzg/popup_fixes_sw

This commit is contained in:
Rémi Verschelde 2022-06-13 10:51:46 +02:00 committed by GitHub
commit ae5a962cc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 13 deletions

View File

@ -108,9 +108,7 @@ void Popup::_close_pressed() {
_deinitialize_visible_parents(); _deinitialize_visible_parents();
// Hide after returning to process events, but only if we don't call_deferred(SNAME("hide"));
// get popped up in the interim.
call_deferred(SNAME("_popup_conditional_hide"));
} }
void Popup::_post_popup() { void Popup::_post_popup() {
@ -118,15 +116,8 @@ void Popup::_post_popup() {
popped_up = true; popped_up = true;
} }
void Popup::_popup_conditional_hide() {
if (!popped_up) {
hide();
}
}
void Popup::_bind_methods() { void Popup::_bind_methods() {
ADD_SIGNAL(MethodInfo("popup_hide")); ADD_SIGNAL(MethodInfo("popup_hide"));
ClassDB::bind_method(D_METHOD("_popup_conditional_hide"), &Popup::_popup_conditional_hide);
} }
Rect2i Popup::_popup_adjust_rect() const { Rect2i Popup::_popup_adjust_rect() const {

View File

@ -48,8 +48,6 @@ class Popup : public Window {
void _initialize_visible_parents(); void _initialize_visible_parents();
void _deinitialize_visible_parents(); void _deinitialize_visible_parents();
void _parent_focused();
protected: protected:
void _close_pressed(); void _close_pressed();
virtual Rect2i _popup_adjust_rect() const override; virtual Rect2i _popup_adjust_rect() const override;
@ -57,7 +55,7 @@ protected:
void _notification(int p_what); void _notification(int p_what);
static void _bind_methods(); static void _bind_methods();
void _popup_conditional_hide(); virtual void _parent_focused();
virtual void _post_popup() override; virtual void _post_popup() override;

View File

@ -243,6 +243,29 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {
} }
} }
void PopupMenu::_parent_focused() {
if (is_embedded()) {
Point2 mouse_pos_adjusted;
Window *window_parent = Object::cast_to<Window>(get_parent()->get_viewport());
while (window_parent) {
if (!window_parent->is_embedded()) {
mouse_pos_adjusted += window_parent->get_position();
break;
}
window_parent = Object::cast_to<Window>(window_parent->get_parent()->get_viewport());
}
Rect2 safe_area = DisplayServer::get_singleton()->window_get_popup_safe_rect(get_window_id());
Point2 pos = DisplayServer::get_singleton()->mouse_get_position() - mouse_pos_adjusted;
if (safe_area == Rect2i() || !safe_area.has_point(pos)) {
Popup::_parent_focused();
} else {
grab_focus();
}
}
}
void PopupMenu::_submenu_timeout() { void PopupMenu::_submenu_timeout() {
if (mouse_over == submenu_over) { if (mouse_over == submenu_over) {
_activate_submenu(mouse_over); _activate_submenu(mouse_over);

View File

@ -148,6 +148,8 @@ public:
// this value should be updated to reflect the new size. // this value should be updated to reflect the new size.
static const int ITEM_PROPERTY_SIZE = 10; static const int ITEM_PROPERTY_SIZE = 10;
virtual void _parent_focused() override;
void add_item(const String &p_label, int p_id = -1, Key p_accel = Key::NONE); void add_item(const String &p_label, int p_id = -1, Key p_accel = Key::NONE);
void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, Key p_accel = Key::NONE); void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, Key p_accel = Key::NONE);
void add_check_item(const String &p_label, int p_id = -1, Key p_accel = Key::NONE); void add_check_item(const String &p_label, int p_id = -1, Key p_accel = Key::NONE);

View File

@ -165,14 +165,26 @@ void Window::set_flag(Flags p_flag, bool p_enabled) {
embedder->_sub_window_update(this); embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) { } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
#ifdef TOOLS_ENABLED
if ((p_flag != FLAG_POPUP) || !(Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
DisplayServer::get_singleton()->window_set_flag(DisplayServer::WindowFlags(p_flag), p_enabled, window_id);
}
#else
DisplayServer::get_singleton()->window_set_flag(DisplayServer::WindowFlags(p_flag), p_enabled, window_id); DisplayServer::get_singleton()->window_set_flag(DisplayServer::WindowFlags(p_flag), p_enabled, window_id);
#endif
} }
} }
bool Window::get_flag(Flags p_flag) const { bool Window::get_flag(Flags p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
if (window_id != DisplayServer::INVALID_WINDOW_ID) { if (window_id != DisplayServer::INVALID_WINDOW_ID) {
#ifdef TOOLS_ENABLED
if ((p_flag != FLAG_POPUP) || !(Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
flags[p_flag] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(p_flag), window_id);
}
#else
flags[p_flag] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(p_flag), window_id); flags[p_flag] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(p_flag), window_id);
#endif
} }
return flags[p_flag]; return flags[p_flag];
} }
@ -255,7 +267,15 @@ void Window::_make_window() {
#endif #endif
DisplayServer::get_singleton()->window_set_title(tr_title, window_id); DisplayServer::get_singleton()->window_set_title(tr_title, window_id);
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id); DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
#ifdef TOOLS_ENABLED
if (!(Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
} else {
DisplayServer::get_singleton()->window_set_exclusive(window_id, false);
}
#else
DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive); DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
#endif
_update_window_size(); _update_window_size();
@ -441,6 +461,8 @@ void Window::set_visible(bool p_visible) {
ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child."); ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child.");
transient_parent->exclusive_child = this; transient_parent->exclusive_child = this;
} }
#else
transient_parent->exclusive_child = this;
#endif #endif
} else { } else {
if (transient_parent->exclusive_child == this) { if (transient_parent->exclusive_child == this) {
@ -488,7 +510,13 @@ void Window::_make_transient() {
window->transient_children.insert(this); window->transient_children.insert(this);
if (is_inside_tree() && is_visible() && exclusive) { if (is_inside_tree() && is_visible() && exclusive) {
if (transient_parent->exclusive_child == nullptr) { if (transient_parent->exclusive_child == nullptr) {
#ifdef TOOLS_ENABLED
if (!(Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
transient_parent->exclusive_child = this;
}
#else
transient_parent->exclusive_child = this; transient_parent->exclusive_child = this;
#endif
} else if (transient_parent->exclusive_child != this) { } else if (transient_parent->exclusive_child != this) {
ERR_PRINT("Making child transient exclusive, but parent has another exclusive child"); ERR_PRINT("Making child transient exclusive, but parent has another exclusive child");
} }
@ -531,13 +559,27 @@ void Window::set_exclusive(bool p_exclusive) {
exclusive = p_exclusive; exclusive = p_exclusive;
if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID) { if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID) {
#ifdef TOOLS_ENABLED
if (!(Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
} else {
DisplayServer::get_singleton()->window_set_exclusive(window_id, false);
}
#else
DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive); DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
#endif
} }
if (transient_parent) { if (transient_parent) {
if (p_exclusive && is_inside_tree() && is_visible()) { if (p_exclusive && is_inside_tree() && is_visible()) {
ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child."); ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child.");
#ifdef TOOLS_ENABLED
if (!(Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
transient_parent->exclusive_child = this;
}
#else
transient_parent->exclusive_child = this; transient_parent->exclusive_child = this;
#endif
} else { } else {
if (transient_parent->exclusive_child == this) { if (transient_parent->exclusive_child == this) {
transient_parent->exclusive_child = nullptr; transient_parent->exclusive_child = nullptr;