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. }