How to get correct global mouse coordinates inside a sub-viewport

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

Scene Structure
Viewport in action

I have a sub-viewport with a 2D scene instanced as a child. On this scene I draw a grid and I want to be able to click inside of the grid and place a sprite on the tile that I clicked on.
To achieve this I use following code:

func _on_Preview_gui_input(p_event):
    ._on_Preview_gui_input(p_event)

    if p_event.is_action_pressed("Mouse_Left"):
	    var mouse_pos = a_preview_scene.get_global_mouse_position()
	    var point = _pos_to_grid_point(mouse_pos)
	
	    if a_point_vec != point || a_point == null:
		    _update_point(point)
	    else:
		    _delete_point()

This works fine as long as the window size doesn’t change. I have stretch_mode 2D and aspect keep in the project settings, and if I resize the window to be wider or higher CanvasItem.get_global_mouse_position() starts to give me wrong values. (Note: In this case the size of the root viewport is still the default value, only black bars appear).

This offset caused by the black bars can be easily fixed by doing:

var root = get_tree().get_root()
var bars = (OS.window_size - root.size) / 2
mouse_pos -= bars

I believe you also have to take the viewport stretch into account if Viewport.size_override_stretch is active.
(By calculating the factor sub_viewport.size_override / sub_viewport.size)

But if I now happen to resize the root viewports size, either by making the window size smaller or by switching to full screen (The sub-viewport size stays the same), everything breaks apart and I’m left with a coordinate I have no idea how to make use of. And even if that worked, changing properties of the current camera 2D would break it too.

So I’m asking, how do I always get the correct global mouse coordinates inside a sub-viewport?

Minimal Reproduction Project: Sub-Viewport Global Mouse Position (Issue) – Google Drive

did You try using Viewport.get_mouse_position() ?

Inces | 2022-03-17 17:15

That gives you local viewport screen coordinates, with the top-left of the viewport being 0,0 and the bottom-right viewport.size.
I want global world coordinates that take a Camera2D into account.

Grandro | 2022-03-17 17:26

Can you show the question with the help of a picture?

ramazan | 2022-03-18 09:44

I included two pictures in the original post, but I couldn’t get them to show a preview. Anyways here are the links to the two pictures:
Imgur: The magic of the Internet
Imgur: The magic of the Internet

In the first one you can see the scene structure, but you just have to have a viewport besides the root viewport to encounter the issue.
In the second one you can see the viewport in action (rendering a 2D scene with a grid). If I click inside of the grid I want to change the global position of a Sprite2D to be the global mouse position in the world. But as soon as you resize the window the coordinates start to be off.

I will also include a minimal showcase project so you can see it for yourself.

Grandro | 2022-03-18 10:17

I understood the question, if I’m not mistaken, I’ve seen similar questions, I don’t know the answer, but I think this will help you

`2d` or `viewport` stretch mode does not scale mouse coordinates · Issue #34805 · godotengine/godot · GitHub

ramazan | 2022-03-18 11:40