Single-window mode popups and edited scene windows fixes.
Fix single-window mode popup not closing when OptionBox is clicked. Fix single-window mode submenus closing when parent menu item, that was used to open it is clicked (using same safe-area logic as platform specific code). Disallow windows that are part of an edited scene from being set as exclusive or popup to prevent it from locking up the editor.
This commit is contained in:
parent
803d25a20a
commit
f7269fe878
|
@ -108,9 +108,7 @@ void Popup::_close_pressed() {
|
|||
|
||||
_deinitialize_visible_parents();
|
||||
|
||||
// Hide after returning to process events, but only if we don't
|
||||
// get popped up in the interim.
|
||||
call_deferred(SNAME("_popup_conditional_hide"));
|
||||
call_deferred(SNAME("hide"));
|
||||
}
|
||||
|
||||
void Popup::_post_popup() {
|
||||
|
@ -118,15 +116,8 @@ void Popup::_post_popup() {
|
|||
popped_up = true;
|
||||
}
|
||||
|
||||
void Popup::_popup_conditional_hide() {
|
||||
if (!popped_up) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void Popup::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("popup_hide"));
|
||||
ClassDB::bind_method(D_METHOD("_popup_conditional_hide"), &Popup::_popup_conditional_hide);
|
||||
}
|
||||
|
||||
Rect2i Popup::_popup_adjust_rect() const {
|
||||
|
|
|
@ -48,8 +48,6 @@ class Popup : public Window {
|
|||
void _initialize_visible_parents();
|
||||
void _deinitialize_visible_parents();
|
||||
|
||||
void _parent_focused();
|
||||
|
||||
protected:
|
||||
void _close_pressed();
|
||||
virtual Rect2i _popup_adjust_rect() const override;
|
||||
|
@ -57,7 +55,7 @@ protected:
|
|||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
void _popup_conditional_hide();
|
||||
virtual void _parent_focused();
|
||||
|
||||
virtual void _post_popup() override;
|
||||
|
||||
|
|
|
@ -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() {
|
||||
if (mouse_over == submenu_over) {
|
||||
_activate_submenu(mouse_over);
|
||||
|
|
|
@ -148,6 +148,8 @@ public:
|
|||
// this value should be updated to reflect the new size.
|
||||
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_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);
|
||||
|
|
|
@ -165,15 +165,27 @@ void Window::set_flag(Flags p_flag, bool p_enabled) {
|
|||
embedder->_sub_window_update(this);
|
||||
|
||||
} 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);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::get_flag(Flags p_flag) const {
|
||||
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
return flags[p_flag];
|
||||
}
|
||||
|
||||
|
@ -255,7 +267,15 @@ void Window::_make_window() {
|
|||
#endif
|
||||
DisplayServer::get_singleton()->window_set_title(tr_title, 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);
|
||||
#endif
|
||||
|
||||
_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.");
|
||||
transient_parent->exclusive_child = this;
|
||||
}
|
||||
#else
|
||||
transient_parent->exclusive_child = this;
|
||||
#endif
|
||||
} else {
|
||||
if (transient_parent->exclusive_child == this) {
|
||||
|
@ -488,7 +510,13 @@ void Window::_make_transient() {
|
|||
window->transient_children.insert(this);
|
||||
if (is_inside_tree() && is_visible() && exclusive) {
|
||||
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;
|
||||
#endif
|
||||
} else if (transient_parent->exclusive_child != this) {
|
||||
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;
|
||||
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (transient_parent) {
|
||||
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.");
|
||||
#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;
|
||||
#endif
|
||||
} else {
|
||||
if (transient_parent->exclusive_child == this) {
|
||||
transient_parent->exclusive_child = nullptr;
|
||||
|
|
Loading…
Reference in New Issue