Merge pull request #109590 from bruvzg/focus_checks

`find_*_valid_focus`: Check all tested neighbors to prevent loops.
This commit is contained in:
Thaddeus Crews 2025-09-30 18:35:00 -05:00
commit 45d064c388
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC

View file

@ -2392,10 +2392,12 @@ Control *Control::find_next_valid_focus() const {
} }
Control *from = const_cast<Control *>(this); Control *from = const_cast<Control *>(this);
HashSet<Control *> checked;
bool ac_enabled = get_tree() && get_tree()->is_accessibility_enabled(); bool ac_enabled = get_tree() && get_tree()->is_accessibility_enabled();
// Index of the current `Control` subtree within the containing `Window`. // Index of the current `Control` subtree within the containing `Window`.
int window_next = -1; int window_next = -1;
checked.insert(from);
while (true) { while (true) {
// Find next child. // Find next child.
@ -2457,9 +2459,10 @@ Control *Control::find_next_valid_focus() const {
return next_child; 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. 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. from = next_child; // Try to find the next control with focus mode FOCUS_ALL.
} }
@ -2496,10 +2499,12 @@ Control *Control::find_prev_valid_focus() const {
} }
Control *from = const_cast<Control *>(this); Control *from = const_cast<Control *>(this);
HashSet<Control *> checked;
bool ac_enabled = get_tree() && get_tree()->is_accessibility_enabled(); bool ac_enabled = get_tree() && get_tree()->is_accessibility_enabled();
// Index of the current `Control` subtree within the containing `Window`. // Index of the current `Control` subtree within the containing `Window`.
int window_prev = -1; int window_prev = -1;
checked.insert(from);
while (true) { while (true) {
// Find prev child. // Find prev child.
@ -2555,9 +2560,10 @@ Control *Control::find_prev_valid_focus() const {
return prev_child; 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. 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. from = prev_child; // Try to find the prev control with focus mode FOCUS_ALL.
} }