Godot: Viewport does not handle input even it "Disable Input" is off

Created on 8 Jan 2018  Â·  6Comments  Â·  Source: godotengine/godot

Godot version:

3.0, master branch, commit c791c1d48ec7dc4df30f4778eb007ad05b3686bf

OS/device including version:

Ubuntu 17.10 64bit

Issue description:

When adding a viewport to the scene, it does not receive input, even if the "Disable Input" option is off.
What is expected is for it to properly handle _input and gui_input when the "Disable Input" option is off.
Was working properly in 2.x

Steps to reproduce:

- Control (attach script here, _input properly receives events)
  - ViewportContainer
    - Viewport (attach script here, _input DOES NOT receive events)

Minimal reproduction project:

3.0 demo showing bug: viewport_input_bug.zip
2.1.4 demo showing how it should behave: viewport_input_working_2x.zip

bug core

All 6 comments

VieportContainer do no call attach_to_screen_rect which in turns disable input:
See: https://github.com/godotengine/godot/blob/master/scene/main/viewport.cpp#L1318
See: https://github.com/godotengine/godot/blob/master/scene/main/viewport.cpp#L1328
See: https://github.com/godotengine/godot/blob/master/scene/main/viewport.cpp#L1271

Calling attach_to_screen_rect from ViewportContainer does not appear to be a solution as it seems it breaks the rendering order, plus other troubles in Editor

This patch seems to fix the problem, although it might have side effects as I had to remove some set_input_has_handled() due to the changes introduced in 5da02a0d9c causing gui events on sub viewport to be blocked.
Probably not a good enough fix, but I'll leave it here as a reference. Suggestions are welcome.

diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 5f1257a85..489c8b7e8 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -42,6 +42,7 @@
 #include "scene/gui/control.h"
 #include "scene/gui/label.h"
 #include "scene/gui/panel.h"
+#include "scene/gui/viewport_container.h"
 #include "scene/main/timer.h"
 #include "scene/resources/mesh.h"
 #include "scene/scene_string_names.h"
@@ -1276,6 +1277,11 @@ Transform2D Viewport::_get_input_pre_xform() const {

        pre_xf.elements[2] = -to_screen_rect.position;
        pre_xf.scale(size / to_screen_rect.size);
+   } else if (get_parent() && !Object::cast_to<ViewportContainer>(get_parent())) {
+
+       ViewportContainer *container = Object::cast_to<ViewportContainer>(get_parent());
+       pre_xf.elements[2] = -container->get_global_rect().position;
+       pre_xf.scale(size / get_size());
    }

    return pre_xf;
@@ -1315,7 +1321,7 @@ void Viewport::_vp_input(const Ref<InputEvent> &p_ev) {
    }
 #endif

-   if (to_screen_rect == Rect2())
+   if (to_screen_rect == Rect2() && !(get_parent() && Object::cast_to<ViewportContainer>(get_parent())))
        return; //if render target, can't get input events

    //this one handles system input, p_ev are in system coordinates
@@ -1340,7 +1346,7 @@ void Viewport::_vp_unhandled_input(const Ref<InputEvent> &p_ev) {
        return;
    */

-   if (to_screen_rect == Rect2())
+   if (to_screen_rect == Rect2() && !(get_parent() && Object::cast_to<ViewportContainer>(get_parent())))
        return; //if render target, can't get input events

    //this one handles system input, p_ev are in system coordinates
@@ -1763,7 +1769,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
                _gui_call_input(gui.mouse_focus, mb);
            }

-           get_tree()->set_input_as_handled();
+           //get_tree()->set_input_as_handled();

            if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {

@@ -1835,7 +1841,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
                gui.drag_data=Variant(); //always clear
            }*/

-           get_tree()->set_input_as_handled();
+           //get_tree()->set_input_as_handled();
        }
    }

@@ -1982,7 +1988,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
            _gui_call_input(over, mm);
        }

-       get_tree()->set_input_as_handled();
+       //get_tree()->set_input_as_handled();

        if (gui.drag_data.get_type() != Variant::NIL && mm->get_button_mask() & BUTTON_MASK_LEFT) {

@@ -2025,7 +2031,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
                    touch_event->set_position(pos);
                    _gui_call_input(over, touch_event);
                }
-               get_tree()->set_input_as_handled();
+               //get_tree()->set_input_as_handled();
                return;
            }
        } else if (gui.mouse_focus) {
@@ -2037,7 +2043,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {

                _gui_call_input(gui.mouse_focus, touch_event);
            }
-           get_tree()->set_input_as_handled();
+           //get_tree()->set_input_as_handled();
            return;
        }
    }
@@ -2063,7 +2069,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
                gesture_event->set_position(pos);
                _gui_call_input(over, gesture_event);
            }
-           get_tree()->set_input_as_handled();
+           //get_tree()->set_input_as_handled();
            return;
        }
    }
@@ -2101,7 +2107,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
                _gui_call_input(over, drag_event);
            }

-           get_tree()->set_input_as_handled();
+           //get_tree()->set_input_as_handled();
            return;
        }
    }
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 48e2929e5..04506c776 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -49,6 +49,7 @@ class Panel;
 class Label;
 class Timer;
 class Viewport;
+class ViewportContainer;

 class ViewportTexture : public Texture {

would it not be better to create input handlers in ViewportContainer and pass them?

would it not be better to create input handlers in ViewportContainer and pass them?

I thought ViewportContainer's input would be dependant on the current focus status (it being a Control inside another Viewport). In this case we want the viewport input to be called nevertheless.

I might be mistaken though, as I don't grasp yet the full picture of input handling in Godot.

Just using _input, transforming the events by inverse global matrix and
passing them

On Jan 12, 2018 5:35 PM, "Fabio Alessandrelli" notifications@github.com
wrote:

would it not be better to create input handlers in ViewportContainer and
pass them?

I thought ViewportContainer's input would be dependant on the current
focus status (it being a Control inside another Viewport). In this case
we want the viewport input to be called nevertheless.

I might be mistaken though, as I don't grasp yet the full picture of input
handling in Godot.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/15488#issuecomment-357338383,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF-Z26QmFnOh9H4t8wc7901GsnF1u7kJks5tJ78PgaJpZM4RWgaU
.

is this issue what is causing viewports as a texture on a 3d quad to not receive input or was that never something that was supposed to work?

Was this page helpful?
0 / 5 - 0 ratings