Repository: godotengine/godot (language: cpp)

Issue:
Follow Focus not working as expected in a rotated `ScrollContainer`
### Tested versions
Bad: v4.0.stable.official [92bee43ad], master

### System information

Godot v4.4.dev (e19746352) - Linux Mint 22 (Wilma) on X11 - X11 display driver, Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1050 Ti (nvidia; 535.183.01) - Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz (4 threads)

### Issue description

https://github.com/user-attachments/assets/443244ff-871d-42f7-b653-a80cc0ff159d

Navigating down in a rotating `ScrollContainer` with follow focus enabled, the focused control is not fully visible. Note the StyleBox border.

### Steps to reproduce

1. Import and run the MRP;
2. Select any node inside the `ScrollContainer` and navigate using `Tab`/`Shift + Tab`.
3. Navigate down to reproduce the issue.

### Minimal reproduction project (MRP)

[MRP.zip](https://github.com/user-attachments/files/18432280/MRP.zip)


Discussion / hints:

Fix patch:
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index f3c50c626c17..3bad76baada4 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -292,16 +292,20 @@ void ScrollContainer::_gui_focus_changed(Control *p_control) {
 void ScrollContainer::ensure_control_visible(Control *p_control) {
 	ERR_FAIL_COND_MSG(!is_ancestor_of(p_control), "Must be an ancestor of the control.");
 
-	Rect2 global_rect = get_global_rect();
-	Rect2 other_rect = p_control->get_global_rect();
+	// Just eliminate the rotation of this ScrollContainer.
+	Transform2D other_in_this = get_global_transform().affine_inverse() * p_control->get_global_transform();
+
+	Size2 size = get_size();
+	Rect2 other_rect = other_in_this.xform(Rect2(Point2(), p_control->get_size()));
+
 	float side_margin = v_scroll->is_visible() ? v_scroll->get_size().x : 0.0f;
 	float bottom_margin = h_scroll->is_visible() ? h_scroll->get_size().y : 0.0f;
 
-	Vector2 diff = Vector2(MAX(MIN(other_rect.position.x - (is_layout_rtl() ? side_margin : 0.0f), global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x + (!is_layout_rtl() ? side_margin : 0.0f)),
-			MAX(MIN(other_rect.position.y, global_rect.position.y), other_rect.position.y + other_rect.size.y - global_rect.size.y + bottom_margin));
+	Vector2 diff = Vector2(MAX(MIN(other_rect.position.x - (is_layout_rtl() ? side_margin : 0.0f), 0.0f), other_rect.position.x + other_rect.size.x - size.x + (!is_layout_rtl() ? side_margin : 0.0f)),
+			MAX(MIN(other_rect.position.y, 0.0f), other_rect.position.y + other_rect.size.y - size.y + bottom_margin));
 
-	set_h_scroll(get_h_scroll() + (diff.x - global_rect.position.x));
-	set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y));
+	set_h_scroll(get_h_scroll() + diff.x);
+	set_v_scroll(get_v_scroll() + diff.y);
 }
 
 void ScrollContainer::_reposition_children() {


Test patch: