Skip to content

feat(keys): vim-style Ctrl+w pane focus navigation#108

Merged
peternaame-boop merged 1 commit into
masterfrom
feat/pane-focus-nav
Jun 21, 2026
Merged

feat(keys): vim-style Ctrl+w pane focus navigation#108
peternaame-boop merged 1 commit into
masterfrom
feat/pane-focus-nav

Conversation

@peternaame-boop

@peternaame-boop peternaame-boop commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Keyboard-only users couldn't move focus into the Playlists sidebar. on_key
intercepts every keystroke and calls prevent_default(), which suppresses
Textual's native Tab traversal, so the sidebar's ListView was unreachable —
on the Library page Tab did nothing at all.

This adds three rebindable vim-style window-navigation actions through the
keymap system (remappable in config.toml):

  • Ctrl+w h → Playlists sidebar (auto-shows it if hidden)
  • Ctrl+w l → main content, then the lyrics pane when it's visible
  • Ctrl+w w → cycle focus through the visible panes

Focusing the widget alone isn't enough: on_key routes movement keys to the
current page regardless of Textual focus. So a new _active_pane flag routes
move/select/filter to the existing PlaylistSidebar.handle_sidebar_action()
and the scroll subset to LyricsSidebar.handle_action(); everything else
falls through to the page. Focus resets to content when the sidebar is hidden
and on page navigation. Tab stays page-local — repurposing it globally would
regress Browse (sub-tab switch) and Context (track/album cycle).

Ctrl+w h is directional, matching vim splits: from the content pane it
reaches Playlists; from the lyrics pane it steps to content first.

Testing

  • Ran ruff format src/ tests/
  • Ran ruff check src/ tests/
  • Ran pytest tests/
  • Manually tested in the TUI (if UI change)

pytest → 951 passed, 2 skipped. pyright src/ytm_player/ → 0 errors. New
focused coverage in tests/test_app/test_pane_focus.py (keymap chord parsing,
the pane state machine, action routing).

Related

Updates the in-app help screen and docs/keybindings.md (the previous "Tab
focuses the next panel" line was inaccurate). No linked issue.

Keyboard-only users could not move focus to the Playlists sidebar: on_key
intercepts every keystroke and prevents Textual's native Tab traversal, so
the sidebar's ListView was unreachable.

Add three rebindable actions through the keymap system:
- Ctrl+w h  -> Playlists sidebar (auto-shows it if hidden)
- Ctrl+w l  -> main content, then lyrics when the lyrics pane is visible
- Ctrl+w w  -> cycle focus through the visible panes

Focus alone is insufficient because on_key routes movement keys to the
current page regardless of Textual focus, so an _active_pane flag routes
move/select/filter to the existing PlaylistSidebar.handle_sidebar_action()
and the scroll subset to LyricsSidebar.handle_action(); everything else
falls through to the page. Focus resets to content on hide and on page
navigation. Tab stays page-local (repurposing it would regress Browse and
Context). Help page + keybindings docs updated.
@peternaame-boop peternaame-boop merged commit 89dff43 into master Jun 21, 2026
11 checks passed
@peternaame-boop peternaame-boop deleted the feat/pane-focus-nav branch June 21, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant