Releases: Valkirie/HandheldCompanion
0.28.6.14 - Hotfix
Hotfixes
- Fixed an issue with the input shifting logic on layout manager.
Full Changelog: 0.28.6.13...0.28.6.14
0.28.6.13 - Hotfix
Hotfixes
- Fixed an issue with the input shifting logic on layout manager.
Full Changelog: 0.28.6.12...0.28.6.13
0.28.6.12 - Hotfix
Hotfixes
- Fixed an issue causing a crash on Settings manager on corrupted values.
Full Changelog: 0.28.6.11...0.28.6.12
0.28.6.11 - Hotfix
Hotfixes
- Fixed an issue causing virtual controller combobox value to be randomly incorrect on startup.
- Fixed an issue with Steam Deck HID inputBufferLen.
Full Changelog: 0.28.6.10...0.28.6.11
Build 0.28.6.4
Handheld Companion – Release Notes
0.28.6.4
Highlights
- Performance and startup improvements: Several targeted optimizations reduce startup time and runtime overhead. JIT compilation for loops is now faster on startup, and GC scaling behavior has been tuned to avoid stalls when the app wakes from idle. A handful of hot code paths also received aggressive inlining for better runtime throughput.
- UI and library experience: The Library has received a round of focused improvements: games now load asynchronously so the UI stays responsive, a new All Wide view mode has been added, missing artwork is now surfaced clearly with a dedicated UI element, and hovering a game now shows a quick Play/Stop button. Logo selection is now available in the artwork picker, and navigation debouncing prevents visual noise when moving through pages quickly.
- Navigation and profiles: Gamepad and keyboard navigation has been improved with better control target logic and additional default button assignments. Hotkey settings have been moved to their own dedicated page, which also meaningfully reduces the loading time for that section. The Profiles page received several usability improvements.
What Changed
Performance
- Optimized build output to skip copying unchanged 3D model files.
- Enabled TieredCompilationQuickJitForLoops for faster startup.
- Tuned GarbageCollectionAdaptationMode to prevent GC stalls on app wake.
- Applied AggressiveInlining to several performance-sensitive code paths.
- Miscellaneous performance and stability improvements throughout.
UI/UX
- Added a MissingArtwork UI element for games without artwork.
- Improved Library metadata and artwork refresh logic to preserve existing visuals and fill in missing ones.
- Implemented Logo selection in the artwork/library picker.
- Added All Wide as a new Library view mode.
- Games in the Library now display asynchronously.
- Play/Stop button now appears on mouse hover over library items.
- Migrated Hotkey settings to a dedicated page, reducing Hotkeys page load time.
- Implemented UI navigation debouncing (300ms) to smooth out rapid page transitions.
- Improved gamepad navigation with better control target logic.
- Added missing DefaultButton assignments for keyboard navigation.
- Improved Profiles page behavior.
Fixes
- Fixed a timeout issue in ForegroundCallback() when task.Wait() would expire.
- Fixed QuickTools failing to create and apply profiles with per-game mode enabled.
- Fixed a UI freeze when an SDL controller GameType could not be retrieved.
- Fixed controller passthrough being incorrectly enabled on the default profile.
- Fixed SDL controller glyph logic.
- Fixed a memory leak originating from LibreHardwarePlatform.
- Fixed Hotkey chord listening button staying toggled after gamepad press.
Controller
- Implemented partial vJoy support.
Device
- Fixed IMU axis configuration for GPD Win 5, Win Max 2, and Win Mini.
Library updates
- SDL3 3.4.2
- SDL3-CS 3.4.2
Installer
- gamecontrollerdb.txt is now downloaded automatically during installation.
0.28.6.10 - Performance Improvements and OpenXInput Support
Highlights
- Performance improvements: This update includes a broad round of optimizations aimed at reducing CPU usage and memory footprint in several subsystems, including process and window management, LibreHardware, SDL event waiting, and power management logic.
- OpenXInput implementation: Recent Windows changes broke the previous method we relied on for associating an XInput controller with its UserIndex. HC now implements OpenXInput. This replaces our previous approach for retrieving XInput controller UserIndex through the device path and gives us a much more reliable foundation beyond Xbox 360-based controllers, extending support to Xbox One-based controllers as well.
What Changed
Performance
- Reduced CPU and memory footprint from process and window management.
- Reduced CPU and memory footprint from LibreHardware.
- Reduced CPU footprint from SDL.WaitEventTimeout().
- Reduced CPU footprint in PerformanceManager, with RequestCoreParkingMode now checking current values before reapplying them.
- Reduced overall CPU and memory footprint across the application.
Controller / Input
- Implemented OpenXInput (Xinput1_4.dll) to support Windows 11 KB5086672 update while improving the UserIndex reading logic.
- Implemented ReleaseNumber reading, which may help manage firmware-related HID index differences in the future.
- Improved the overall Inputs manager robustness and implemented per-device, KeyboardChord-based flush intervals.
- Improved the overall Controller manager robustness.
- Fixed an issue causing a race condition with XInput controller IsGone / IsBusy.
- Fixed SDL GetPathFromUserIndex() logic.
UI / UX
- Reworked the Controller Page architecture around a cleaner MVVM structure, improving maintainability and helping make future controller-related UI changes easier to build and manage.
- Improved threading and observable collection management.
- Fixed an issue preventing UI navigation when focus was on a disabled, hidden, or collapsed control.
- Fixed a controller lock race condition that could freeze the UI.
Device
- Legion Go: updated factory default fan values.
- Legion Go: reduced keyboard hook flush interval from 150ms to 10ms.
Library / Dependencies
- PixiEditor.ColorPicker
- Sentry
- WindowsAPICodePack
Full Changelog: 0.24.1.2...0.28.6.10
Build 0.28.4.6
Handheld Companion – Release Notes
0.28.4.6
Hotfixes
- Fixed an issue preventing CPU data from being read due to outdated LibreHardwareMonitor library and recent PawnIO update.
- Fixed an issue with PawnIO implementation due to lack of PCI Mutex.
- Fixed an issue causing TDPOverride values to be set to 0, potentially causing major stability and performance issues.
Build 0.28.4.5
Handheld Companion – Release Notes
0.28.4.5
Highlights
-
WinRing0/RyzenAdj to PawnIO (AMD power path): All AMD power manipulation (TDP, CPU clock frequency, GPU frequency, Curve Optimizer) has been moved off WinRing0/RyzenAdj and onto PawnIO. This should prevent any future Windows Defender warnings and make the whole stack more robust and cooperative with anti-cheat systems going forward.
-
Extra buttons on SDL controllers: We’ve updated the SDL controller database and added support for paddles and miscellaneous buttons on any SDL-supported controller. If your pad exposes extra buttons through SDL, HC can now see and bind them.
Hotfixes
-
0.28.4.3b: Fixed a regression with keyboard based OEM buttons.
-
0.28.4.4: Fixed support for PawnIO version 2.1.0.0.
-
0.28.4.5: Fixed simultaneous support for PawnIO versions 2.0.1.0 and 2.1.0.0.
Power & Dependencies
Please let us know if you notice any regressions or improvements on TDP manipulation (all devices) or Curve Optimizer (AMD specific).
PawnIO-based power path
We’ve replaced the RyzenAdj and WinRing0 dependencies with PawnIO for AMD power manipulation, covering:
-
TDP control
-
CPU clock frequency
-
GPU frequency
-
AMD voltage curve (Curve Optimizer)
This is aimed at eliminating WinRing0-related issues and Defender warnings, and giving us a cleaner, more maintainable power path going forward.
TDP handling improvements
- Improved overall TDP management so requested values are properly (re)applied instead of occasionally "sticking".
Controllers & Input
-
Improved SDL controllers support with an updated the gamecontroller database (12/02/2025) and support for paddles and miscellaneous buttons from generic SDL controllers.
-
Legion Go 2: M1 and Page/Desktop buttons are now properly integrated into the device mapping.
UI/UX & OSD
- On-screen display / RTSS: Added an RTSS frame graph to the on-screen display, giving you a clearer view of frame pacing and performance (thanks to @ltchipotle).
Navigation & interaction
-
You can now use the gamepad left joystick for UI navigation.
-
Miscellaneous tweaks and improvements to the Layout page for a smoother configuration experience.
Settings & window behavior
- New setting: Fullscreen on launch. ALT+ENTER now toggles the main window between windowed and fullscreen states.
- New setting: Show splash-screen at startup if you like the visual cue when HC launches.
QuickTools
- Added an "Exit HC" button to the QuickTools navigation bar to cleanly close Handheld Companion without having to fight against Windows task-tray icon.
Stability & Fixes
- Fixed an issue where Configurable TDP up/down could be set to 0, forcing TDP to an abnormally low value.
- Fixed AMD-specific Curve Optimizer availability checks so the feature is only exposed when supported.
- Fixed AMD integer scaling registry check/override by matching the currently active GPU while also making the integer scaling dropdown selection more robust.
- Fixed an issue preventing some inputs from being captured when the controller polling rate was set to 250 Hz and above.
- Fixed Legion Go 2 M1 button behavior, so the button now works as expected.
- Fixed a crash when failing to open the ONEXPLAYER serial port.
- Fixed a crash on null selectedProfile when navigating to the power profile page.
Library Updates
- SDL3
- LibreHardwareMonitor
- Sentry
- Microsoft.Xaml.Behaviors.Wpf
- System.Drawing.Common
- System.IO.Ports
- System.ServiceProcess.ServiceController
- System.Text.Json
Special thanks to
@ltchipotle for his support on WinRing0 migration
Release Build 0.28.3.3
Handheld Companion – Release Notes
0.28.3.3
Highlights
- UI/UX overhaul (Profiles + Layout): Redesigned pages for simpler navigation and reduced loading times, plus improved controller-first navigation across the app.
- NavigationView improvements: Main window navigation is now horizontal (use L1/R1), and embedded NavigationViews (as seen on the Layout page) now support L2/R2 navigation.
- Update interval (advanced latency tuning): New setting for advanced users to manipulate the controller update rate. Default is now 125 Hz (8 ms) instead of 100 Hz (10 ms), with options up to 1000 Hz (1 ms).
- Controller order management (better out-of-the-box experience): Controller order adjustment is now manual by default, with clear UI feedback (toast + icon) if your virtual controller is not on slot 1—helping avoid “why is my controller unresponsive?” situations.
UI/UX improvements
- Profiles page: Full UI refresh aimed at faster load and simpler day-to-day navigation.
- Layout page: Revamped layout experience and navigation, including easier access to advanced action configuration.
- Controller management UI polish: Controller management should behave the same as before, but now includes clearer interface text and notifications (updated across all supported languages), and a more understandable user flow around controller order and slot state.
- Quality-of-life: Added a library shortcut to edit controller layout when pressing the X button.
NavigationView controls:
- Main window: L1/R1 navigation (horizontal logic).
- Embedded views (Layout page): L2/R2 navigation.
Update interval (advanced latency tuning)
We’re adding a new setting for advanced users who want to manipulate the controller update rate. The new default is 125 Hz (8 ms), replacing the previous 100 Hz (10 ms).
Available options:
- 125 Hz ≈ 8.00 ms: very common for Xbox/XInput-class wireless + many older controllers
- 250 Hz ≈ 4.00 ms: very common for PlayStation over USB, and many wired third-party pads
- 500 Hz ≈ 2.00 ms: less common; some wireless/dongle implementations
- 1000 Hz ≈ 1.00 ms: common on competitive/PC-focused wired pads; some dongles
Higher rates may slightly increase CPU usage, but the goal is to give latency-focused users a straightforward, supported way to tune responsiveness.
Stability & Fixes
- Fixed a crash when calling ControllerManager.GetDefault().
- Fixed a crash when cloning an unsynced Layout (Clone()).
- Fixed SensorsManager suspend/resume handling across sleep.
- Fixed a race-condition crash in TimerManager.
- GPD Win 5: Added OEM buttons mapping support.
Library updates
- SDL: updated gamecontrollerdb and SDL 3.3.6.
Special thanks to
- @P3P0 (new layout functions + layout UI revamp)
- @mistakeplays (support to validate and land proper GPD Win 5 mapping)
Full Changelog: 0.28.3.1...0.28.3.3
Release Build 0.28.3.1
Handheld Companion – Release Notes
0.28.3.1
Highlights
- Voltage control (AMD & Intel): Implemented proper voltage control for both AMD and Intel devices.
- AMD: Works on all 4000-series SKUs and below. From the 5000-series onward, voltage control only works on Ryzen 9 or HX SKUs.
- Intel: Works as expected.
- Layout Editor upgrades: More reliable toggles and new automation options. Toggle state is now shared and matches the real status, action bindings can be delayed, and shift actions now support triggers (by @pepordev).
- Improved sleep behavior: Added Enhanced sleep to optimize modern sleep power policies, plus Go back to sleep to automatically send the device back to sleep when it wakes for reasons other than the power button (ported from SuspendedNTime by @BassemMohsen).
- Improved FSE support: HC main window and quick tools window will now properly be recognized and manipulated by FSE task manager.
Device & Controller Support
SuiPlay
- 0X1: Implemented device support for SuiPlay 0X1 (MYSTEN LABS, INC.).
GPD
- Win 5: Updated device max TDP to 85W and fixed gyrometer support.
- Win Mini (8840U, HX370 models): Fixed gyrometer support.
- Win Max (HX370): Fixed gyrometer support.
- AYANEO (all devices): Improved LED control (by @GopherTheCoder).
UI & Experience
Hotkeys
- New command: Controller status (Connected / Disconnected).
- New command: PowerShellCommands (execute multiline script content).
- UI: Ask before deleting hotkeys (confirmation prompt).
Layout Editor
- New layout action: Absolute mouse position.
- Added new action modifier key: LWin.
- Added support for shift combinations (by @pepordev).
Power & Process Handling
EnhancedSleep & ReSleep
- Ported Enhanced sleep, which optimizes modern sleep power policies.
- Ported Go back to sleep, which puts the device back to sleep when wake source is not the power button.
Stability & Fixes
- Fixed: AMD Adrenalin library (ADLX) NET10 support.
- Fixed: An edge case where profile's actions could end up with Turbo and Toggle enabled simultaneously.
- Fixed: Layout editor input duration slider not displayed.
- Fixed: Layout editor shift logic.
- Fixed: A rare crash when editing a layout.
- Fixed: Charge bypass logic for AYANEO Legacy and Modern device families.
- Fixed: AYANEO Air Plus EC logic.
- Fixed: An issue where the plugged controller wouldn't behave properly after a power cycling.
- Fixed: A rare crash on HotkeyViewModel where Hotkey command buttonflags would be null.
- Fixed: Creating a profile for explorer.exe will no longer try and get an artwork and proper name for it.
Library updates
- SDL3
- LibreHardwareMonitor
- RAMSPDToolkit-NDD
Special thanks to
- @pepordev (shared toggle state, delayed actions, shift triggers)
- @GopherTheCoder (AYANEO LED control fix)
- @BassemMohsen (EnhancedSleep / ReSleep port)