Repository: godotengine/godot (language: cpp)

Issue:
Node inspector location jumping when tree item is opened or closed
### Tested versions

Reproducible
v4.4.dev6.mono.official [1f47e4c4e]
v4.4.dev7.mono.official [46c8f8c5c]

NOT reproducible:
v4.3.stable.mono.official [77dcf97d8]
v4.4.dev1.mono.official [28a72fa43]
v4.4.dev2.mono.official [97ef3c837]
v4.4.dev3.mono.official [f4af8201b]
v4.4.dev4.mono.official [36e6207bb]
v4.4.dev5.mono.official [9e6098432]


### System information

Godot v4.4.dev7.mono - Windows 10 (build 19045) - Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1060 6GB (NVIDIA; 32.0.15.6094) - Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz (4 threads)

### Issue description

When in the node inspector a item (for example `GPUParticles2D | Process Material | Process Material (Particle Process Material) | Display | Scale`) is clicked open, the view jumps. The item under the mouse cursor is no longer the item that was clicked. Sometimes the item will be higher, sometimes lower in the view, which makes this very annoying. Click something, then try to find the item again.

I haven't been able to reproduce this with simple nodes, like `Node2D,` but with nodes with a lots of stuff, like `GPUParticles2D,` this is easily reproducible.

The jumping happens both when tree items are opened and closed. But it seems that jumping happens only once per node selection. So after the first jump, no other jumps will happen until some other node is selected and then this node is selected again.

The first and second to screenshots show what happens when `Scale` item is opened. The second and third screenshots show wahn happens when `Scale` item is closed. The red arrow shows where the mouse cursor is (sorry, too difficult to get mouse cursor in screenshots in Windows).

![Image](https://github.com/user-attachments/assets/c60179e4-a5fd-41eb-b772-8b24c8756670)


### Steps to reproduce

Setup:
1. Add `Node2D` as a root node
2. Add `GPUParticles2D` to the root node
3. Add `Particle Process Material` to the `GPUParticles2D` node

Reproduction:

4. Scroll to `Process Material (Particle Process Material) | Display | Scale`
6. Click `Scale` tree item to open it 
7. => THE PROBLEM `Scale` is no longer under mouse cursor 

Repeat:

9. Click Scale tree item to close it
10. Select scene's root node `Node2D`
11. Select `GPUParticles2D` again 
12. goto step 4

### Minimal reproduction project (MRP)

N/A


Discussion / hints:
A important step missing is that's necessary have enough unfolded sections to vertically fill the inspector for this happen:

https://github.com/user-attachments/assets/7e848c03-c53e-4e5a-87c7-bb5ae9a28c18

<br>

Also, only happens when the inspector receive the focus, as you can see in the video above i just click outside the editor to trigger the bug and while you keep the inspector focus the bug will not happen. I'll start the bisect.
Bisected to #97521, @pafuent

![Image](https://github.com/user-attachments/assets/0b39ec02-9fa7-465b-9a66-c44f08ae8714)

If I got it correctly this issue is caused when this line was added (on https://github.com/godotengine/godot/pull/97521)
https://github.com/godotengine/godot/blob/master/editor/editor_inspector.cpp#L4699
![Image](https://github.com/user-attachments/assets/eb3e5965-4be3-4262-90ce-1920f988a59b)
In [this](https://github.com/godotengine/godot/pull/97521#discussion_r1855013999) comment you can see the reason why this line was added.
The function that it seems to be causing this problem is [this](https://github.com/godotengine/godot/blob/master/scene/gui/scroll_container.cpp#L292) one.
[This](https://github.com/godotengine/godot/issues/91287) bug has some analysis on `ScrollContainer::ensure_control_visible` that could be useful.
CC @KoBeWi 

Fix patch:
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 0bbd55f00757..644cbe5b5817 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -51,7 +51,6 @@
 	<members>
 		<member name="draw_focus_border" type="bool" setter="set_draw_focus_border" getter="get_draw_focus_border" overrides="ScrollContainer" default="true" />
 		<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
-		<member name="follow_focus" type="bool" setter="set_follow_focus" getter="is_following_focus" overrides="ScrollContainer" default="true" />
 		<member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" overrides="ScrollContainer" enum="ScrollContainer.ScrollMode" default="0" />
 	</members>
 	<signals>
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 3f3b06b428a6..b79d1243ba6c 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -2996,6 +2996,7 @@ void EditorInspector::update_tree() {
 	int current_focusable = -1;
 
 	// Temporarily disable focus following on the root inspector to avoid jumping while the inspector is updating.
+	bool was_following = get_root_inspector()->is_following_focus();
 	get_root_inspector()->set_follow_focus(false);
 
 	if (property_focusable != -1) {
@@ -3024,7 +3025,7 @@ void EditorInspector::update_tree() {
 	_clear(!object);
 
 	if (!object) {
-		get_root_inspector()->set_follow_focus(true);
+		get_root_inspector()->set_follow_focus(was_following);
 		return;
 	}
 
@@ -3890,7 +3891,7 @@ void EditorInspector::update_tree() {
 		EditorNode::get_singleton()->hide_unused_editors();
 	}
 
-	get_root_inspector()->set_follow_focus(true);
+	get_root_inspector()->set_follow_focus(was_following);
 }
 
 void EditorInspector::update_property(const String &p_prop) {
@@ -4742,6 +4743,15 @@ void EditorInspector::_notification(int p_what) {
 				update_tree();
 			}
 		} break;
+
+		case NOTIFICATION_FOCUS_ENTER: {
+			set_follow_focus(true);
+		} break;
+
+		case NOTIFICATION_FOCUS_EXIT: {
+			// Don't follow focus when the inspector is not focused. Prevents potential jumping when gaining focus.
+			set_follow_focus(false);
+		} break;
 	}
 }
 
@@ -4898,7 +4908,6 @@ EditorInspector::EditorInspector() {
 	base_vbox->add_child(main_vbox);
 
 	set_horizontal_scroll_mode(SCROLL_MODE_DISABLED);
-	set_follow_focus(true);
 
 	changing = 0;
 	search_box = nullptr;


Test patch: