From 2cb49cf680123c8cae36016cf11cfc0903b59e76 Mon Sep 17 00:00:00 2001 From: Voyager Date: Sat, 22 Aug 2026 23:10:41 -0400 Subject: [PATCH] Preserve profile name input focus --- ...ontroller_menu_accessibility_validation.gd | 7 ++ ui/profile_page.gd | 90 ++++++++++--------- 2 files changed, 55 insertions(+), 42 deletions(-) diff --git a/tests/controller_menu_accessibility_validation.gd b/tests/controller_menu_accessibility_validation.gd index 4176ddc..c2a58ee 100644 --- a/tests/controller_menu_accessibility_validation.gd +++ b/tests/controller_menu_accessibility_validation.gd @@ -735,6 +735,13 @@ func _validate_profile_confirmation_focus() -> void: page.call("activate") page.call("set_interactive", true) page.call("reset_controller_zone") + var name_edit := page.get("_name_edit") as LineEdit + name_edit.grab_focus() + page.call("_on_name_changed", "V") + _expect( + root.gui_get_focus_owner() == name_edit, + "Typing a profile name released the active name field.", + ) var suggestions := page.get("_suggestions") as HBoxContainer var suggestion := Button.new() suggestion.text = "alternate name" diff --git a/ui/profile_page.gd b/ui/profile_page.gd index be15a0f..ece0673 100644 --- a/ui/profile_page.gd +++ b/ui/profile_page.gd @@ -365,54 +365,60 @@ func _apply_controller_zone_focus() -> void: var control := item as Control if control != null and control not in all_option_controls: all_option_controls.append(control) - for control: Control in account_controls + category_controls + all_option_controls: - control.focus_mode = Control.FOCUS_NONE + var active_controls: Array[Control] = [] + if _profile_interactive: + if _discard_confirmation != null and _discard_confirmation.visible: + active_controls = [ + _confirmation_confirm, + _keep_editing_button, + ] + else: + match _controller_zone: + ControllerZone.ACCOUNT: + active_controls = account_controls + ControllerZone.CATEGORIES: + active_controls = category_controls + ControllerZone.OPTIONS: + if not option_groups.is_empty(): + _controller_option_depth = clampi( + _controller_option_depth, + 0, + option_groups.size() - 1, + ) + for item: Variant in option_groups[ + _controller_option_depth + ]: + var control := item as Control + if control != null: + active_controls.append(control) + ControllerZone.COLOR_PICKER: + active_controls = _color_picker_controller_controls() + var controlled_controls: Array[Control] = ( + account_controls + category_controls + all_option_controls + ) for control: Control in [_confirmation_confirm, _keep_editing_button]: - if control != null: - control.focus_mode = Control.FOCUS_NONE + if control != null and control not in controlled_controls: + controlled_controls.append(control) + for control: Control in controlled_controls: + var button := control as BaseButton + var requested_focus_mode := ( + Control.FOCUS_ALL + if ( + control in active_controls + and (button == null or not button.disabled) + ) + else Control.FOCUS_NONE + ) + # Reassigning FOCUS_NONE to every control before restoring the active zone + # drops an active LineEdit after its first text_changed signal. + if control.focus_mode != requested_focus_mode: + control.focus_mode = requested_focus_mode if _preview != null: _preview.focus_mode = Control.FOCUS_NONE if _reset_view_button != null: _reset_view_button.focus_mode = Control.FOCUS_NONE - if not _profile_interactive: + if not _profile_interactive or active_controls.is_empty(): return - if _discard_confirmation != null and _discard_confirmation.visible: - var confirmation_controls: Array[Control] = [ - _confirmation_confirm, - _keep_editing_button, - ] - for control: Control in confirmation_controls: - control.focus_mode = Control.FOCUS_ALL - ControllerFocusNavigation.configure_spatial_neighbors( - confirmation_controls - ) - return - var active_controls: Array[Control] = [] - match _controller_zone: - ControllerZone.ACCOUNT: - active_controls = account_controls - ControllerZone.CATEGORIES: - active_controls = category_controls - ControllerZone.OPTIONS: - if not option_groups.is_empty(): - _controller_option_depth = clampi( - _controller_option_depth, - 0, - option_groups.size() - 1, - ) - for item: Variant in option_groups[_controller_option_depth]: - var control := item as Control - if control != null: - active_controls.append(control) - ControllerZone.COLOR_PICKER: - active_controls = _color_picker_controller_controls() - for control: Control in active_controls: - var button := control as BaseButton - control.focus_mode = ( - Control.FOCUS_ALL - if button == null or not button.disabled - else Control.FOCUS_NONE - ) ControllerFocusNavigation.configure_spatial_neighbors(active_controls)