Why does setting mouse mode to Visible after Confining keep mouse cursor hidden till moved outside viewport?

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

I have created a breakout style game, where I want the mouse to be hidden and confined to the viewport. I am only tracking the x axis (moving a paddle left & right). I allow the player to select different paddles, where I need to show the mouse cursor again till a new paddle is selected. I pause the game and set the mouse mode back to visible to do this.

Unfortunately the mouse cursor will not show unless I move the mouse outside the viewport and back in again.

This only happens when I am setting the mouse mode to confined and then setting it back to visible. If I set the mouse mode to Hidden and then back to Visible it works, but the mouse can escape the viewport which then stops the paddle from being able to be moved.

Is this a bug with mouse mode Confined?

I also noticed that mouse mode Confined is described as mouse cursor being visible but confined, When setting the mouse mode to confined the mouse cursor is hidden, which works for my game, but it is different then the documentation.

I have listed some code below:

Not working (mouse cursor hidden till moved outside viewport)

Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

Working (mouse cursor show immediately)

Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
:bust_in_silhouette: Reply From: GreyMiller

Have you figured it out?
I have a similar problem with HIDDEN, but a bit more complicated. The following lines are not exactly in the same order they are in my script (they are in different functions) but in the order they are run while playing:

Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
#gameplay
#pressing pause
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
#move mouse manually or by script, it becomes visible
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
#gameplay
#pressing pause
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
#cursor seen not immediately but as soon as mouse moved

but:

Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
#gameplay
#pressing pause
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
#don't move mouse
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
#gameplay
#pressing pause
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
#cursor not seen until moved out of game window

So the problem seems to be with mouse mode in general.
I fixed it temporary with warp_mouse_position function added after every time I make it visible, but I don’t like this solution.

How are you making it confined AND hidden? Because with confined mode cursor is shown. Maybe for your case you should use captured?

Also, I tried making it confined right before visible, like this (I don’t use mouse in my gameplay):

Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
#gameplay
#pressing pause
Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
#cursor shows literally immediately

It works, but I’m still looking for a better solution.
However, in HIDDEN mode cursor can be moved out of window

First of, why haven’t you asked this in a separate question? You’re not providing an answer to the original question (which is 2 years old!) with your post…

Furthermore I cannot reproduce the problem you’re describing: switching from HIDDEN to VISIBLE will make the cursor visible immediately, without any mouse movement needed. Here’s the script I used for testing:

func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

	var timer = Timer.new()
	timer.connect("timeout", self, "_on_Timer_timeout")
	add_child(timer)
	timer.start()
    
func _on_Timer_timeout():
	if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
		Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
	elif Input.get_mouse_mode() == Input.MOUSE_MODE_HIDDEN:
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

How are you making it confined AND hidden?

You don’t! There can only be one mouse-mode active at any time. That’s why there is MOUSE_MODE_CAPTURED. But you seem to be aware of it, so…?

Alternatively, you could set the mouse-mode to MOUSE_MODE_CONFINED and the mouse cursor to a fully transparent image like this:

Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
Input.set_custom_mouse_cursor(load("res://transparent.png"))

To reset the mouse cursor image simply run:

Input.set_custom_mouse_cursor(null)

njamster | 2020-03-25 12:03

Sorry, I assume it’s the same problem and my comment might provide a little help. Btw most forums don’t like flooding with new topics.

You don’t! There can only be one mouse-mode active at any time.

I know, I was asking gswashburn what he means.

Tried exactly your code with timer (running on Windows 7, nvidia), and I get this:
-if i don’t move mouse at all, cursor disappears in one sec an doesn’t show again
-if i move mouse continuously, cursor blinks
-if i don’t move cursor for 3 secs, it won’t appear until I move it outside the window.
Also I replaced timer event with keyboard input to switch mode manually, and if I hide and then make cursor visible again, it actually appears exactly when i move mouse.
If i do the following: set to hidden - set to visible - set to hidden - move cusor outside the window and back in - set to visible - move cursor, in the last case it appears as soon as i move mouse. If cursor is outside the window it is always visible.

So the problem seems to be not in the code. May it be because of something in Windows? What’s your OS?

GreyMiller | 2020-03-25 13:14

May it be because of something in Windows? What’s your OS?

Might be. I’m using Linux and don’t have a Windows-machine in reach right now for testing this. You might consider opening an issue at github then.

I know, I was asking gswashburn what he means.

He hasn’t been active here since 2018, so your chances of an answer are meager.

Btw most forums don’t like flooding with new topics.

However, this is not a forum, it’s a question board. :wink: Of course it’s still good practice to check if a question has already been answered before, but if it hasn’t, asking again is perfectly fine. Especially since Godot underwent some substantial changes and improvements since 2018. It’s also worth pointing out that a new question gets better visibility than a new answer, as it will appear here, here and here instead of just here.

njamster | 2020-03-25 13:35

Thanks, I’ll note that)

GreyMiller | 2020-03-25 13:38