UI on_mouse_exit does not work if any UI is behind it

Godot Version

4.4

Hey all, I have a weird one that is making me pull my hair out. And I think I have tried almost everything. I am making a right click menu for my inventory, getting it to show up is pretty easy. But I want the popup window to go away when the mouse moves outside the area of the popup. This is a 3D game, if that helps.

So normally, I would just create a signal and use one of the many versions of “_on_mouse_exit” that exist. But that doesn’t work. I can make it work if the Control node isn’t showing any buttons, but as soon as I fill the window with anything, those children count as the mouse leaving the control node.

I tried adding an Area2D with some collision and detecting that. But this doesn’t work if there is any UI behind the popup window. If I can make the window popup over just the world, not over any other UI, then I can make the mouse_exit signals work.

I have no idea why this isn’t working. I tried changing the z-index, I tried changing the layers, and I think I tried every setting. I even tried doing it by code! But that doesn’t work either. Nothing works to properly check if my mouse has exited my popup window, and I have no idea why.

What if you do it the other way around? Make a transparent control that stretches full screen behind your popup window that will detect the mouse_entered signal upon which it will hide/remove your popup window.

Unfortunately it is the same problem. The mouse_entered will only trigger if the mouse is not over any UI at all. But I need it to trigger while still over other UI


Mouse is just outside the popup window (The window with Equip, Drop, and Examine)


Mouse is just outside all the UI, and triggers the signal

Can you show a screenshot of you popup window with the solution I suggested?
And the 2D view of the scene.

I just quickly tested it on my end and it should work perfectly fine.

That’s the weird part, it worked exactly the same as the images above. Doesn’t matter if I put the Area2D inside the popup or outside the popup, it will only trigger if the mouse is not over any other UI.

Its clear that my other UI is the problem, but I don’t know why or where. Nothing in that UI has anything that should be causing problems, I don’t have any other Area2d on that other UI

I don’t think you understand what I mean.
See this little demo I made


This is the scene tree, important is to have the Control node stretched on the Full Rect.

This is the code on the Control node

extends Control


func _ready() -> void:
	mouse_entered.connect(func() -> void: update_label("mouse_entered << this is where I close the UI"))
	mouse_exited.connect(func() -> void: update_label("mouse_exited"))


func update_label(text: String) -> void:
	$"../Label".text = text
	print(text)

Can you try to recreate it in your setup?


I turned off the code for when it enters. But the rest is directly from the code you gave. I’ll make a clip of the current problem as it was before too


This is what it looks like with all my previous code. The original problem

Can you show your scene tree?


The very last item is the popup window. Which is its own scene.


This is with the grid container expanded


This is the inventory slot


This is the popup

Still, I don’t see anywhere this Control that I have in my scene


which should be around here where I drew the red line

This Control is crucial to make this thing work :slight_smile:

As far as I know, it’s not a good idea to put Sprite (2D node) under Control node. If you want to display an image under a Control node, you can use TextureRect. I’m not sure if it’s the cause of your issue, but wouldn’t hurt to try.

EDIT:

All Control nodes have natively mouse_enter and mouse_exit signals, so you can use them instead of creating an extra Area2D node.
You should also check “mouse filter” option to make sure it behaves how you want. You can find it here:

EDIT2:

I think your Sprite is for the background of the menu. You can use NinePatchRect instead of TextureRect. So it can be resized however you want, without messing up the scaling of edges/borders.

1 Like

I tried adding that control node and moving the code to there, but now the signals never fire (And yes, I reconnected the signals)

Oh yeah I tried the mouse filter options for literally everything already. Was one of the first things I tried, but it doesn’t change anything sadly

I also tried replacing the images with NinePatchRect and the problem still remains

It may be because your main Inventory node has a Sprite2D background and Area2D. Try to make them TextureRect.

Even if making them TextureRect wouldn’t solve your issue, do it anyway. You’ll find more problems ahead if you leave Node2D nodes under Control nodes.

I tried TextureRect earlier, but I couldn’t scale it for some reason. Is there something I am missing to allow me to scale the image on a TextureRect?

I don’t mean to move your code there, there’s no need for that. You just need this node to catch the mouse_entered signal off of it - and this signal should make your right click UI disappear.
Can you try implementing that, or do you need any help with it?