From 56ddf89fac84cdf12b571866790b492d2f6cc072 Mon Sep 17 00:00:00 2001 From: Markus Sauermann <6299227+Sauermann@users.noreply.github.com> Date: Thu, 31 Mar 2022 12:01:04 +0200 Subject: [PATCH] Adjust SubViewportContainer event handling Change SubViewportContainer, so that it processes events with a position property no longer in 'input', but in 'gui_input'. This fixes the issue, that Nodes within its SubViewport receive MouseButton events before other Control-Nodes. --- scene/gui/subviewport_container.cpp | 41 ++++++++++++++++++++++++----- scene/gui/subviewport_container.h | 3 +++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 3ad84cbc6d7e..5f49c2271bcc 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -180,24 +180,51 @@ void SubViewportContainer::input(const Ref &p_event) { return; } - Transform2D xform = get_global_transform_with_canvas(); + if (_is_propagated_in_gui_input(p_event)) { + return; + } - if (stretch) { - Transform2D scale_xf; - scale_xf.scale(Vector2(shrink, shrink)); - xform *= scale_xf; + _send_event_to_viewports(p_event); +} + +void SubViewportContainer::gui_input(const Ref &p_event) { + ERR_FAIL_COND(p_event.is_null()); + + if (Engine::get_singleton()->is_editor_hint()) { + return; } - Ref ev = p_event->xformed_by(xform.affine_inverse()); + if (!_is_propagated_in_gui_input(p_event)) { + return; + } + if (stretch && shrink > 1) { + Transform2D xform; + xform.scale(Vector2(1, 1) / shrink); + _send_event_to_viewports(p_event->xformed_by(xform)); + } else { + _send_event_to_viewports(p_event); + } +} + +void SubViewportContainer::_send_event_to_viewports(const Ref &p_event) { for (int i = 0; i < get_child_count(); i++) { SubViewport *c = Object::cast_to(get_child(i)); if (!c || c->is_input_disabled()) { continue; } - c->push_input(ev); + c->push_input(p_event); + } +} + +bool SubViewportContainer::_is_propagated_in_gui_input(const Ref &p_event) { + // Propagation of events with a position property happen in gui_input + // Propagation of other events happen in input + if (Object::cast_to(*p_event) || Object::cast_to(*p_event) || Object::cast_to(*p_event) || Object::cast_to(*p_event)) { + return true; } + return false; } void SubViewportContainer::unhandled_input(const Ref &p_event) { diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h index 63a58b5f0781..adfdbaadac1b 100644 --- a/scene/gui/subviewport_container.h +++ b/scene/gui/subviewport_container.h @@ -39,6 +39,8 @@ class SubViewportContainer : public Container { bool stretch = false; int shrink = 1; void _notify_viewports(int p_notification); + bool _is_propagated_in_gui_input(const Ref &p_event); + void _send_event_to_viewports(const Ref &p_event); protected: void _notification(int p_what); @@ -49,6 +51,7 @@ class SubViewportContainer : public Container { bool is_stretch_enabled() const; virtual void input(const Ref &p_event) override; + virtual void gui_input(const Ref &p_event) override; virtual void unhandled_input(const Ref &p_event) override; void set_stretch_shrink(int p_shrink); int get_stretch_shrink() const;