2
0
Эх сурвалжийг харах

Merge pull request #81243 from Sauermann/fix-window-events

Fix internal events not being delivered to some Window types
Yuri Sizov 1 жил өмнө
parent
commit
8a9aa30348

+ 1 - 2
scene/gui/dialogs.cpp

@@ -42,6 +42,7 @@ void AcceptDialog::_input_from_window(const Ref<InputEvent> &p_event) {
 	if (close_on_escape && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) {
 		_cancel_pressed();
 	}
+	Window::_input_from_window(p_event);
 }
 
 void AcceptDialog::_parent_focused() {
@@ -428,8 +429,6 @@ AcceptDialog::AcceptDialog() {
 	ok_button->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed));
 
 	set_title(TTRC("Alert!"));
-
-	connect("window_input", callable_mp(this, &AcceptDialog::_input_from_window));
 }
 
 AcceptDialog::~AcceptDialog() {

+ 1 - 1
scene/gui/dialogs.h

@@ -65,11 +65,11 @@ class AcceptDialog : public Window {
 
 	static bool swap_cancel_ok;
 
-	void _input_from_window(const Ref<InputEvent> &p_event);
 	void _parent_focused();
 
 protected:
 	virtual Size2 _get_contents_minimum_size() const override;
+	virtual void _input_from_window(const Ref<InputEvent> &p_event) override;
 
 	void _notification(int p_what);
 	static void _bind_methods();

+ 1 - 2
scene/gui/popup.cpp

@@ -39,6 +39,7 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
 	if (get_flag(FLAG_POPUP) && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) {
 		_close_pressed();
 	}
+	Window::_input_from_window(p_event);
 }
 
 void Popup::_initialize_visible_parents() {
@@ -204,8 +205,6 @@ Popup::Popup() {
 	set_flag(FLAG_BORDERLESS, true);
 	set_flag(FLAG_RESIZE_DISABLED, true);
 	set_flag(FLAG_POPUP, true);
-
-	connect("window_input", callable_mp(this, &Popup::_input_from_window));
 }
 
 Popup::~Popup() {

+ 1 - 2
scene/gui/popup.h

@@ -47,14 +47,13 @@ class Popup : public Window {
 		Ref<StyleBox> panel_style;
 	} theme_cache;
 
-	void _input_from_window(const Ref<InputEvent> &p_event);
-
 	void _initialize_visible_parents();
 	void _deinitialize_visible_parents();
 
 protected:
 	void _close_pressed();
 	virtual Rect2i _popup_adjust_rect() const override;
+	virtual void _input_from_window(const Ref<InputEvent> &p_event) override;
 
 	void _notification(int p_what);
 	void _validate_property(PropertyInfo &p_property) const;

+ 9 - 4
scene/gui/popup_menu.cpp

@@ -414,9 +414,16 @@ void PopupMenu::_submenu_timeout() {
 	submenu_over = -1;
 }
 
-void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
-	ERR_FAIL_COND(p_event.is_null());
+void PopupMenu::_input_from_window(const Ref<InputEvent> &p_event) {
+	if (p_event.is_valid()) {
+		_input_from_window_internal(p_event);
+	} else {
+		WARN_PRINT_ONCE("PopupMenu has received an invalid InputEvent. Consider filtering invalid events out.");
+	}
+	Popup::_input_from_window(p_event);
+}
 
+void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
 	if (!items.is_empty()) {
 		Input *input = Input::get_singleton();
 		Ref<InputEventJoypadMotion> joypadmotion_event = p_event;
@@ -2849,8 +2856,6 @@ PopupMenu::PopupMenu() {
 	scroll_container->add_child(control, false, INTERNAL_MODE_FRONT);
 	control->connect("draw", callable_mp(this, &PopupMenu::_draw_items));
 
-	connect("window_input", callable_mp(this, &PopupMenu::gui_input));
-
 	submenu_timer = memnew(Timer);
 	submenu_timer->set_wait_time(0.3);
 	submenu_timer->set_one_shot(true);

+ 2 - 1
scene/gui/popup_menu.h

@@ -115,7 +115,6 @@ class PopupMenu : public Popup {
 
 	void _shape_item(int p_idx);
 
-	virtual void gui_input(const Ref<InputEvent> &p_event);
 	void _activate_submenu(int p_over, bool p_by_keyboard = false);
 	void _submenu_timeout();
 
@@ -194,10 +193,12 @@ class PopupMenu : public Popup {
 	void _minimum_lifetime_timeout();
 	void _close_pressed();
 	void _menu_changed();
+	void _input_from_window_internal(const Ref<InputEvent> &p_event);
 
 protected:
 	virtual void add_child_notify(Node *p_child) override;
 	virtual void remove_child_notify(Node *p_child) override;
+	virtual void _input_from_window(const Ref<InputEvent> &p_event) override;
 
 	void _notification(int p_what);
 	bool _set(const StringName &p_name, const Variant &p_value);

+ 6 - 1
scene/main/window.cpp

@@ -1559,7 +1559,12 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
 		}
 	}
 
-	if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+	// If the event needs to be handled in a Window-derived class, then it should overwrite
+	// `_input_from_window` instead of subscribing to the `window_input` signal, because the signal
+	// filters out internal events.
+	_input_from_window(p_ev);
+
+	if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL && is_inside_tree()) {
 		emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
 	}
 

+ 1 - 0
scene/main/window.h

@@ -239,6 +239,7 @@ protected:
 	virtual void _post_popup() {}
 
 	virtual void _update_theme_item_cache();
+	virtual void _input_from_window(const Ref<InputEvent> &p_event) {}
 
 	void _notification(int p_what);
 	static void _bind_methods();