浏览代码

Merge pull request #61842 from bruvzg/popup_fixes_sw

Rémi Verschelde 3 年之前
父节点
当前提交
ae5a962cc4
共有 5 个文件被更改,包括 69 次插入13 次删除
  1. 1 10
      scene/gui/popup.cpp
  2. 1 3
      scene/gui/popup.h
  3. 23 0
      scene/gui/popup_menu.cpp
  4. 2 0
      scene/gui/popup_menu.h
  5. 42 0
      scene/main/window.cpp

+ 1 - 10
scene/gui/popup.cpp

@@ -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 {

+ 1 - 3
scene/gui/popup.h

@@ -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;
 

+ 23 - 0
scene/gui/popup_menu.cpp

@@ -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);

+ 2 - 0
scene/gui/popup_menu.h

@@ -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);

+ 42 - 0
scene/main/window.cpp

@@ -165,14 +165,26 @@ 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;