summaryrefslogtreecommitdiffstats
path: root/scene
diff options
context:
space:
mode:
authorMarkus Sauermann <6299227+Sauermann@users.noreply.github.com>2023-09-01 08:40:35 +0200
committerMarkus Sauermann <6299227+Sauermann@users.noreply.github.com>2023-11-14 20:29:17 +0100
commitfa02d19fd170d050bb47c4e525061bf96afdb62a (patch)
tree443063d8f1bde9711f16fa5f9b5f29155d4aa3fc /scene
parentc455cb65550c19afbbf657a1dbf9af2ca3b603da (diff)
downloadredot-engine-fa02d19fd170d050bb47c4e525061bf96afdb62a.tar.gz
Fix internal events not being delivered to some Window types
`AcceptDialog`, `Popup` and `PopupMenu` no longer subscribe to "window_input" signal, because that is only sent if it is not an internal signal. Instead they receive events in `_input_from_window`. They ensure that the event is also propagated to their super-function, just like previously the signals would be treated.
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/dialogs.cpp3
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/popup.cpp3
-rw-r--r--scene/gui/popup.h3
-rw-r--r--scene/gui/popup_menu.cpp13
-rw-r--r--scene/gui/popup_menu.h3
-rw-r--r--scene/main/window.cpp7
-rw-r--r--scene/main/window.h1
8 files changed, 22 insertions, 13 deletions
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 957a8f276e..3e827e76dc 100644
--- a/scene/gui/dialogs.cpp
+++ b/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() {
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index d5cbaaeef8..e28d6b7467 100644
--- a/scene/gui/dialogs.h
+++ b/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();
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index b16e8371a2..8369bedda9 100644
--- a/scene/gui/popup.cpp
+++ b/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() {
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index d524e448dd..25edca3657 100644
--- a/scene/gui/popup.h
+++ b/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;
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index d6b8dd0202..cf8082d137 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -378,9 +378,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;
@@ -2799,8 +2806,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);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 5d5f4a8322..3e542b5d8b 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -112,7 +112,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();
@@ -191,10 +190,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);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 2c28dc31d6..0d554de6f4 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1543,7 +1543,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);
}
diff --git a/scene/main/window.h b/scene/main/window.h
index 8a54b6c7d3..3ef8d41b1b 100644
--- a/scene/main/window.h
+++ b/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();