-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Make mouse enter/exit notifications match mouse events #84547
Conversation
cbe6c02
to
5adf98c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your great effort! The changes are looking good so far.
The notification propagation test doesn't check for notification order, I'm not sure if it's possible to check that in a test or if it really needs to be tested.
It is possible to check the notification order. You can see a method for how to do that in the updated #83276.
However I wouldn't consider testing the notification order strictly necessary for this PR.
These tests don't cover all edgecases [...]
I believe, that the implemented set of unit-tests covers the most important cases. I will try to test the implementation before Thursday.
5adf98c
to
fd08ed7
Compare
I have created a testing project for mouse notifications: HierarchicalMouseNotifications.zip In most cases this PR works as expected. Only when switching from/to In the following video I show these. MouseNotifications.mp4The first one (top right corner):
The second one (bottom left corner):
The third one (bottom right corner) A:
The third one (bottom right corner) B (not in the video):
I noticed that in contrast to #83276, in this PR a Control with |
Yes, since this is how it works with mouse events in For changing mouse filter to/from ignore while the mouse is over it or a descendant (your 1st, 3rd, and 4th cases): I consider this intended, since setting the mouse filter to ignore means it should not receive any notifications or signals. |
For your 2nd case, when a Control is hidden (or removed) and the mouse is over it or a descendant: If we want, I could update the mouse over when a hovered Control is hidden or removed. If do we update on hide/remove then some test cases will need to be updated ( |
fd08ed7
to
add52a1
Compare
Updated to handle hiding/removing Controls when the mouse was over a descendant not updating until the mouse was over a Control. This fixes the 2nd case in the testing project (bottom left corner). The Controls hidden/removed get mouse exit immediately, and the rest of the mouse over updates the next time a mouse event occurs. |
That is good. Also it is consistent with previous behavior.
I see the following problems with this approach:
In my opinion, the description leaves room for interpretation. The description can be interpreted as: "after the successful change of the mouse-filter to ignore, the control will not receive entered/exited signals." But during the process of changing the filter from pass to ignore, the signals can be received.
The current behavior is not very robust, and considered a bug (see #40012). See also #78017, which fixed this behavior for Node2D physics nodes. The Control node case is more complex (as seen in #66625) and needs some additional changes before that can be implemented.
I can confirm this improvement. Now, just like in the Control-movement case, an additional mouse-move is necessary to cause the mouse-exited signal.
Thanks for the info, I will keep it in mind for this situation.
That change should be postponed until after #40012 gets fixed, so the current handling of hiding nodes is fine. |
I was thinking I noticed Mouse Enter/Exit Self handles I will also add a note to clarify on the Control |
add52a1
to
3aeb26a
Compare
Changed to send Added test case "[Viewport][GuiInputEvent] Mouse Enter/Exit notification when changing the mouse filter to ignore." Changing the When hovering a control and changing it to |
Great work on that, thanks! I have tested the latest changes and found only one strange case: MouseNotificationsB.mp4Testing project: "Switch between Stop and Ignore"
|
CC @mrTag if you could help test that it solves your issues too. |
LocalVector<Control *> new_mouse_over_hierarchy; | ||
LocalVector<Control *> needs_enter; | ||
LocalVector<int> needs_exit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to avoid allocations in such a hot function. @Sauermann has an idea on maybe using just references to nodes at the ends of the chain. Maybe the other vector needs something else. This is just an idea about optimization, not meant as a blocker for this PR in any case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this function (_gui_mouse_over_hierarchy
) is hot. It is only called when set_top_level()
or set_mouse_filter()
is called, and only executed if the mouse is over something.
If we want I can add a guard before the allocations that is similar to the loop below it but smaller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the mouse_over_hierarchy
contains a list of all nodes that have gotten mouse_entered
but still need a mouse_exited
. If we change this to only store the ends, we wouldn't be able to send the correct signals when the mouse filter ignore is changed, or it would be more complicated.
I just tested this PR with our game and can confirm: mouse_enter/exit works as expected and our tooltips are not broken anymore. |
`NOTIFICATION_MOUSE_ENTER` and `NOTIFICATION_MOUSE_EXIT` now includes the areas of children control nodes if the mouse filters allow it. In order to check if a Control node itself was entered/exited, the newly introduced `NOTIFICATION_MOUSE_ENTER_SELF` and `NOTIFICATION_MOUSE_EXIT_SELF` can be used. Co-authored-by: Markus Sauermann <6299227+Sauermann@users.noreply.github.com>
Changing from stop to ignore: |
3aeb26a
to
d24d73b
Compare
Updated to add Unrelated: The Control documentation seems to use |
When we discussed it, this seems to be a minor edge case and could be deferred to a followup-PR. However from my analysis, this has nothing to do with updates after the next mouse-move event, because the problem happens long before the next mouse event. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We reviewed this early today with the input team and approved it for merging. It seems to be a pretty thorough solution with extensive unit testing.
We had some doubts on whether the ENTER_SELF
and EXIT_SELF
notifications are needed, which is why they're now marked as experimental. The engine itself doesn't use them, so we can see if users start making good use of the additional functionality or if they find it too confusing.
Thanks @kitbdev and @Sauermann! Amazing work fixing a critical regression so fast during the beta stage :) |
Thanks @kitbdev for putting so much effort into this! |
Is this already in 4.2, or later? |
It's in 4.2. |
I created this based on #83276 to fix some logic and edgecases and to add some tests, since this is important for 4.2.
mouse_entered
andmouse_exited
signals #82530mouse_entered
andmouse_exited
signals #67791MOUSE_FILTER_PASS
#82182Changes:
Mouse Enter/Exit notifications go through non-Control CanvasItems to match mouse event behavior in
gui_input
.Handles Mouse Filters.
Handles changing Mouse Filters while hovering a descendant.
Handles changing Top Level in CanvasItems while hovering a descendant.
Handles removing or hiding a Control when hovering a descendant.
Simplified some logic.
Added tests.
Clarified some documentation.
Updated test case "[Viewport][GuiInputEvent] Mouse Motion changes the Control that it is over." to check both mouse enter and mouse enter self notifications.
Added test cases:
The notification propagation test doesn't check for notification order, I'm not sure if it's possible to check that in a test or if it really needs to be tested.
These tests don't cover all edgecases, so I could add more if it is wanted. Such as changing mouse filter ignore when hovering on and off, moving mouse between siblings, or moving the mouse up and down the node hierarchy when mouse filter is stop or is set to top level.