Mouse cursor changes over a Control node, even if it has been removed from the scene tree

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

I have created a GUI via Control nodes that is added to the screen dynamically like this:

onready var sub_menu_container = $MainMenu/SubMenu

var construction_menu = preload("res://gui/construction/construction_menu.tscn")
var sub_menu_scene = null

sub_menu_scene = construction_menu.instance()
sub_menu_container.add_child(sub_menu_scene)

Then later when I click on to a button (which is part of that dynamically added GUI) that GUI itself is removed again:

sub_menu_container.remove_child(sub_menu_scene)
sub_menu_scene.queue_free()
sub_menu_scene = null

When that happens (i.e. removing the GUI node again) I also set the mouse cursor:

Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND)

However, now this new cursor is only shown on the part of the game window that was not where the GUI has been shown. When I move the mouse over that area where the GUI has been, then the cursor switches back to the default ARROW again - as if the GUI would still be visible. But I have removed it before, as show above, via remove_child().

Minimal Sample Project
You can find all code to reproduce this error in the minimal sample project that I have created. in the scene res://gui/main/main_gui.tscn and in its script res://gui/main/main_gui.gd. There the GUI is added and removed to the current scene in the main_button_pressed() function, and the cursor is set in line 33 in the construction_item_selected() function.

Open the project, run the game, then click on this one single menu item in the top left corner. Then in the sub menu that opens click the one new button. Now the sub menu is hidden again - the cursor is set to the new shape only on the right part of the game window. When moving the mouse left again, on to the area where the sub menu has been, then the normal ARROW cursor is shown. You can now move the cursor left and right to see the cursor image change between the two shapes.

You can find this minimal sample project here.

:bust_in_silhouette: Reply From: Thomas Karcher

The cursor shape only applies to all areas outside the (now empty) menu container, which will not automatically shrink after the instanced scene is removed.

You can force-shrink the container by adding

sub_menu_container.get_parent_control().rect_size.x = 0

in line 20 of main_gui.gd

Ohh yes indeed - thank you very much!

haimat | 2020-12-18 22:20

By the way, did you just know that from your experience with Godot, or did you debug that issue somehow and found the solution? If so, could you please be so kind and explain how you found that solution?

haimat | 2020-12-19 17:18

I started with debugging: I examined the remote tree while running the program and noticed that (1) yes, the submenu was indeed removed (as expected), but (2) the rect size of the parent container was not changed after that. So I googled “hboxcontainer shrink issue” to make sure this isn’t a known bug, and the very first hit was a lengthy discussion about exactly this behaviour, which (as it turned out) is both expected and desired. So I googled some more to find the best approach to cope with this, and found a forum post with the promising title “How to force a container to updates it’s size when the size of it’s children changes”. And indeed, there was the line I was looking for: “The key here is adjusting the parent rect size with get_parent_control().rect_size

Thomas Karcher | 2020-12-19 19:00

Awesome, thanks a lot, Thomas.

haimat | 2020-12-19 19:03