Skip to content

Commit f6d5491

Browse files
committed
fix(Focus): re-focus ui if focus is lost but a direction is pressed
1 parent 452e217 commit f6d5491

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

core/systems/input/focus_group.gd

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func _ready():
5555

5656
# Try to find a focus node if one was not specified
5757
if not current_focus or not current_focus.is_visible_in_tree():
58-
current_focus = _find_focusable(parent.get_children(), parent)
58+
current_focus = find_focusable(parent.get_children(), parent)
5959

6060

6161
## Recalculate the focus neighbors of the container's children
@@ -118,7 +118,7 @@ func grab_focus() -> void:
118118
if not is_focused():
119119
focus_stack.push(self)
120120
if not current_focus:
121-
current_focus = _find_focusable(parent.get_children(), parent)
121+
current_focus = find_focusable(parent.get_children(), parent)
122122
logger.trace("Found focus node: " + str(current_focus))
123123
if current_focus:
124124
logger.info(parent.name + " grabbing focus on node: " + current_focus.name)
@@ -225,7 +225,8 @@ func _find_child_focus_group(nodes: Array[Node], root: Node = null) -> FocusGrou
225225

226226

227227
# Recursively searches the given node children for a focusable node.
228-
func _find_focusable(nodes: Array[Node], root: Node = null) -> Node:
228+
static func find_focusable(nodes: Array[Node], root: Node = null) -> Node:
229+
var logger := Log.get_logger("FocusGroup", Log.LEVEL.INFO)
229230
if nodes.size() == 0:
230231
logger.trace("Node has no children to check.")
231232
return null
@@ -236,7 +237,7 @@ func _find_focusable(nodes: Array[Node], root: Node = null) -> Node:
236237
# If the node is not a Control, try to find a child control node
237238
if not node is Control:
238239
logger.trace("Node not control. Checking children.")
239-
focusable = _find_focusable(node.get_children(), root)
240+
focusable = find_focusable(node.get_children(), root)
240241
if focusable:
241242
return focusable
242243
logger.trace("Node: " + node.name + " has no more children to check.")
@@ -254,7 +255,7 @@ func _find_focusable(nodes: Array[Node], root: Node = null) -> Node:
254255
return node
255256
# Otherwise try and recursively find a child that can be focused
256257
logger.trace("Node: " + node.name + " is not focusable. Checking its children.")
257-
focusable = _find_focusable(node.get_children(), root)
258+
focusable = find_focusable(node.get_children(), root)
258259
if focusable:
259260
return focusable
260261
logger.trace("Node has no focusable children.")

core/systems/input/input_manager.gd

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ func _input(event: InputEvent) -> void:
131131
return
132132
actions_pressed[action] = value
133133

134+
# If no focus exists and a direction is pressed, try to find a new focus
135+
if event.is_action("ui_left") or event.is_action("ui_right") or event.is_action("ui_up") or event.is_action("ui_down"):
136+
if not get_viewport().gui_get_focus_owner():
137+
logger.debug("Focus lost. Finding something to focus.")
138+
var new_focus := _find_focus()
139+
if new_focus:
140+
logger.debug("Found something to focus:", new_focus)
141+
new_focus.grab_focus.call_deferred()
142+
return
143+
134144
# Handle guide button inputs
135145
if event.is_action("ogui_guide"):
136146
_guide_input(event)
@@ -208,6 +218,16 @@ func _input(event: InputEvent) -> void:
208218
action_release(dbus_path, "ogui_search")
209219

210220

221+
## Find a node to grab focus on if no focus exists
222+
func _find_focus() -> Node:
223+
var main := get_tree().get_first_node_in_group("main")
224+
if not main:
225+
logger.debug("Unable to find main node to find focus. Is there a node in the 'main' node group?")
226+
return null
227+
228+
return FocusGroup.find_focusable([main])
229+
230+
211231
## Handle guide button events and determine whether this is a guide action
212232
## (e.g. guide + A to open the Quick Bar), or if it's just a normal guide button press.
213233
func _guide_input(event: InputEvent) -> void:

core/systems/input/overlay_mode_input_manager.gd

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ func _input(event: InputEvent) -> void:
9898
return
9999
actions_pressed[action] = value
100100

101+
# If no focus exists and a direction is pressed, try to find a new focus
102+
if event.is_action("ui_left") or event.is_action("ui_right") or event.is_action("ui_up") or event.is_action("ui_down"):
103+
if not get_viewport().gui_get_focus_owner():
104+
logger.debug("Focus lost. Finding something to focus.")
105+
var new_focus := _find_focus()
106+
if new_focus:
107+
logger.debug("Found something to focus:", new_focus)
108+
new_focus.grab_focus.call_deferred()
109+
return
110+
101111
# Handle guide button inputs
102112
if event.is_action("ogui_guide_ov"):
103113
_guide_input(event)
@@ -250,6 +260,16 @@ func _input(event: InputEvent) -> void:
250260
get_viewport().set_input_as_handled()
251261

252262

263+
## Find a node to grab focus on if no focus exists
264+
func _find_focus() -> Node:
265+
var main := get_tree().get_first_node_in_group("main")
266+
if not main:
267+
logger.debug("Unable to find main node to find focus. Is there a node in the 'main' node group?")
268+
return null
269+
270+
return FocusGroup.find_focusable([main])
271+
272+
253273
## Handle guide button events and determine whether this is a guide action
254274
## (e.g. guide + A to open the Quick Bar), or if it's just a normal guide button press.
255275
func _guide_input(event: InputEvent) -> void:

0 commit comments

Comments
 (0)