Input.set_custom_mouse_cursor() doesn't work until mouse leaves window and returns

Godot Version

4.5 stable.mono.official
Mac OS 26.0.1

Question

Calling Input.set_custom_mouse_cursor() works the first time it’s called. Any subsequent calls do nothing until the mouse cursor leaves the window and returns.

Also, if I change the cursor then close the player, the cursor remains changed when restarted.

Is there a way to poke the cursor to tell it to update immediately?

It seems to be a limitation/bug when running the game in the embedded window. Are you running the game in the embedded window?

No, I’m using a separate window.

Thanks for pointing out the GitHub post. I didn’t think of looking there for possible bugs.

I’m not sure if i misunderstood the problem but could it perhaps not be possible to first set it to null and then set it to what you want it to be? If there is a bug that happens on any attempt except for the first, it could be possible to solve it by replicating the setting of the first attempt. I guess that it is null first time you set it?
Just a thought that came to mind and I can’t promise it will work.

It was a good idea, as according to what I can find online, Input.set_custom_mouse_cursor(null) is supposed to reset the cursor to default. Instead it fails with error "Parameter “imgrep” is null”.

Interestingly, if I do try setting it to null then quit, upon restart it gives the same error. I suppose the last known cursor is saved regardless of whether it was valid.

Testing some more, it always works immediately if I do it within the initial scene’s _ready(), but anytime later it doesn’t change the cursor until leaving the window and returning. I’m guessing that the _ready() is performed before the window displays for the first time.

A workaround for my particular case is to use other cursor shapes for each cursor image:

Input.set_custom_mouse_cursor(cursorSelect, Input.CURSOR_CROSS, Vector2(7,7))
Input.set_custom_mouse_cursor(cursorDraw, Input.CURSOR_BUSY, Vector2(7,7))
Input.set_custom_mouse_cursor(cursorErase, Input.CURSOR_WAIT, Vector2(7,7))

Then change with:
Input.set_default_cursor_shape(Input.CURSOR_CROSS)

I’ve noticed that when things go awry I’ve probably made mistakes setting cursors incorrectly and I need to quit Godot entirely to reset things.