Can't make warp_mouse to move the mouse cursor

Godot Version

4.3

Question

I’ve been trying to create a right stick moue control in godot and it seems the warp_mouse function is not working. None of them, coming from get_window, get_viewport, Input, seems to work.

The interesting thing is the mouse position seems to be updated internally but the mouse cursor is not moving at all in the screen.

Here it is a simple scene code you can use to reproduce this. Just create a basic scene with whatever root node you want, and add a script with this code. It should work and move the cursor, but in my case the cursor is not moving at all. (Added also commented code I’ve been using but nothing of that worked)

extends Node


#func _ready() -> void:
	#Input.mouse_mode = Input.MOUSE_MODE_CONFINED

#func _process(_delta: float) -> void:
		#var direction = Vector2(0, 0)
		#var speed = 10
		#if Input.is_action_pressed("rs_right") or Input.is_action_pressed("rs_left"):
			#direction.x = Input.get_action_strength("rs_right") - Input.get_action_strength("rs_left")
		#if Input.is_action_pressed("rs_up") or Input.is_action_pressed("rs_down"):
			#direction.y = Input.get_action_strength("rs_down") - Input.get_action_strength("rs_up")
		#if direction != Vector2(0,0):
			#var viewport = get_viewport()
			#var curpos =  viewport.get_mouse_position()
			#var pos = curpos + direction.normalized() * speed
			#print(curpos, " -> ", pos)
			#Input.warp_mouse(pos)

func _process(delta: float) -> void:
	if Input.is_action_pressed("rs_right"):
		var mp := get_window().get_mouse_position()
		print("PRE ", mp)
		Input.warp_mouse(
			Vector2(mp.x + mp.x * delta, mp.y)
		)
		mp = get_window().get_mouse_position()
		print("POST ", mp)

Are you experimenting the same problem? It can be related with my setup (I’m using Linux, wayland and Intel Irix iGPU), but after looking for errors like this one in every place I can’t find anyone with this specific problem, so I do not know if it is a bug or what can it be.

I’ve not checked with your code but this seems to work just fine:

extends Node


func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CONFINED


func _process(delta: float) -> void:
	var vector = Input.get_vector(&"ui_left", &"ui_right", &"ui_up", &"ui_down")
	var pos = get_window().get_mouse_position() + vector * 100 * delta
	Input.warp_mouse(pos)

Result:

I’m on Linux x11

Thank you very much for showing it works for you.

I’ve copied your code and tried to execute it in my machine and it didn’t work.

I will try to execute it in a different machine (windows for example) and come back with more info.

Ok. Tested it in windows and it works.

So, the problem is only on my computer it seems. Maybe wayland related.

Should I file an issue to godot github?

I’ve also tested this in Godot 4.4 and in different linux computers (Fedora Workstation with Wayland) and the code do not work in them. It seems it is a bug related with Linux/Wayland

Adding here a workaround using a fake cursor

extends Node

const MOUSE_MOVE_SPEED = 10


func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_HIDDEN


func _process(_delta: float) -> void:
	var pos = get_window().get_mouse_position()
	var vector = Input.get_vector(&"ui_left", &"ui_right", &"ui_up", &"ui_down")
	
	if vector != Vector2.ZERO:
		var display_size = DisplayServer.window_get_size() # get_viewport().get_visible_rect().size
		pos += vector * MOUSE_MOVE_SPEED
		pos.x = max(min(pos.x, display_size.x - 1), 0)
		pos.y = max(min(pos.y, display_size.y - 1), 0)
		Input.warp_mouse(pos)
	$FakeCursor.position = pos