Godot version: 3.0 stable, mono 5.4.1.7
OS/device including version:
Win 8.1
Issue description:
The mouse_exited() signal has the following description in the docs:
http://docs.godotengine.org/en/3.0/classes/class_control.html
Emitted when the mouse leaves the control鈥檚 Rect area, provided its mouse_filter lets the event reach it.
And for NOTIFICATION_MOUSE_EXIT:
Sent when the mouse pointer exits the node鈥檚 Rect area.
Well, that's not the case. The signal and notification are also emitted from control A when the cursor goes to another control B inside and children of A. The behavior is the same whether B has MouseFilter set to Stop or more surprisingly to Pass.
I am guessing that the issue comes from the fact that an object with MouseFilter set to pass only transmit click events and not all mouse events. (according to MouseFilter Pass documentation).
My use case is a small menu that should disappear when the
mouse_exited[1].zip
cursor moves outside. Ideally I would just call queue_free when mouse_exited is received, but in reality this cause the menu to disappear when the mouse moves to a button of the menu.
I tried to add a check to the mouse_exited() event: call queue_free only when mouse_exited() is sent AND the mouse is actually outside of the menu's rect. This does not work either: moving quickly from a button to outside of the menu means that the mouse is never registered as having entered the menu's control, so mouse_exited() is never called.
The first workaround that I found is to check for the cursor's position relative to the control's rect inside _Process(delta) which is very very ugly.
Another one is to add a control that pass mouse clicks on top of the menu, but that's not really clean either.
The best solution would be to have control with mouseFilter set to Pass to pass all mouse info and not only clicks.
The less good solution would be to correct the docs of mouse_exited(), NOTIFICATION_MOUSE_EXIT, mouse_entered() and NOTIFICATION_MOUSE_ENTER.
Steps to reproduce:
Create any control (parentControl)
Create another control inside it (childControl)
set childControl's mouseFilter property to "Pass"
parentControl's mouse_exited() signal fires when the cursor is moved from parentControl to childControl
Minimal reproduction project:
mouse_exited.zip
I'm experiencing the same problem. 3.1.1 stable mono. Any updates / workarounds for this?
Same here, having a way to say "If the mouse is inside the container" instead of "if the mouse is inside the container, as long as its not hovering over a child of the container" would be great.
I'm facing the same issue on v3.2.1
I'm experiencing the same problem. 3.1.1 stable mono. Any updates / workarounds for this?
Sorry for the late comment, maybe you have already solved this problem or moved on, but writing this to be helpful for other encountering this problem:
A simple but brute-force method is to check if the mouse coordinates are inside the Control:
var mouse = node.get_global_mouse_position()
var global_position = node.rect_global_position
var min_x = global_position.x
var min_y = global_position.y
var max_x = global_position.x + node.rect_size.x
var max_y = global_position.y + node.rect_size.y
var mouse_is_inside = mouse.x > min_x and mouse.y > min_y and mouse.x < max_x and mouse.y < max_y
A simpler method is via has_point()
var mouse_is_inside = node.get_global_rect().has_point(node.get_global_mouse_position()):
Edit: edited source-code formatting
I'm facing the same issue on v3.2.2 stable build, ubuntu 20.04
I'm having the same issue on 3.2.2 stable, but with Area2D.
I'm having the same issue on 3.2.2 stable, but with Area2D. on MacOS Catalina ver 10.15
EDIT:
I realised the reason it was happening for me was because I had children nodes
Yes, it looks like the mouse_exited() and mouse_entered() signals are sent even when a the mouse moves from one control node, to a child node inside that node while that child is set to pass. I believe this is happening because even though the signal passes through the child, it is coming from a different source. Before, the input event it was coming from the viewport, while now it's coming from the child.
I do agree that this is counter-intuitive though.
Ugh, the workaround with checking manually if the mouse is within the children rect is really hacky and has too many edge cases. For example, If I rotate the parent, the mouse-coordinates check is of course not aware, so I would need to offset the position it thinks the children rect are by the rotation they received.
There has to be a better way...
Most helpful comment
Same here, having a way to say "If the mouse is inside the container" instead of "if the mouse is inside the container, as long as its not hovering over a child of the container" would be great.