Skip to content

UI - Version 2 - #283

Open
mpotrykus wants to merge 2 commits into
TheElixZammuto:masterfrom
mpotrykus:UI/V2
Open

UI - Version 2#283
mpotrykus wants to merge 2 commits into
TheElixZammuto:masterfrom
mpotrykus:UI/V2

Conversation

@mpotrykus

Copy link
Copy Markdown
Contributor

UI - Version 2


I have been working on this UI rework for around a year, off-and-on. This is meant to be a complete overhaul of the front-end, with no changes to the back-end and stream-handling. Only a few instances of app-hardening.

I have been testing this on XSX and Xbox One for a few months, and have resolved any bugs I could find. That does not mean there will be none, but that I have exhausted what QA work I can do alone.

I am dedicated to work on any requested edits to get this merged. Feel free to ask or open any discussion. I will either defend my code or be happy to make the change.

Disclaimer: AI was used to help me write out areas. I have reviewed and rewritten most of it. I take ownership of anything you find and have reviewed it all line-by-line.

Builds


I have builds available here to test:
UI-VR2
UI-VR2-nightly

Preview


Moonlight.UWP.-.UIV2.Demo.20260729.output._1.1.mp4

Headline changes

  • Full UI rework: pages moved into new UI/ tree (Pages, Modals, Models, Styles, Utilities) with a real design system (Colors.xaml, Controls.xaml)
  • List/grid toggle, per-host backgrounds/accent colors, favorites, and a new animated background system (DynamicBackgroundHost, EffectsLibrary, ImageHelpers)
  • Consistent modal vocabulary (UI/Modals/*) replacing ad-hoc ContentDialog usage
  • Leveled logging + crash diagnostics (MLOG/MLOGF, InstallCrashHandlers, in-app log viewer)
  • Several misc. fixes in the connection/state layer

Page-level highlights

  • AppPage: list/grid views, search, favorites, per-app blurred backgrounds, first MVVM view-model (AppPageViewModel), new hamburger menu
  • HostSelectorPage: dedicated modals for add/pair/alert/confirm/actions/test-connection
  • HostSettingsPage: full personalization UI (background/effects/accent picker)
  • MoonlightSettings: new in-app log viewer tab
  • StreamPage: new overlay menu

Core/connection fixes

  • IsConnectionTerminated fixed to be per-instance (was global, causing state bleed)
  • Connect() mutex + freed-hostname leak fix on reconnect
  • Rumble fallback to GamepadVibration when no handler registered
  • Per-host box-art cache namespacing + stale-image sweep
  • ApplicationState::RemoveHost no-longer-crashes-on-not-found bug fix
  • libgamestream: SRWLOCK fixes concurrent gs_init() race; HTTP status codes now checked (no more caching 404s as success)

…tartConnection failures, remove dead EffectsLibrary blur/glow code
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 158 files, which is 8 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a7b14e92-4d96-45d4-8c01-50ff0545e334

📥 Commits

Reviewing files that changed from the base of the PR and between 261303b and ba62432.

⛔ Files ignored due to path filters (61)
  • Assets/LargeTile.scale-100.png is excluded by !**/*.png
  • Assets/LargeTile.scale-125.png is excluded by !**/*.png
  • Assets/LargeTile.scale-150.png is excluded by !**/*.png
  • Assets/LargeTile.scale-200.png is excluded by !**/*.png
  • Assets/LargeTile.scale-400.png is excluded by !**/*.png
  • Assets/Play1.png is excluded by !**/*.png
  • Assets/SmallTile.scale-100.png is excluded by !**/*.png
  • Assets/SmallTile.scale-125.png is excluded by !**/*.png
  • Assets/SmallTile.scale-150.png is excluded by !**/*.png
  • Assets/SmallTile.scale-200.png is excluded by !**/*.png
  • Assets/SmallTile.scale-400.png is excluded by !**/*.png
  • Assets/SplashScreen.scale-100.png is excluded by !**/*.png
  • Assets/SplashScreen.scale-125.png is excluded by !**/*.png
  • Assets/SplashScreen.scale-150.png is excluded by !**/*.png
  • Assets/SplashScreen.scale-200.png is excluded by !**/*.png
  • Assets/SplashScreen.scale-400.png is excluded by !**/*.png
  • Assets/Square150x150Logo.scale-100.png is excluded by !**/*.png
  • Assets/Square150x150Logo.scale-125.png is excluded by !**/*.png
  • Assets/Square150x150Logo.scale-150.png is excluded by !**/*.png
  • Assets/Square150x150Logo.scale-200.png is excluded by !**/*.png
  • Assets/Square150x150Logo.scale-400.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-unplated_targetsize-16.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-unplated_targetsize-256.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-unplated_targetsize-32.png is excluded by !**/*.png
  • Assets/Square44x44Logo.altform-unplated_targetsize-48.png is excluded by !**/*.png
  • Assets/Square44x44Logo.scale-100.png is excluded by !**/*.png
  • Assets/Square44x44Logo.scale-125.png is excluded by !**/*.png
  • Assets/Square44x44Logo.scale-150.png is excluded by !**/*.png
  • Assets/Square44x44Logo.scale-200.png is excluded by !**/*.png
  • Assets/Square44x44Logo.scale-400.png is excluded by !**/*.png
  • Assets/Square44x44Logo.targetsize-16.png is excluded by !**/*.png
  • Assets/Square44x44Logo.targetsize-24.png is excluded by !**/*.png
  • Assets/Square44x44Logo.targetsize-24_altform-unplated.png is excluded by !**/*.png
  • Assets/Square44x44Logo.targetsize-256.png is excluded by !**/*.png
  • Assets/Square44x44Logo.targetsize-32.png is excluded by !**/*.png
  • Assets/Square44x44Logo.targetsize-48.png is excluded by !**/*.png
  • Assets/StoreLogo.scale-100.png is excluded by !**/*.png
  • Assets/StoreLogo.scale-125.png is excluded by !**/*.png
  • Assets/StoreLogo.scale-150.png is excluded by !**/*.png
  • Assets/StoreLogo.scale-200.png is excluded by !**/*.png
  • Assets/StoreLogo.scale-400.png is excluded by !**/*.png
  • Assets/Wide310x150Logo.scale-100.png is excluded by !**/*.png
  • Assets/Wide310x150Logo.scale-125.png is excluded by !**/*.png
  • Assets/Wide310x150Logo.scale-150.png is excluded by !**/*.png
  • Assets/Wide310x150Logo.scale-200.png is excluded by !**/*.png
  • Assets/Wide310x150Logo.scale-400.png is excluded by !**/*.png
  • Assets/grid.png is excluded by !**/*.png
  • Assets/loading2.gif is excluded by !**/*.gif
  • Assets/logo1.gif is excluded by !**/*.gif
  • Assets/logo1.png is excluded by !**/*.png
  • Assets/logo2.gif is excluded by !**/*.gif
  • Assets/logo_a.gif is excluded by !**/*.gif
  • Assets/orbit_load.gif is excluded by !**/*.gif
  • Assets/orbit_load2.gif is excluded by !**/*.gif
  • Assets/orbit_load3.gif is excluded by !**/*.gif
  • Assets/play.png is excluded by !**/*.png
📒 Files selected for processing (175)
  • App.xaml
  • App.xaml.cpp
  • App.xaml.h
  • Common/DeviceResources.cpp
  • Common/DirectXHelper.h
  • Common/ModalDialog.xaml
  • Common/ModalDialog.xaml.cpp
  • Common/ModalDialog.xaml.h
  • Common/TextConsole.cpp
  • Common/TextConsole.h
  • Converters/BoolToTextConverter.h
  • MoonlightWelcome.xaml
  • Pages/AppPage.xaml
  • Pages/AppPage.xaml.cpp
  • Pages/AppPage.xaml.h
  • Pages/HostSelectorPage.xaml
  • Pages/HostSelectorPage.xaml.cpp
  • Pages/HostSelectorPage.xaml.h
  • Pages/HostSettingsPage.xaml
  • Pages/HostSettingsPage.xaml.cpp
  • Pages/MoonlightSettings.xaml
  • Pages/MoonlightSettings.xaml.cpp
  • Pages/MoonlightSettings.xaml.h
  • Pages/StreamPage.xaml
  • State/ApplicationState.cpp
  • State/ApplicationState.h
  • State/GamepadState.h
  • State/MDNSHandler.cpp
  • State/MDNSHandler.h
  • State/MoonlightApp.cpp
  • State/MoonlightApp.h
  • State/MoonlightClient.cpp
  • State/MoonlightClient.h
  • State/MoonlightHost.cpp
  • State/MoonlightHost.h
  • State/Stats.cpp
  • State/StreamConfiguration.h
  • Streaming/AudioPlayer.cpp
  • Streaming/FFmpegDecoder.cpp
  • Streaming/FrameQueue.cpp
  • Streaming/LogRenderer.cpp
  • Streaming/Pacer.cpp
  • Streaming/VideoRenderer.cpp
  • Streaming/moonlight_xbox_dxMain.cpp
  • Streaming/moonlight_xbox_dxMain.h
  • UI/Backgrounds/BackgroundRegistry.h
  • UI/Backgrounds/BackgroundSettingsHelpers.h
  • UI/Backgrounds/Blobs/BlobsBackground.xaml
  • UI/Backgrounds/Blobs/BlobsBackground.xaml.cpp
  • UI/Backgrounds/Blobs/BlobsBackground.xaml.h
  • UI/Backgrounds/Blobs/BlobsSettingsControl.xaml
  • UI/Backgrounds/Blobs/BlobsSettingsControl.xaml.cpp
  • UI/Backgrounds/Blobs/BlobsSettingsControl.xaml.h
  • UI/Backgrounds/DynamicBackgroundHost.xaml
  • UI/Backgrounds/DynamicBackgroundHost.xaml.cpp
  • UI/Backgrounds/DynamicBackgroundHost.xaml.h
  • UI/Backgrounds/GlobeGrid/GlobeGridBackground.xaml
  • UI/Backgrounds/GlobeGrid/GlobeGridBackground.xaml.cpp
  • UI/Backgrounds/GlobeGrid/GlobeGridBackground.xaml.h
  • UI/Backgrounds/Orbs/OrbsBackground.xaml
  • UI/Backgrounds/Orbs/OrbsBackground.xaml.cpp
  • UI/Backgrounds/Orbs/OrbsBackground.xaml.h
  • UI/Backgrounds/Orbs/OrbsSettingsControl.xaml
  • UI/Backgrounds/Orbs/OrbsSettingsControl.xaml.cpp
  • UI/Backgrounds/Orbs/OrbsSettingsControl.xaml.h
  • UI/Backgrounds/Particles/ParticleBackground.xaml
  • UI/Backgrounds/Particles/ParticleBackground.xaml.cpp
  • UI/Backgrounds/Particles/ParticleBackground.xaml.h
  • UI/Backgrounds/Particles/ParticleSettingsControl.xaml
  • UI/Backgrounds/Particles/ParticleSettingsControl.xaml.cpp
  • UI/Backgrounds/Particles/ParticleSettingsControl.xaml.h
  • UI/Backgrounds/README.md
  • UI/Backgrounds/Spheres/SpheresBackground.xaml
  • UI/Backgrounds/Spheres/SpheresBackground.xaml.cpp
  • UI/Backgrounds/Spheres/SpheresBackground.xaml.h
  • UI/Backgrounds/Spheres/SpheresSettingsControl.xaml
  • UI/Backgrounds/Spheres/SpheresSettingsControl.xaml.cpp
  • UI/Backgrounds/Spheres/SpheresSettingsControl.xaml.h
  • UI/Backgrounds/Streaks/StreaksBackground.xaml
  • UI/Backgrounds/Streaks/StreaksBackground.xaml.cpp
  • UI/Backgrounds/Streaks/StreaksBackground.xaml.h
  • UI/Backgrounds/Streaks/StreaksSettingsControl.xaml
  • UI/Backgrounds/Streaks/StreaksSettingsControl.xaml.cpp
  • UI/Backgrounds/Streaks/StreaksSettingsControl.xaml.h
  • UI/Backgrounds/SwipeReveal/SwipeRevealBackground.xaml
  • UI/Backgrounds/SwipeReveal/SwipeRevealBackground.xaml.cpp
  • UI/Backgrounds/SwipeReveal/SwipeRevealBackground.xaml.h
  • UI/Controls/AspectRatioBox.xaml
  • UI/Controls/AspectRatioBox.xaml.cpp
  • UI/Controls/AspectRatioBox.xaml.h
  • UI/Controls/LunarPhaseControl.xaml
  • UI/Controls/LunarPhaseControl.xaml.cpp
  • UI/Controls/LunarPhaseControl.xaml.h
  • UI/Controls/SlidingMenu.xaml
  • UI/Controls/SlidingMenu.xaml.cpp
  • UI/Controls/SlidingMenu.xaml.h
  • UI/Controls/SwatchPicker.xaml
  • UI/Controls/SwatchPicker.xaml.cpp
  • UI/Controls/SwatchPicker.xaml.h
  • UI/Controls/TabsLayout.xaml
  • UI/Controls/TabsLayout.xaml.cpp
  • UI/Controls/TabsLayout.xaml.h
  • UI/Converters/BoolToTextConverter.cpp
  • UI/Converters/BoolToTextConverter.h
  • UI/Converters/BoolToVisibilityConverter.cpp
  • UI/Converters/BoolToVisibilityConverter.h
  • UI/Modals/AddHostDialog.xaml
  • UI/Modals/AddHostDialog.xaml.cpp
  • UI/Modals/AddHostDialog.xaml.h
  • UI/Modals/AlertDialog.xaml
  • UI/Modals/AlertDialog.xaml.cpp
  • UI/Modals/AlertDialog.xaml.h
  • UI/Modals/AppActionsDialog.xaml
  • UI/Modals/AppActionsDialog.xaml.cpp
  • UI/Modals/AppActionsDialog.xaml.h
  • UI/Modals/ConfirmDialog.xaml
  • UI/Modals/ConfirmDialog.xaml.cpp
  • UI/Modals/ConfirmDialog.xaml.h
  • UI/Modals/HostActionsDialog.xaml
  • UI/Modals/HostActionsDialog.xaml.cpp
  • UI/Modals/HostActionsDialog.xaml.h
  • UI/Modals/PairDialog.xaml
  • UI/Modals/PairDialog.xaml.cpp
  • UI/Modals/PairDialog.xaml.h
  • UI/Modals/StreamErrorDialog.xaml
  • UI/Modals/StreamErrorDialog.xaml.cpp
  • UI/Modals/StreamErrorDialog.xaml.h
  • UI/Modals/TestConnectionResultDialog.xaml
  • UI/Modals/TestConnectionResultDialog.xaml.cpp
  • UI/Modals/TestConnectionResultDialog.xaml.h
  • UI/Models/MenuItem.cpp
  • UI/Models/MenuItem.h
  • UI/Models/UIPersonalization.h
  • UI/Models/ViewModels/AppPageViewModel.cpp
  • UI/Models/ViewModels/AppPageViewModel.h
  • UI/Pages/AppPage/AppPage.Resources.Grid.xaml
  • UI/Pages/AppPage/AppPage.Resources.List.xaml
  • UI/Pages/AppPage/AppPage.Resources.xaml
  • UI/Pages/AppPage/AppPage.Selection.cpp
  • UI/Pages/AppPage/AppPage.xaml
  • UI/Pages/AppPage/AppPage.xaml.cpp
  • UI/Pages/AppPage/AppPage.xaml.h
  • UI/Pages/HostSelectorPage.xaml
  • UI/Pages/HostSelectorPage.xaml.cpp
  • UI/Pages/HostSelectorPage.xaml.h
  • UI/Pages/HostSettingsPage.xaml
  • UI/Pages/HostSettingsPage.xaml.cpp
  • UI/Pages/HostSettingsPage.xaml.h
  • UI/Pages/MoonlightSettings.xaml
  • UI/Pages/MoonlightSettings.xaml.cpp
  • UI/Pages/MoonlightSettings.xaml.h
  • UI/Pages/MoonlightWelcome.xaml
  • UI/Pages/MoonlightWelcome.xaml.cpp
  • UI/Pages/MoonlightWelcome.xaml.h
  • UI/Pages/StreamPage.xaml
  • UI/Pages/StreamPage.xaml.cpp
  • UI/Pages/StreamPage.xaml.h
  • UI/Styles/Colors.xaml
  • UI/Styles/Controls.xaml
  • UI/Utilities/EffectsLibrary.cpp
  • UI/Utilities/EffectsLibrary.h
  • UI/Utilities/ImageHelpers.cpp
  • UI/Utilities/ImageHelpers.h
  • UI/Utilities/ToastService.cpp
  • UI/Utilities/ToastService.h
  • UI/Utilities/XamlHelpers.cpp
  • UI/Utilities/XamlHelpers.h
  • Utils.cpp
  • Utils.hpp
  • Utils/FloatBuffer.cpp
  • libgamestream/client.c
  • libgamestream/http.c
  • moonlight-xbox-dx.vcxproj
  • moonlight-xbox-dx.vcxproj.filters
  • pch.h

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@naireet

naireet commented Jul 31, 2026

Copy link
Copy Markdown

Nice to finally see the pull request, going to install your build on my xbox tonight!

@andygrundman

Copy link
Copy Markdown
Collaborator

I haven't looked at any of this yet but I'm ok if we want to do a UI overhaul. My main thing is that the quick menu, stats, logs should stay unchanged. The streaming UX can't have any fancy animations that would risk performance issues. But it should be ok for host and settings pages.

I figured out a way to get the Tracy profiler to run on Xbox so we'll be able to better analyze any performance problems especially on the slower boxes. This is the next thing I'm going to work on. Maybe it will help find some improvements in the logs which is a real performance killer now. Stats is even too much for Xbox One sometimes.

@mpotrykus

Copy link
Copy Markdown
Contributor Author

@andygrundman Understood. I did redo the in-stream menu to look flashier. If it ends up being a blocker, I can remove it if we find it hinders performance.

I threw anything I could reasonably think of into this for the UI and tried to keep away from any of the actual streaming work. I'd say go through whenever you have time and update with a list of changes you'd like and what you want gutted out. In the mean time, I am collecting any user feedback I can.

Take your time, I will update this branch if I ever find bugs. Otherwise, I will just wait until I hear more.

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.

3 participants