@@ -972,6 +972,17 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) {
972972}
973973
974974bool SceneTreeEditor::_update_filter (TreeItem *p_parent, bool p_scroll_to_selected) {
975+ TreeItem *last_selected = nullptr ;
976+ bool result = _update_filter_helper (p_parent, p_scroll_to_selected, last_selected);
977+ if (p_scroll_to_selected && last_selected) {
978+ // Scrolling to the first selected in the _update_filter call above followed by the last
979+ // selected here is enough to frame all selected items as well as possible.
980+ callable_mp (tree, &Tree::scroll_to_item).call_deferred (last_selected, false );
981+ }
982+ return result;
983+ }
984+
985+ bool SceneTreeEditor::_update_filter_helper (TreeItem *p_parent, bool p_scroll_to_selected, TreeItem *&r_last_selected) {
975986 if (!p_parent) {
976987 p_parent = tree->get_root ();
977988 filter_term_warning.clear ();
@@ -1026,7 +1037,8 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select
10261037 bool keep_for_children = false ;
10271038 for (TreeItem *child = p_parent->get_first_child (); child; child = child->get_next ()) {
10281039 // Always keep if at least one of the children are kept.
1029- keep_for_children = _update_filter (child, p_scroll_to_selected) || keep_for_children;
1040+ // Only scroll if we haven't already found a child to scroll to.
1041+ keep_for_children = _update_filter_helper (child, p_scroll_to_selected && !keep_for_children, r_last_selected) || keep_for_children;
10301042 }
10311043
10321044 if (!is_root) {
@@ -1099,9 +1111,13 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select
10991111 if (editor_selection) {
11001112 Node *n = get_node (p_parent->get_metadata (0 ));
11011113 if (selectable) {
1102- if (p_scroll_to_selected && n && editor_selection->is_selected (n)) {
1103- // Needs to be deferred to account for possible root visibility change.
1104- callable_mp (tree, &Tree::scroll_to_item).call_deferred (p_parent, false );
1114+ if (n && editor_selection->is_selected (n)) {
1115+ if (p_scroll_to_selected) {
1116+ // Needs to be deferred to account for possible root visibility change.
1117+ callable_mp (tree, &Tree::scroll_to_item).call_deferred (p_parent, false );
1118+ } else {
1119+ r_last_selected = p_parent;
1120+ }
11051121 }
11061122 } else if (n) {
11071123 editor_selection->remove_node (n);
0 commit comments