So I’ve been making a shitton of small experimental godot plugins, some of them proved useful, a lot of them didn’t, but those that I ended up using were never shared.

This simple addon is one of those that stood the test of time.

Just dropping code here for now because I may not have time to support and respond to GH issues. One day I might put everything I make in some kind of a single thing, but in the meantime this could help somebody and it may give people ideas for their own tools too.

Double click?

I’m a lazy person and I like optimizing tools, anything from big picture systematic problems down to tiny annoyances that create friction when you have a lot of them.

Godot needing a double click on resources to open them in inspector is one of those small things that are easy to fix. Inspecting scene nodes is single click and there’s no reason it shouldn’t be the same for resources:

When to open

We open them in inspector when:

  1. We are not trying to drag. Otherwise you won’t be able to move files between folders or drop them into inspectors of other nodes/resources.
  2. We are not trying to select multiple. Same reason as above, we want to be able to drag multiple files into inspector.
  3. It’s a type of file that won’t trigger a popup. Just filtering by extension now because there’s no way to know in advance whether a file will trigger a popup from a gdscript addon alone.

I’m including shaders in the third one because I don’t want the bottom panel to pop up when I accidentally click on them, but I have no strong preference here because I write shaders in vscode. You can add extensions to the ignore list as you see fit. It’s a very simple addon.

Addon

@tool
extends EditorPlugin

const IGNORED_EXTENSIONS = [
	"gd",
	"cs",
	"tscn",
	"gltf",
	"glb",
	"fbx",
	"blend",
	"gdshader",
	"gdshaderinc"
]

var _tree: Tree

func _enter_tree() -> void:
	var filesystem_dock = EditorInterface.get_file_system_dock()
	_tree = filesystem_dock.find_children("", "Tree", true, false)[0]
	_tree.cell_selected.connect(_on_cell_selected)

func _exit_tree() -> void:
	_tree.cell_selected.disconnect(_on_cell_selected)

func _on_cell_selected() -> void:
	# Early exit if trying to select multiple files
	if Input.is_key_pressed(KEY_CTRL)\
		or Input.is_key_pressed(KEY_META)\
		or Input.is_key_pressed(KEY_SHIFT):
		return

	var selected_item = _tree.get_selected()

	# Wait for left mouse button to be released
	while Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		await get_tree().process_frame

	# Check if mouse is still over the same item to prevent activation
	# when dragging files inside or outside the tree
	var mouse_local_pos = _tree.get_local_mouse_position()
	var item_at_mouse_pos = _tree.get_item_at_position(mouse_local_pos)
	if item_at_mouse_pos != selected_item:
		return

	var file_extension = _tree.get_selected().get_text(0).get_extension()

	# Ignore folders or extensions that might trigger other apps or
	# changes in godot UI (i.e import popups, opening bottom panel, etc)
	if file_extension == "" or file_extension in IGNORED_EXTENSIONS:
		return

	_tree.item_activated.emit()

Here’s a zip that you unpack can drop into your res://addons:

Some notes on the code

I usually get children by type rather than by their position in the tree:

_tree = filesystem_dock.find_children("", "Tree", true, false)[0]

All I care about is that there should be a Tree somewhere in the filesystem dock, I don’t care how deep or where exactly. This makes the addon a bit more resilient to editor layout changes between godot versions. I wish godot had a way to find a single child by type though, there’s a proposal for that.

I use coroutines a lot in godot tools:

# Wait for left mouse button to be released
while Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
    await get_tree().process_frame

It’s a basic usecase here, but in general it allows creating very complex tools with little code. Making tools that expect user input is nowhere as easy in i.e blender because of how blender is designed. So I’m a huge fan of being able to do stuff like that in godot.

Godot editor scriptability

This is probably my favorite thing about godot. When it comes to editor API, you’re not limited to just making your own new tools, you can change how the editor works itself. Even if something is not explicitly exposed via it’s own API, you can just click buttons via gdscript. Not a lot of software has this kind of flexibility.