Skip to content

Properly show detach script button when script is added via inspector #108122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Kazuo256
Copy link
Contributor

@Kazuo256 Kazuo256 commented Jun 29, 2025

Fixes #107059.

The SceneTreeDock was not tracking script changes in selected nodes in any capacity as far as I could assess. To do
that, my solution essentially connects the "script_changed" signal from selected nodes to
"SceneTreeDock::_update_script_button()" whenever the selection changes. It actually queues the update to make sure it
happens only once no matter how many nodes are selected.

However, only connecting that signal would leave previously selected nodes with a signal connection that should no
longer exist. To properly disconnect previously selected nodes, we have to store the list of currently selected nodes so
we can disconnect them when the selection changes.

@Kazuo256 Kazuo256 requested a review from a team as a code owner June 29, 2025 19:19
@Kazuo256 Kazuo256 changed the title Show detach script button when added via inspector Properly show detach script button when script is added via inspector Jun 30, 2025
@Chaosus Chaosus added this to the 4.5 milestone Jun 30, 2025
Comment on lines 2915 to 2916
for (int i = 0; i < node_previous_selection.size(); i++) {
Node *node = node_previous_selection.get(i);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (int i = 0; i < node_previous_selection.size(); i++) {
Node *node = node_previous_selection.get(i);
for (Node *node : node_previous_selection) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -135,6 +135,7 @@ class SceneTreeDock : public VBoxContainer {

EditorData *editor_data = nullptr;
EditorSelection *editor_selection = nullptr;
List<Node *> node_previous_selection;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
List<Node *> node_previous_selection;
LocalVector<Node *> node_previous_selection;

No reason to use a List.
Also remember to reserve() before adding elements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@KoBeWi
Copy link
Member

KoBeWi commented Jul 3, 2025

You can't just connect script_changed to _update_script_button(), because it will update the button for every selected node. It should happen only once. You can add something like _queue_update_script_button().

@Kazuo256
Copy link
Contributor Author

Kazuo256 commented Jul 8, 2025

You can't just connect script_changed to _update_script_button(), because it will update the button for every selected node. It should happen only once. You can add something like _queue_update_script_button().

Makes sense. Do you have a suggestion for where to check for queued updates? My first guess would under the NOTIFICATION_PROCESS case in the _notification() method.

@KoBeWi
Copy link
Member

KoBeWi commented Jul 8, 2025

The usual pattern is

void queue_update() {
	if (is_update_queued) {
		return
	}
	is_update_queued = true
	call_deferred("actual_update")
}

Fixes godotengine#107059.

The SceneTreeDock was not tracking script changes in selected nodes in any capacity as far as I could assess. To do
that, my solution essentially connects the "script_changed" signal from selected nodes to
"SceneTreeDock::_update_script_button()" whenever the selection changes. It actually queues the update to make sure it
happens only once no matter how many nodes are selected.

However, only connecting that signal would leave previously selected nodes with a signal connection that should no
longer exist. To properly disconnect previously selected nodes, we have to store the list of currently selected nodes so
we can disconnect them when the selection changes.
@Kazuo256
Copy link
Contributor Author

Kazuo256 commented Jul 9, 2025

I've implemented the requested changes. One thing I realized is that clicking the script button in the scene tree dock to remove the script will call _update_script_button twice (regardless of how many nodes are selected). One because of the callback I added to the script_changed signal, and another as part of the usual logic of the remove script button. Is that OK or should I also adjust the script button to queue the update?

@KoBeWi
Copy link
Member

KoBeWi commented Jul 9, 2025

should I also adjust the script button to queue the update?

Now that we have a queue method, it can be used more. So yes.

Comment on lines +2908 to +2912
}

update_script_button_queued = true;

callable_mp(this, &SceneTreeDock::_update_script_button).call_deferred();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
update_script_button_queued = true;
callable_mp(this, &SceneTreeDock::_update_script_button).call_deferred();
}
update_script_button_queued = true;
callable_mp(this, &SceneTreeDock::_update_script_button).call_deferred();

Unnecessary empty lines.

@@ -2911,6 +2923,18 @@ void SceneTreeDock::_selection_changed() {
_push_item(nullptr);
}

// Track script changes in selected nodes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Track script changes in selected nodes
// Track script changes in selected nodes.

Also this comment should be when connecting the signal I think.

@@ -135,6 +135,8 @@ class SceneTreeDock : public VBoxContainer {

EditorData *editor_data = nullptr;
EditorSelection *editor_selection = nullptr;
LocalVector<Node *> node_previous_selection;
bool update_script_button_queued;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool update_script_button_queued;
bool update_script_button_queued = false;

@@ -4653,6 +4677,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
edited_scene = nullptr;
editor_data = &p_editor_data;
editor_selection = p_editor_selection;
update_script_button_queued = false;
Copy link
Member

@KoBeWi KoBeWi Jul 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary.
You might as well delete edited_scene above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The editor does not update the assigned script status
3 participants