diff options
author | Markus Sauermann <6299227+Sauermann@users.noreply.github.com> | 2023-09-01 08:40:35 +0200 |
---|---|---|
committer | Markus Sauermann <6299227+Sauermann@users.noreply.github.com> | 2023-11-14 20:29:17 +0100 |
commit | fa02d19fd170d050bb47c4e525061bf96afdb62a (patch) | |
tree | 443063d8f1bde9711f16fa5f9b5f29155d4aa3fc /scene | |
parent | c455cb65550c19afbbf657a1dbf9af2ca3b603da (diff) | |
download | redot-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.cpp | 3 | ||||
-rw-r--r-- | scene/gui/dialogs.h | 2 | ||||
-rw-r--r-- | scene/gui/popup.cpp | 3 | ||||
-rw-r--r-- | scene/gui/popup.h | 3 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 13 | ||||
-rw-r--r-- | scene/gui/popup_menu.h | 3 | ||||
-rw-r--r-- | scene/main/window.cpp | 7 | ||||
-rw-r--r-- | scene/main/window.h | 1 |
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(); |