Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mouse cursor shape is not updated after scene change #45936

Closed
dploeger opened this issue Feb 12, 2021 · 9 comments · Fixed by #58913 or #58995
Closed

Mouse cursor shape is not updated after scene change #45936

dploeger opened this issue Feb 12, 2021 · 9 comments · Fixed by #58913 or #58995

Comments

@dploeger
Copy link

Godot version:
3.2.3

OS/device including version:
macOS 10.15.7

Issue description:
When you set the mouse cursor shape on a control in one scene and another shape in another scene that shape is not switched when the scene changes. Only after the first mouse move, the shape is updated.

Steps to reproduce:

  • Create two scenes with two control nodes that share the same screen position
  • Set different mouse cursor shapes on both nodes
  • Switch from one scene to the other
  • => The mouse cursor shape is only updated once the mouse is moved

Minimal reproduction project:
mousetest.zip

(Run the game, then click on the button. The cursor should change to the hand icon but only does that when you move the mouse)

@Calinou
Copy link
Member

Calinou commented Feb 12, 2021

Related to #30582.

I think this happens in general whenever you change the cursor shape of a Control that's under the cursor. It will keep the old appearance until you move the cursor.

dploeger added a commit to deep-entertainment/egoventure-example-game that referenced this issue Feb 21, 2021
@nathanfranke
Copy link
Contributor

Linking this to #6633. Workaround:

yield(get_tree(), "idle_frame")
get_viewport().warp_mouse(get_viewport().get_mouse_position())

For some reason, yield is needed when going from ARROW to DRAG but not needed when going from DRAG to ARROW.

@dploeger
Copy link
Author

@nathanfranke Should that code go into _ready? If so, it isn't working if I put it in _ready of the second scene included in the reproduction project.

@nathanfranke
Copy link
Contributor

@nathanfranke Should that code go into _ready? If so, it isn't working if I put it in _ready of the second scene included in the reproduction project.

I put it directly after a call to change the default cursor shape of the control I am hovering over. I can't know exactly for your project but you can try making a 0.5 second timer and running that warp mouse call every 0.5 seconds for testing purposes. I wouldn't recommend that for production though.

Also I'm on Ubuntu, this could be an OS dependent thing. You can also try warping the mouse one pixel down and then back up

@dploeger
Copy link
Author

dploeger commented Apr 26, 2021

Ah okay. I didn't change the default cursor shape of the control by code. I use the normal setting in the node definition. And yes, this is definitely a OS thing, because I had to use different approaches on macOS and Windows.

@Calinou
Copy link
Member

Calinou commented Apr 26, 2021

This issue may be related to #39608 too.

@chucklepie
Copy link

chucklepie commented Jul 23, 2021

I found a (dreadful) way to fix it by calling this in my startup _ready method:

	var custom= "display/mouse_cursor/custom_image"
	var icon=ProjectSettings.get_setting(custom)
	ProjectSettings.set_setting(custom,null)
	get_viewport().warp_mouse(Vector2(50,50))
	get_viewport().warp_mouse(Vector2(150,150))
	ProjectSettings.set_setting(custom,icon)

You can get by with just the warp_mouse if the mouse is visible, but when it's not visible warp_mouse does nothing.

I doubt it's a proper fix, but it works for me. The problem is pretty bad, please observe the effect on a video I made on another thread before I saw this original thread:

Untitled.Project.mp4

Thanks.

@dploeger
Copy link
Author

For EgoVenture we worked around this by calling this not very elegant function after a scene change:

func check_cursor(offset: Vector2 = Vector2(0,0)):
	if not is_touch and not Speedy.hidden:
		var target_shape = Input.CURSOR_ARROW
		var mousePos = get_viewport().get_mouse_position() + offset

		var current_scene = get_tree().get_current_scene()
		for child in current_scene.get_children():
			if "mouse_default_cursor_shape" in child and child.visible:
				var global_rect = child.get_global_rect()
				if global_rect.has_point(mousePos):
					if child.get_class() == "TriggerHotspot":
						child.on_mouse_entered()
					target_shape = child.mouse_default_cursor_shape
		Speedy.keep_shape_once = true
		Speedy.set_shape(target_shape)

dploeger added a commit to deep-entertainment/speedy_gonzales that referenced this issue Nov 22, 2021
@akien-mga akien-mga added this to the 4.0 milestone Mar 9, 2022
@akien-mga
Copy link
Member

Reopening as #58913 is reverted due to a regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
5 participants