From f260c5db8a643d06bd079935cfc0f3f8898c1916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Wed, 13 Aug 2025 23:59:01 +0300 Subject: [PATCH] `find_*_valid_focus`: Check all tested neighbors to prevent loops. --- scene/gui/control.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index d12a87ded4b..5e7cbaf531f 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2391,10 +2391,12 @@ Control *Control::find_next_valid_focus() const { } Control *from = const_cast(this); + HashSet checked; bool ac_enabled = get_tree() && get_tree()->is_accessibility_enabled(); // Index of the current `Control` subtree within the containing `Window`. int window_next = -1; + checked.insert(from); while (true) { // Find next child. @@ -2456,9 +2458,10 @@ Control *Control::find_next_valid_focus() const { return next_child; } - if (next_child == from || next_child == this) { + if (checked.has(next_child)) { return nullptr; // Stuck in a loop with no next control. } + checked.insert(next_child); from = next_child; // Try to find the next control with focus mode FOCUS_ALL. } @@ -2495,10 +2498,12 @@ Control *Control::find_prev_valid_focus() const { } Control *from = const_cast(this); + HashSet checked; bool ac_enabled = get_tree() && get_tree()->is_accessibility_enabled(); // Index of the current `Control` subtree within the containing `Window`. int window_prev = -1; + checked.insert(from); while (true) { // Find prev child. @@ -2554,9 +2559,10 @@ Control *Control::find_prev_valid_focus() const { return prev_child; } - if (prev_child == from || prev_child == this) { + if (checked.has(prev_child)) { return nullptr; // Stuck in a loop with no prev control. } + checked.insert(prev_child); from = prev_child; // Try to find the prev control with focus mode FOCUS_ALL. }