Repository: godotengine/godot (language: cpp)

Issue:
Incorrect Camera2D movement in embedded game window with stretch mode enabled
### Tested versions

- Reproductible in: Godot v4.4.rc3

### System information

Godot v4.4.rc3 - Windows 11 (build 22631) - Multi-window, 1 monitor - OpenGL 3 (Compatibility) - AMD Radeon RX 6700 XT (Advanced Micro Devices, Inc.; 32.0.12033.1030) - AMD Ryzen 5 3600 6-Core Processor (12 threads)

### Issue description

I tried to override and move the in-game camera (using middle mouse button) inside the embedded game window. When having stretch mode enabled and resized the window, instead of correctly moving the camera it moves either too fast or too slow and the mouse curser "wraps" at unpredictable positions.

### Steps to reproduce

1. Inside a new project, add a sprite to a 2D scene
2. Set display/window/stretch/mode to either "canvas_items" or "viewport"
3. Make sure to have "Embed Game on Next Play" and "Make Game Workspace Floating on Next Play" enabled
4. Run the project and resize the window (bug is most noticeable when resizing the window to about half the viewports size)
5. In the game workspace toolbar, disable game input and enable overriding the in-game camera
6. Try moving the in-game camera using the middle mouse button

Inside the MRP, I already set the window width and height override to half the viewport's size, so you can start the project and proceed at step 5.

### Minimal reproduction project (MRP)

[embedded_window_camera_bug.zip](https://github.com/user-attachments/files/19040413/embedded_window_camera_bug.zip)


Discussion / hints:
CC @YeldhamDev @Hilderin 
I did some testing and the issue is probably in the overriden camera 2d movement. It seems to not take into account the window stretching. I was able to reproduce the same problem without the embedded only by resizing the game window.

I will let @YeldhamDev check that, I'm not familiar with the overriden camera.

https://github.com/user-attachments/assets/188c31b7-cf8c-4019-969f-425bd8360c1a



Fix patch:
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index cd2388da5ada..8a054edcee7f 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -1425,7 +1425,7 @@ void RuntimeNodeSelect::_root_window_input(const Ref<InputEvent> &p_event) {
 	bool is_dragging_camera = false;
 	if (camera_override) {
 		if (node_select_type == NODE_TYPE_2D) {
-			is_dragging_camera = panner->gui_input(p_event, Rect2(Vector2(), root->get_size()));
+			is_dragging_camera = panner->gui_input(p_event, Rect2(Vector2(), root->get_visible_rect().get_size()));
 		} else if (node_select_type == NODE_TYPE_3D && selection_drag_state == SELECTION_DRAG_NONE) {
 #ifndef _3D_DISABLED
 			if (_handle_3d_input(p_event)) {
@@ -2214,8 +2214,9 @@ void RuntimeNodeSelect::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_
 }
 
 void RuntimeNodeSelect::_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) {
-	view_2d_offset.x -= p_scroll_vec.x / view_2d_zoom;
-	view_2d_offset.y -= p_scroll_vec.y / view_2d_zoom;
+	Vector2 scroll = SceneTree::get_singleton()->get_root()->get_screen_transform().affine_inverse().xform(p_scroll_vec);
+	view_2d_offset.x -= scroll.x / view_2d_zoom;
+	view_2d_offset.y -= scroll.y / view_2d_zoom;
 
 	_update_view_2d();
 }


Test patch: