Reactive set_custom_mouse_cursor only updates when mouse leaves window!

Godot Version

4.6 stable

Question

Hi!
My goal is to create a custom cursor that can be updated during gameplay with Input.set_custom_mouse_cursor.
My issue is that the cursor’s state is updated successfully, but the actual image of the cursor only updates when the cursor leaves and re-enters the window.

More descriptively, I keep track of what state the cursor should be in a variable (current_state,) and when I toggle what state the cursor should be in with a button,* the cursor does not visibly change image. However, when i remove my mouse from the window and reintroduce it, the cursor’s image has updated to the correct image that corresponds with the current state.

*The button, attached below in “drawing_manager.gd,” runs “cursor_manager.set_state,” which changes current_state and runs Input.set_custom_mouse_cursor.

My cursor_manager is an autoload, and follows:

#cursor_manager.gd
#autoload

extends Node2D

enum CursorState {DRAWING, LOOKING, POINTING};

var _cursors: Dictionary = {
	CursorState.DRAWING: null,
	CursorState.LOOKING: null,
}

var current_state: CursorState = CursorState.LOOKING

func _ready() -> void:
	_cursors[CursorState.DRAWING] = load("res://art assets/cursors/pencil.png");
	_cursors[CursorState.LOOKING] = load("res://art assets/cursors/looking_eye.png");
	
	Input.set_custom_mouse_cursor(_cursors[current_state], Input.CURSOR_ARROW, Vector2(0,0));

func set_state(state: CursorState) -> void:
	if state == current_state:
		return;
	current_state = state;
	print("cursor loaded: ", _cursors[current_state]);
	Input.set_custom_mouse_cursor(_cursors[state], Input.CURSOR_ARROW, Vector2(0,31));

and my set_state is ONLY called via:

#drawing_manager.gd
#.............
func _on_draw_b_pressed() -> void:
	if !drawing:
		CursorManager.set_state(CursorManager.CursorState.DRAWING);
	elif drawing:
		CursorManager.set_state(CursorManager.CursorState.LOOKING);

	drawing = !drawing; #--toggles.

I would love it if someone with experience wrangling cursors could take a look at this and help me make my cursors update while within the window. Thank you very much!

Could you check at the end of this how often _on_draw_b_pressed()is called when pressing the corresponding button, please?

Hi Ximossi, thanks for taking a look at my problem. _on_draw_b_pressed() only runs once per press. I omitted some prints from my code that I initially posted.
A potential problem: I am coding on a Mac.
What I’ve observed is that when I update the cursor using Input.set_custom_mouse_cursor or DisplayServer.cursor_set_custom_image, I do not see the cursor update until I move the cursor in and out of the window consistently.
My use case is specifically being able to toggle what the cursor looks like depends on the mouse’s functionality, which is something I can’t find tutorials for online to check for other approaches. If there is another way to do this that doesn’t rely on running Input.set_custom_mouse_cursor, I would pursue it at this point. I’m starting to consider a Sprite2D cursor for certain modes…..

Ah! I found documentation of the issue. The error is on mac, when the debug session is in embedded mode. If you are on mac and want regular cursor logic to be applied, change your editor window to non-embedded mode in project settings.

1 Like