mouse_exited() fires even though the mouse didn't leave

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ifgiU


This is a repost from the r/godot subreddit, but noone could help me there, so I’m trying my luck here.

I have a HBoxContainer with a placeholder circle (using a TextureRect) and a button. I want the circle to be visible the whole time, but the button should be hidden. When I hover over the circle, the button should be revealed and I should be able to freely interact with it. When the mouse leaves both the button and circle, the button should be hidden again.

So, I used the mouse_entered() signal of the circle to reveal the button, and the mouse_exited() signal of the HBoxContainer to hide it again.

But when I run it, the button shows up when I hover the circle, but also dissapears when I leave the circle. I also tried changing the Mouse Mode of the Button to “Pass”, but that didn’t help. How could I fix this?

:bust_in_silhouette: Reply From: jgodfrey

The problem here is that when the mouse Enters the child control, that causes it to Exit the parent container. There are probably a number of ways to handle this “manually”, but here’s one that seems to work.

First, my test scene looks like this:


Next, the Button control’s mouse_filter must be set to pass

Finally, I have the following script attached to the Control node.

extends Control

@onready var hbox = $HBoxContainer
@onready var button = $HBoxContainer/Button

# Called when the node enters the scene tree for the first time.
func _ready():
	button.visible = false

func _on_texture_rect_mouse_entered():
	button.visible = true

func _on_h_box_container_mouse_exited():
	if not Rect2(hbox.get_global_rect()).has_point(get_global_mouse_position()):
		button.visible = false

func _on_button_pressed():
	print("Button pressed")

Of course, you’ll have to season to taste if your scene structure differs.

Thanks, that worked! Though I have one question: I understand what “get_rect()” does, but what is “get_global_rect()”? I don’t quite understand the difference.

ifgiU | 2023-04-11 13:45

get_rect() and get_global_rect() are similar - they just return the rect info in (potentially) different coordinate systems. I’m using get_global_rect() as it should coincide with the coordinates returned by the get_global_mouse_position() call that we’re comparing.

You can see the detailed difference between the two methods here:

jgodfrey | 2023-04-11 13:54