Skip to content

Build fixes, Xbox controller support, and movie/TV search#89

Closed
CyberoniOntoni wants to merge 8 commits into
dfederm:mainfrom
CyberoniOntoni:feature/xbox-controller-navigation
Closed

Build fixes, Xbox controller support, and movie/TV search#89
CyberoniOntoni wants to merge 8 commits into
dfederm:mainfrom
CyberoniOntoni:feature/xbox-controller-navigation

Conversation

@CyberoniOntoni

@CyberoniOntoni CyberoniOntoni commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves JellyBox build reliability, subtitle playback, Xbox Series X/S controller navigation, shell-level search, and library browsing on console.

It includes the work from #88 plus additional controller, search, and navigation features.

Build and restore (VS 2026 / CPM)

  • Fix Central Package Management discovery via DirectoryPackagesPropsPath
  • Pin Kiota packages to 1.22.0 (addresses NU1903)
  • Harden appx manifest versioning for Visual Studio builds
  • Add win-x64.pubxml publish profile for Native AOT Xbox sideload builds
  • Target Xbox OS 22000+ in manifest and use JellyBox.exe entry point for AOT packages

Subtitle playback

  • Load only the selected external subtitle stream when the client can render subtitles
  • Reduce subtitle track churn and dispatcher overhead during playback
  • Cache max streaming bitrate per playback session

Xbox controller and navigation

  • Centralize gamepad input in GamepadInput and handle shell navigation at the CoreWindow level
  • Map video controls (A play/pause, X mute, sticks/D-pad volume and seek, LB/RB skip)
  • Support B/View/Menu consistently across shell pages
  • Add ShellFocusCoordinator so search is not auto-focused; fix invalid FocusState.Unfocused crash on navigation

Search

  • Persistent search bar in the main shell with debounced Jellyfin hints
  • Search results page with portrait cards
  • Fixes for AutoSuggestBox binding and navigation races when opening item details

Library navigation

  • Route Home "My Media" collection tiles through the same path as the side menu (NavigateToItem(BaseItemDto))
  • Add CollectionNavigation mapping for Movies, TV Shows, Collections (box sets), and Books
  • Move library filter toolbar XYFocus bindings to code-behind for Xbox stability

Test plan

  • Release/Debug x64 build succeeds in VS 2026
  • App launches and browses library/home on Xbox Series X (dev mode)
  • Side menu: Movies, TV Shows, Collections, and Books open library views
  • Home: Movies and TV Shows tiles open the same library views as the side menu
  • Subtitle playback without severe lag
  • Search finds movies and TV shows; selecting opens item details
  • Xbox navigation and search focus behavior verified on hardware

Notes

Build/restore: pin Directory.Packages.props path for Visual Studio CPM discovery; pin Microsoft.Kiota.* to 1.22.0 (fixes NU1903); harden SetAppxManifestVersion with explicit manifest path and BuildVersion fallback.

Playback: prefer direct play without subtitle index when client-side rendering is supported; load only the selected external subtitle; download external subtitles with Jellyfin auth via CreateFromStream; cache bitrate test per session; reduce subtitle presentation churn.
Centralize gamepad virtual-key handling in GamepadInput and route shell navigation (menu toggle, left-edge open, B/Escape back) through NavigationManager at the CoreWindow level so it works on every content page, not only when MainPage has focus.

Video playback now maps A to play/pause, X to mute, and D-pad/stick directions to volume and seeking. Login and server selection accept Gamepad A to submit. WebVideo supports B to go back.
Place a styled AutoSuggestBox at the top of MainPage with debounced Jellyfin search hints. Submitting a query or picking a suggestion navigates to search results or item details. Includes a dedicated Search page with portrait result cards and adjusted content page spacing for the new header.
Replace nested TwoWay x:Bind on search text with code-behind TextChanged handling, use ObservableCollection for suggestions with TextMemberPath, simplify the search box style, and restore full-screen navigation overlay span.
Suppress duplicate QuerySubmitted navigation after SuggestionChosen, cancel stale ItemDetails loads when navigating away, and guard against null UserData on series items.
Defer AutoSuggestBox suggestion navigation to the next UI frame, reset ItemDetails playback state between loads, use null-safe stream bindings, navigate cards by item id, and log unhandled exceptions to the debug output.
AutoSuggestBox TextMemberPath requires WinRT bindable custom properties on suggestion items. Selection text is already applied in code when a suggestion is chosen.
Route Home page collection tiles through the same navigation path as the side menu so Movies, TV Shows, Collections, and Books open the library view instead of item details. Add CollectionNavigation to map Jellyfin collection types to library parameters.

Introduce ShellFocusCoordinator so search is not focused by default and navigation no longer calls the invalid FocusState.Unfocused API on Xbox. Move library filter toolbar XYFocus bindings to code-behind for console stability.

Target Xbox in the app manifest (min OS 22000, JellyBox.exe entry for AOT) and add a win-x64 publish profile for Release sideload builds.

@dfederm dfederm left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! I only really skimmed the changes for now as it's over 1000 lines to look at and intertwined with your changes in #88. Tease these apart in to separate PRs so I can review them independently in bite-sized chunks.


SystemNavigationManager.GetForCurrentView().BackRequested += BackRequested;
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += AcceleratorKeyActivated;
Window.Current.CoreWindow.KeyDown += CoreWindowKeyDown;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is event registration is never removed and collides with full-screen players. Both the Video and WebVideo pages register their own CoreWindow.KeyDown, so during playback both fire.

// TODO: Some kind of error message. Or genericize the collection view.
}
else
if (CollectionNavigation.TryCreateLibraryParameters(item, out Library.Parameters libraryParameters))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unmapped collections (Music, etc) now map to ItemDetails instead of no-op'ing. Likely that's a broken details page for those, so this should either preserve the old no-op behavior or I'd like to see that the experience is at least non-broken (doesn't need to be optimized; a nop isn't great either but is is non-broken).

/// <summary>
/// Automatically focuses the first item in a list once items are loaded and containers are realized.
/// </summary>
#pragma warning disable CA1812 // Instantiated via XAML Interaction.Behaviors.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing these warnings. Can you explain?

ImageHeight = imageHeight,
Image = image,
NavigateCommand = new RelayCommand(() => _navigationManager.NavigateToItem(item)),
NavigateCommand = item.Type == BaseItemDto_Type.CollectionFolder

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch is redundant. You can always just pass the full item.

public void NavigateToItem(Guid itemId)
{
CurrentItem = itemId;
NavigateContentFrame<ItemDetails>(new ItemDetails.Parameters(itemId));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems pretty brittle. What if the item is a collection?

@CyberoniOntoni

Copy link
Copy Markdown
Contributor Author

Split per your feedback — closing this monolithic PR in favor of bite-sized, ordered reviews.

Upstream PR stack (merge in order)

# PR ~scope
1 #88 — build reliability + subtitle playback build/csproj + video subtitles
2 #93 — Xbox controller + shell navigation GamepadInput, NavigationManager, video controls
3 #94 — shell search (movies/TV) search bar, results page, crash fixes
4 #95 — library navigation + Xbox focus CollectionNavigation, ShellFocusCoordinator, manifest/pubxml

Bite-sized diffs (fork stacked PRs)

If you prefer reviewing only the incremental diff for each step:

  1. CyberoniOntoni/JellyBox#1 — controller on top of Fix build reliability and improve subtitle playback performance #88 branch
  2. CyberoniOntoni/JellyBox#3 — search only
  3. CyberoniOntoni/JellyBox#2 — library navigation only

Sorry for the large combined diff — happy to adjust the split further if you'd like a different grouping.

@CyberoniOntoni

Copy link
Copy Markdown
Contributor Author

Superseded by #88, #93, #94, and #95 — see last comment for merge order.

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.

2 participants