-
-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix subviewports receiving gui input too early #55300
Fix subviewports receiving gui input too early #55300
Conversation
Fixed doc generation and not registering the Viewport::push_gui_input method. |
Backported the fix to 3.x in #55339. |
I tested the PR and can confirm that it fixes a bug without introducing obvious regressions. Not sure about the code, needs a review from core team. |
Looks good, up to @akien-mga to ensure its mergeable. |
Unfortunately this pull request introduces a regression. Here is a MRP:
Current behavior on master branch is, that the Label B receives the gui-input-event of the key. I would expect, that gui-input-events still reach all of the Nodes, as they did before this patch. |
2546a07
to
62070f0
Compare
Thanks for the feedback! I investigated this issue and found it is due to the focus mechanism. When a control in the subviewport grabs the focus, the main viewport nullifies its So to solve this, it must collect all viewports that are its children and find one with the focus (no more than one) and pass this event to the focused node. However, I also found that this PR does not work properly with subwindows. |
Finally got a chance to follow up on this PR and get everything fixed. At the time I started the PR I didn't aware that 4.0 has a dedicated Window class for subwindows, so I accidently copied the window event forwarding function to Originally in this PR Using four functions sounds more reasonable: The above two changes make up the above commit. Here is a small project for testing. It consists of four buttons, each in a different viewport.
Before 67bf3d3 Button 2 was unclickable because the subviewport consumed it. Here is a comparison with and without (Alpha3) this PR when I click a button then press a key for each button Press Button 1: (both the same)
Press a key when Button 1 is focused (both the same)
Press Button 2 (without the fix the event can't go to Button 2 and stops at the subviewport background):
Press a key when Button 2 is focused (without the fix Button 2 is not clickable so Button 1 still had the focus):
For window buttons the events are forwarded to the corrsponding window, so other controls won't recieve any event, as expected. This PR does not change any behavior. Press Button 3:
Press a key when Button 3 is focused
Press Button 4:
Press a key when Button 4 is focused
|
930428b
to
bddae99
Compare
* Rearrange push_input/push_unhandled_input as push_input/push_local_input/ push_local_gui_input/push_local_unhandled_input * Fix extra window event forwarding in push_gui_input * Fix code format of the last commit.
bddae99
to
bece838
Compare
|
I tested the current version bece838 and unfortunately had difficulties with the following things:
|
I believe these two issues are from somewhere else. The issues disappear after I merge the PR with the latest master. |
Btw may I ask how do you manage to come up with these test cases? Honestly I don't really think so much of them. XD |
I am glad to hear that!
Usually by just playing around and more importantly creating a Project-file, in which I gather all of them, which I did for my implementation of the patch. |
This PR and PR #58334 both solve #39666 for positional events (events that have a position parameter). ContextSince #39666 is not the only bug related to event processing, we need to consider both approaches in context of solving all event processing related issues. Here is a list of all issues I found, that put constraints on positional event processing: #39666: _gui_input in parent viewport must happen before _gui_input in child viewport. The PR #57894 also needs to be taken into account, because it solves #17326. The following graphic shows the order of positional event processing when considering the three PR. (diagrams.net Source-File) Events without position parameterEvents without position parameter (like If non-positional events were treated in the same way as positional events, the following problem appears for both combined solutions #58334 + #57894 and #55300 + #57894: This argument makes it necessary to treat positional and non-positional events differently in Additional necessary changes for solving all mentioned issuesThe combination #58334 + #57894 solves all mentioned issues. The combination #55300 + #57894 would require the following additional changes:
Architectural comparison
Finding
|
@Sauermann So you basically say that this PR should be closed and the other 2 merged, as they all fix the same issues? Do you maybe have a test project where all these changes can be easily observed? |
@KoBeWi Both approaches are valid solutions and I am not in a position to decide which is better. I just tried to give an overview of the scope of the changes. The MRP of the linked issues contain use cases for each of the problems. Also I have a test project, that contains use cases for all of them, but it is rather complex: SubViewportClick.zip |
Superseded by #58334. Thanks for the contribution and peer review! |
Issue
Fixes #48401 for 4.0, the wrong order that subviewports handle input events.
Testing project:
viewport_gui_input_fix.zip
Before this fix the order was
One consequence is that no control over a viewport can receive gui_input, as #48401
The root of the problem is that
Viewport::push_input
handles input and gui_input in succession.This is alright for the main viewport but not for subviewports.
Fix
My solution is to split
push_input
into two functionspush_input
andpush_gui_input
(as there has been apush_unhandled_input
). They are almost identical to the originalpush_input
except that one only calls_call_input_pause
and the other one calls_gui_input_event
.The main viewport enters this function from
Window::_window_input
I added
push_gui_input(p_ev);
afterpush_input(p_ev);
so the logic remains the same.Subviewports enter this function from
SubViewportContainer::input
I overrode
void SubViewportContainer::gui_input
which copied the content ofSubViewportContainer::input
except thatc->push_gui_input(ev)
instead at the end.p_event->xformed_by(xform.affine_inverse())
as the gui event has been transformed.After the fix the event order becomes
Other concerns
Viewport::push_input
has anevent_count++
at the end.I removed it from
Viewport::push_gui_input
to avoid an event being counted twice.So only
Viewport::push_input
counts the events,Viewport::push_gui_input
does not (same asViewport::push_unhandled_input
).I saw
TouchScreenButton
inscene/2d/touch_screen_button.cpp
callspush_input
as well.I have no clue why a button needs to call viewport directly.
I simply added a
push_gui_input
call after everypush_input
so the logic should remain the same as before, which means it may still suffer from this bug.I don't have the environment to test it though.
The doc Using InputEvent is wrong about the viewport order, as it says viewports process events one after another. Hopefully someone will update it before 4.0.
Bugsquad edit: