gamepad: Implement directional nav of sidebar

This commit is contained in:
Zoey Ahmed
2025-12-29 12:32:47 +00:00
parent c93a11375e
commit b6d73e0efe

View File

@@ -153,10 +153,28 @@ class Gamepad(GObject.Object):
self.window.props.focus_visible = True self.window.props.focus_visible = True
return return
if self._is_focused_on_sidebar():
# The usual behaviour of child_focus() on the sidebar
# would result in the + button being focused, instead of the grid
# so we need to grab the focus of the grid if the user inputs the
# corresponding direction to the grid.
grid_direction = self._get_rtl_direction(
Gtk.DirectionType.LEFT, Gtk.DirectionType.RIGHT
)
if direction is grid_direction:
self.window.grid.grab_focus()
return
self.window.sidebar.keynav_failed(direction)
return
if self._can_navigate_games_page(): if self._can_navigate_games_page():
self._navigate_to_game_position( if not self._get_focused_game():
self._get_current_position() return
+ (
new_pos = self._get_current_position() + (
-1 -1
if direction if direction
== self._get_rtl_direction( == self._get_rtl_direction(
@@ -164,7 +182,17 @@ class Gamepad(GObject.Object):
) )
else 1 else 1
) )
)
# If the user is focused on the first game and tries to go
# back another game, instead of failing, the focus should
# change to the sidebar.
if new_pos < 0:
self.window.sidebar.grab_focus()
self.window.props.focus_visible = True
return
self._navigate_to_game_position(new_pos)
return return
if self.window.navigation_view.props.visible_page_tag == "details": if self.window.navigation_view.props.visible_page_tag == "details":
@@ -184,6 +212,14 @@ class Gamepad(GObject.Object):
self.window.grid.grab_focus() self.window.grid.grab_focus()
return return
if self._is_focused_on_sidebar():
if self.window.sidebar.child_focus(direction):
self.window.props.focus_visible = True
return
self.window.sidebar.keynav_failed(direction)
return
if self._can_navigate_games_page(): if self._can_navigate_games_page():
if not (game := self._get_focused_game()): if not (game := self._get_focused_game()):
return return
@@ -297,6 +333,9 @@ class Gamepad(GObject.Object):
and not self._get_active_menu_button() and not self._get_active_menu_button()
) )
def _is_focused_on_sidebar(self) -> bool:
return bool(self.window.sidebar.get_focus_child())
def _n_grid_games(self) -> int: def _n_grid_games(self) -> int:
return cast(Gtk.SingleSelection, self.window.grid.props.model).props.n_items return cast(Gtk.SingleSelection, self.window.grid.props.model).props.n_items