godotengine / godotengine/godot
FileSystemDock scrolls to top when ResourceSaver.save() is called from an editor plugin
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
Tested versions:
- Reproducible in: 4.6.stable (89cea1439)
- Not tested in earlier versions, but likely present since the FileSystemDock scroll fix in #101078 only addressed scene saves, not ResourceSaver.save()
### System information
Godot v4.6.stable - macOS Tahoe (26.4.0) - Multi-window, 1 monitor - OpenGL 3 (Compatibility) - Apple M1 Pro - Apple M1 Pro (8 threads) - 16.00 GiB memory
### Issue description
When an editor plugin calls `ResourceSaver.save()` to update a `.res` file in the project directory, the FileSystemDock briefly scrolls/jumps — the scroll position resets and then returns. This creates a visible flicker every time a resource is saved programmatically.
This is similar to #101065, which was fixed for scene saves in #101078 by preserving scroll position in `_update_tree()`. However, `ResourceSaver.save()` triggers the same `_fs_changed() → update_all() → _update_tree()` path without preserving the scroll position.
**Expected behavior:** FileSystemDock scroll position should remain stable when resources are saved from a plugin.
**Actual behavior:** FileSystemDock briefly flickers/scrolls on every `ResourceSaver.save()` call.
### Steps to reproduce
1. Create an editor plugin with a Timer that calls `ResourceSaver.save()` on a `.res` file every few seconds
2. Open any project, scroll down in the FileSystem dock
3. Observe the scroll position jumping briefly each time the resource is saved
Minimal plugin code:
```gdscript
@tool
extends EditorPlugin
var _timer: Timer
func _enter_tree() -> void:
_timer = Timer.new()
_timer.wait_time = 3.0
_timer.timeout.connect(_on_timeout)
add_child(_timer)
_timer.start()
func _exit_tree() -> void:
_timer.queue_free()
func _on_timeout() -> void:
var image := Image.create(16, 16, false, Image.FORMAT_RGBA8)
var texture := ImageTexture.create_from_image(image)
ResourceSaver.save(texture, "res://test_texture.res")
```
### Minimal reproduction project (MRP)
N/A — reproducible with the plugin code above in any project.
Contributor guide
Research direction
Start by tracing FileSystemDock's _fs_changed() → update_all() → _update_tree() path, comparing it with the scroll-preserving behavior added for scene saves in #101078. Reproduce the flicker using the Timer-based editor plugin and verify that saving a .res resource with ResourceSaver.save() leaves the FileSystemDock scroll position stable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100