Skip to content

Change battery overlay widget to better logic and display#1306

Merged
Valkirie merged 14 commits intoValkirie:mainfrom
mops1k:feature/better-battery-overlay
Oct 18, 2025
Merged

Change battery overlay widget to better logic and display#1306
Valkirie merged 14 commits intoValkirie:mainfrom
mops1k:feature/better-battery-overlay

Conversation

@mops1k
Copy link
Contributor

@mops1k mops1k commented Oct 11, 2025

In this case:

  • Do not show time if battery charging
  • Battery left time has better format in hours and minutes (looks like: 1h 24min)

Summary by CodeRabbit

  • New Features

    • Battery widget shows estimated time remaining as hours and minutes when available and not charging.
    • Overlay value formatting now supports an "h" (hours) unit.
  • Bug Fixes

    • More reliable overlay initialization and event wiring to reduce missing or delayed displays.
    • Restored consistent handling of display-level settings (order, time/fps/cpu/ram/gpu/vram/battery).
    • Prevented empty/stale overlays by resetting content before redraw.
  • Refactor

    • Streamlined initialization sequencing and event wiring for greater stability.

mops1k added 10 commits August 7, 2025 21:41
Refactor strategies (use widgets.
…re/better-battery-overlay

# Conflicts:
#	HandheldCompanion/Managers/OSDManager.cs
#	HandheldCompanion/Managers/Overlay/OverlayColors.cs
#	HandheldCompanion/Managers/Overlay/Strategy/CustomStrategy.cs
#	HandheldCompanion/Managers/Overlay/Strategy/DisabledStrategy.cs
#	HandheldCompanion/Managers/Overlay/Strategy/ExtendedStrategy.cs
#	HandheldCompanion/Managers/Overlay/Strategy/ExternalStrategy.cs
#	HandheldCompanion/Managers/Overlay/Strategy/FullStrategy.cs
#	HandheldCompanion/Managers/Overlay/Strategy/MinimalStrategy.cs
#	HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs
#	HandheldCompanion/Managers/Overlay/Widget/CpuWidget.cs
#	HandheldCompanion/Managers/Overlay/Widget/FpsWidget.cs
#	HandheldCompanion/Managers/Overlay/Widget/GpuWidget.cs
#	HandheldCompanion/Managers/Overlay/Widget/RamWidget.cs
#	HandheldCompanion/Managers/Overlay/Widget/TimeWidget.cs
#	HandheldCompanion/Managers/Overlay/Widget/VramWidget.cs
#	HandheldCompanion/Managers/Overlay/WidgetFactory.cs
#	HandheldCompanion/Managers/OverlayManager.cs
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 11, 2025

Walkthrough

OSDManager startup flow restructured: platform init now triggers QueryPlatforms which wires RTSS events and handles any existing AppEntry; Settings wiring expanded to register OnScreenDisplay* handlers; Draw content reinitialized. BatteryWidget caches battery time-left in minutes, detects charging via SystemInformation.PowerStatus, and displays hours/minutes only when not charging.

Changes

Cohort / File(s) Summary
OSD init, RTSS & settings wiring
HandheldCompanion/Managers/OSDManager.cs
Adjusted using directives and formatting; Start defers to a PlatformManager_Initialized handler that calls QueryPlatforms; QueryPlatforms now subscribes RTSS Hooked/Unhooked and processes any existing AppEntry; added PlatformManager_Initialized method; SettingsManager_Initialized now calls QuerySettings which (re)registers OnScreenDisplay* handlers (Order, TimeLevel, FPSLevel, CPULevel, RAMLevel, GPULevel, VRAMLevel, BATTLevel); Content reinitialized before Draw assembly; minor brace/structure refinements.
Battery time, caching & charging detection
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs
Adds cached TimeLeftInMinutes accessor and helpers TimeBatteryHours/TimeBatteryMinutes; adds IsBatteryCharging() using SystemInformation.PowerStatus.PowerLineStatus; Build changes (explicit short _level, early exit default case); removes direct TimeSpan display and only shows hours/minutes when time available and device not charging; introduces new private members to store time-left and computed values.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App
  participant OSDManager
  participant SettingsManager
  participant PlatformManager
  participant RTSS

  App->>OSDManager: Start()
  OSDManager->>SettingsManager: Subscribe Initialized / SettingValueChanged
  alt PlatformManager already initialized
    OSDManager->>OSDManager: QueryPlatforms()
  else
    OSDManager->>PlatformManager: Subscribe Initialized
  end

  PlatformManager-->>OSDManager: Initialized
  OSDManager->>OSDManager: QueryPlatforms()
  note over OSDManager: Wire RTSS Hooked/Unhooked events\nProcess existing AppEntry if present

  rect rgba(200,230,255,0.4)
    OSDManager->>RTSS: Subscribe Hooked/Unhooked
    RTSS-->>OSDManager: Hooked / Unhooked
  end

  SettingsManager-->>OSDManager: Initialized
  OSDManager->>OSDManager: Register OnScreenDisplay* handlers
Loading
sequenceDiagram
  autonumber
  participant UI
  participant BatteryWidget
  participant Platform as PlatformManager

  UI->>BatteryWidget: Build(level)
  BatteryWidget->>Platform: Query LibreHardware time remaining (cached)
  BatteryWidget->>BatteryWidget: Cache TimeLeftInMinutes
  BatteryWidget->>BatteryWidget: IsBatteryCharging (SystemInformation.PowerStatus)
  alt Not charging and time available
    BatteryWidget->>BatteryWidget: Compute hours/minutes
    BatteryWidget-->>UI: Render percent + hh:mm (per display level)
  else
    BatteryWidget-->>UI: Render percent only
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I twitch my whiskers at evented streams,
Platforms queue up, RTSS lights the beams.
If power's plugged in, I'll quiet the time —
Else hours and minutes softly chime.
Hop, overlay — a rabbit's tidy rhyme. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "Change battery overlay widget to better logic and display" directly relates to the primary changes in this changeset. The main modifications are in BatteryWidget.cs, which implements improved logic by skipping time display when the battery is charging and enhances the display format by showing remaining time as hours and minutes (e.g., "1h 24min"). While there are also supporting changes in OSDManager.cs, these are infrastructure updates that enable the new battery widget functionality, such as adding the "h" unit handling for formatting. The title is clear, specific, and accurately captures the user-facing improvement that is the focus of this pull request.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad5ac87 and 4bc7d4c.

📒 Files selected for processing (2)
  • HandheldCompanion/Managers/OSDManager.cs (5 hunks)
  • HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (3)
HandheldCompanion/Managers/PlatformManager.cs (1)
  • PlatformManager (11-119)
HandheldCompanion/Platforms/Misc/LibreHardware.cs (3)
  • GetBatteryTimeSpan (399-399)
  • GetBatteryLevel (397-397)
  • GetBatteryPower (398-398)
HandheldCompanion/Managers/OSDManager.cs (7)
  • OverlayEntry (383-407)
  • OverlayEntry (387-393)
  • OverlayEntry (395-398)
  • OSDManager (12-336)
  • OSDManager (45-49)
  • AddElementIfNotNull (235-239)
  • AddElementIfNotNull (241-245)
HandheldCompanion/Managers/OSDManager.cs (4)
HandheldCompanion/Managers/ManagerFactory.cs (2)
  • ManagerFactory (8-72)
  • ManagerFactory (39-59)
HandheldCompanion/Managers/PlatformManager.cs (1)
  • PlatformManager (11-119)
HandheldCompanion/Platforms/Misc/RTSS.cs (1)
  • AppEntry (171-174)
HandheldCompanion/Managers/SettingsManager.cs (1)
  • GetString (221-224)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and Release

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1)

50-64: Time calculations are correct.

The hour/minute extraction logic is now correct (modulo operation properly preserves minutes). However, see the comment on lines 28-34 regarding the null handling issue.

🧹 Nitpick comments (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1)

37-48: LGTM!

The charging detection correctly handles all charging states (6, 7, 8, 9) and uses proper disposal.

The cast on Line 42 is redundant. You can simplify:

-foreach (var o in searcher.Get())
-{
-    var result = (ManagementObject)o;
+foreach (ManagementObject result in searcher.Get())
+{
     if (result["BatteryStatus"] is ushort status)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bc7d4c and 20dfdfb.

📒 Files selected for processing (1)
  • HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (3)
HandheldCompanion/Managers/PlatformManager.cs (1)
  • PlatformManager (11-119)
HandheldCompanion/Platforms/Misc/LibreHardware.cs (3)
  • GetBatteryTimeSpan (399-399)
  • GetBatteryLevel (397-397)
  • GetBatteryPower (398-398)
HandheldCompanion/Managers/OSDManager.cs (7)
  • OverlayEntry (383-407)
  • OverlayEntry (387-393)
  • OverlayEntry (395-398)
  • OSDManager (12-336)
  • OSDManager (45-49)
  • AddElementIfNotNull (235-239)
  • AddElementIfNotNull (241-245)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and Release
🔇 Additional comments (2)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (2)

1-1: LGTM!

The import is required for the WMI-based charging detection.


7-8: LGTM!

The property correctly retrieves battery time data from LibreHardware.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20dfdfb and 6655d98.

📒 Files selected for processing (1)
  • HandheldCompanion/Managers/OSDManager.cs (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
HandheldCompanion/Managers/OSDManager.cs (4)
HandheldCompanion/Managers/ManagerFactory.cs (2)
  • ManagerFactory (8-72)
  • ManagerFactory (39-59)
HandheldCompanion/Managers/PlatformManager.cs (1)
  • PlatformManager (11-119)
HandheldCompanion/Platforms/Misc/RTSS.cs (1)
  • AppEntry (171-174)
HandheldCompanion/Managers/SettingsManager.cs (1)
  • GetString (221-224)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and Release

Comment on lines +117 to 124
SettingsManager_SettingValueChanged("OnScreenDisplayOrder", ManagerFactory.settingsManager.GetString("OnScreenDisplayOrder"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayTimeLevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayTimeLevel"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayFPSLevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayFPSLevel"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayCPULevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayCPULevel"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayRAMLevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayRAMLevel"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayGPULevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayGPULevel"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayVRAMLevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayVRAMLevel"), false);
SettingsManager_SettingValueChanged("OnScreenDisplayBATTLevel", ManagerFactory.settingsManager.GetString("OnScreenDisplayBATTLevel"), false);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle unset overlay level settings without crashing

GetString returns an empty string when a setting is missing. Calling Convert.ToInt16 on that empty string throws a FormatException, so the very first run (or any run with a missing key) will break out of QuerySettings. Please guard the parsing and fall back to 0 (or whatever default you expect) when the setting is blank.

             case "OnScreenDisplayTimeLevel":
-                OverlayTimeLevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayTimeLevel = level;
+                    break;
+                }
             case "OnScreenDisplayFPSLevel":
-                OverlayFPSLevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayFPSLevel = level;
+                    break;
+                }
             case "OnScreenDisplayCPULevel":
-                OverlayCPULevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayCPULevel = level;
+                    break;
+                }
             case "OnScreenDisplayRAMLevel":
-                OverlayRAMLevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayRAMLevel = level;
+                    break;
+                }
             case "OnScreenDisplayGPULevel":
-                OverlayGPULevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayGPULevel = level;
+                    break;
+                }
             case "OnScreenDisplayVRAMLevel":
-                OverlayVRAMLevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayVRAMLevel = level;
+                    break;
+                }
             case "OnScreenDisplayBATTLevel":
-                OverlayBATTLevel = Convert.ToInt16(value);
-                break;
+                {
+                    if (!short.TryParse(Convert.ToString(value), out short level))
+                        level = 0;
+                    OverlayBATTLevel = level;
+                    break;
+                }

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6655d98 and 2d96fe2.

📒 Files selected for processing (1)
  • HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (3)
HandheldCompanion/Managers/PlatformManager.cs (1)
  • PlatformManager (11-119)
HandheldCompanion/Platforms/Misc/LibreHardware.cs (3)
  • GetBatteryTimeSpan (399-399)
  • GetBatteryLevel (397-397)
  • GetBatteryPower (398-398)
HandheldCompanion/Managers/OSDManager.cs (7)
  • OverlayEntry (384-408)
  • OverlayEntry (388-394)
  • OverlayEntry (396-399)
  • OSDManager (12-336)
  • OSDManager (45-49)
  • AddElementIfNotNull (235-239)
  • AddElementIfNotNull (241-245)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and Release
🔇 Additional comments (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1)

42-53: LGTM! Charging detection correctly implemented.

The WMI query properly checks BatteryStatus values 6, 7, 8, and 9, which correspond to the documented charging states in the Win32_Battery class. The using statement ensures proper disposal of the searcher, and returning false when no battery is found is appropriate fallback behavior.

Comment on lines +7 to +8
private float? TimeLeftInMinutes => PlatformManager.LibreHardware.GetBatteryTimeSpan();

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Cache TimeLeftInMinutes to avoid repeated hardware queries.

The TimeLeftInMinutes property invokes GetBatteryTimeSpan() on every access. Within a single Build() call, this property is read at line 33, then again inside TimeBatteryHours() (line 57), and once more in TimeBatteryMinutes() (line 65), resulting in three separate calls to the underlying hardware query.

Refactor to cache the value in a local variable:

 public void Build(OverlayEntry entry, short? level = null)
 {
     var _level = level ?? OSDManager.OverlayBATTLevel;
     if (_level == null)
     {
         return;
     }

     switch (_level)
     {
         case WidgetLevel.FULL:
             OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryLevel(), "%");
             OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryPower(), "W");
             break;
         case WidgetLevel.MINIMAL:
             OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryLevel(), "%");
             break;
     }

     if (IsBatteryCharging())
     {
         return;
     }

-    if (!TimeLeftInMinutes.HasValue)
+    var timeLeft = TimeLeftInMinutes;
+    if (!timeLeft.HasValue)
     {
         return;
     }

-    OSDManager.AddElementIfNotNull(entry, TimeBatteryHours(), "h");
-    OSDManager.AddElementIfNotNull(entry, TimeBatteryMinutes(), "min");
+    OSDManager.AddElementIfNotNull(entry, TimeBatteryHours(timeLeft.Value), "h");
+    OSDManager.AddElementIfNotNull(entry, TimeBatteryMinutes(timeLeft.Value), "min");
 }

-private int TimeBatteryHours()
+private int TimeBatteryHours(float minutes)
 {
-    if (TimeLeftInMinutes is not float minutes)
-        return 0;
-
     return (int)(minutes / 60f);
 }

-private int TimeBatteryMinutes()
+private int TimeBatteryMinutes(float minutes)
 {
-    if (TimeLeftInMinutes is not float minutes)
-        return 0;
-
     return (int)(minutes % 60f);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private float? TimeLeftInMinutes => PlatformManager.LibreHardware.GetBatteryTimeSpan();
public void Build(OverlayEntry entry, short? level = null)
{
var _level = level ?? OSDManager.OverlayBATTLevel;
if (_level == null)
{
return;
}
switch (_level)
{
case WidgetLevel.FULL:
OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryLevel(), "%");
OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryPower(), "W");
break;
case WidgetLevel.MINIMAL:
OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryLevel(), "%");
break;
}
if (IsBatteryCharging())
{
return;
}
var timeLeft = TimeLeftInMinutes;
if (!timeLeft.HasValue)
{
return;
}
OSDManager.AddElementIfNotNull(entry, TimeBatteryHours(timeLeft.Value), "h");
OSDManager.AddElementIfNotNull(entry, TimeBatteryMinutes(timeLeft.Value), "min");
}
private int TimeBatteryHours(float minutes)
{
return (int)(minutes / 60f);
}
private int TimeBatteryMinutes(float minutes)
{
return (int)(minutes % 60f);
}
🤖 Prompt for AI Agents
In HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs around lines 7-8
(and usages at lines 33, 57, 65), the TimeLeftInMinutes property calls
PlatformManager.LibreHardware.GetBatteryTimeSpan() on every access causing three
hardware queries during a single Build(); refactor by calling
GetBatteryTimeSpan() once inside Build(), store the result in a local variable
(e.g., timeLeftInMinutes), and replace reads of the property within that Build()
invocation with the local variable; if necessary update TimeBatteryHours() and
TimeBatteryMinutes() to accept the nullable float as a parameter (or overload
them) so they use the cached value instead of re-querying the hardware.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1)

8-9: Cache TimeLeftInMinutes to eliminate redundant hardware queries.

The TimeLeftInMinutes property triggers a hardware query via GetBatteryTimeSpan() on every access. Within a single Build() call, this property is accessed at line 29, line 40 (inside TimeBatteryHours()), and line 48 (inside TimeBatteryMinutes()), resulting in three separate hardware queries.

Refactor to cache the value in a local variable and pass it to the helper methods:

 public void Build(OverlayEntry entry, short? level = null)
 {
     short _level = level ?? OSDManager.OverlayBATTLevel;
     switch (_level)
     {
         case WidgetLevel.FULL:
             OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryLevel(), "%");
             OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryPower(), "W");
             break;
         case WidgetLevel.MINIMAL:
             OSDManager.AddElementIfNotNull(entry, PlatformManager.LibreHardware.GetBatteryLevel(), "%");
             break;
         default:
             return;
     }

     if (IsBatteryCharging())
         return;

-    if (!TimeLeftInMinutes.HasValue)
+    var timeLeft = TimeLeftInMinutes;
+    if (!timeLeft.HasValue)
         return;

-    OSDManager.AddElementIfNotNull(entry, TimeBatteryHours(), "h");
-    OSDManager.AddElementIfNotNull(entry, TimeBatteryMinutes(), "min");
+    OSDManager.AddElementIfNotNull(entry, TimeBatteryHours(timeLeft.Value), "h");
+    OSDManager.AddElementIfNotNull(entry, TimeBatteryMinutes(timeLeft.Value), "min");
 }

-private int TimeBatteryHours()
+private int TimeBatteryHours(float minutes)
 {
-    if (TimeLeftInMinutes is not float minutes)
-        return 0;
-
     return (int)(minutes / 60f);
 }

-private int TimeBatteryMinutes()
+private int TimeBatteryMinutes(float minutes)
 {
-    if (TimeLeftInMinutes is not float minutes)
-        return 0;
-
     return (int)(minutes % 60f);
 }
🧹 Nitpick comments (2)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (2)

1-1: Remove unused import.

System.Management is no longer used after the charging detection was refactored to use SystemInformation.PowerStatus instead of WMI queries.

Apply this diff to remove the unused import:

-using System.Management;
 using System.Windows.Forms;

36-36: Method name doesn't match its behavior.

IsBatteryCharging() checks PowerLineStatus.Online, which indicates the device is plugged into AC power, not whether the battery is actively charging. When the battery is full and plugged in, this returns true even though the battery isn't charging. Consider renaming to IsPluggedIn() or IsOnACPower() for clarity.

Apply this diff to clarify the method name:

-private static bool IsBatteryCharging() => SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
+private static bool IsPluggedIn() => SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;

And update the call site:

-if (IsBatteryCharging())
+if (IsPluggedIn())
     return;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d96fe2 and c79566f.

📒 Files selected for processing (1)
  • HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (3)
HandheldCompanion/Managers/PlatformManager.cs (1)
  • PlatformManager (11-119)
HandheldCompanion/Platforms/Misc/LibreHardware.cs (3)
  • GetBatteryTimeSpan (399-399)
  • GetBatteryLevel (397-397)
  • GetBatteryPower (398-398)
HandheldCompanion/Managers/OSDManager.cs (7)
  • OverlayEntry (384-408)
  • OverlayEntry (388-394)
  • OverlayEntry (396-399)
  • OSDManager (12-336)
  • OSDManager (45-49)
  • AddElementIfNotNull (235-239)
  • AddElementIfNotNull (241-245)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and Release
🔇 Additional comments (3)
HandheldCompanion/Managers/Overlay/Widget/BatteryWidget.cs (3)

22-23: Good defensive practice.

Adding a default case prevents unknown widget level values from falling through to the battery time display logic.


26-30: LGTM!

The early returns correctly handle the cases where battery time shouldn't be displayed: when the device is plugged in and when time data is unavailable.


38-52: LGTM!

The hour and minute calculations are correct. The null checks using pattern matching are technically redundant given the guard at line 29, but they make these methods more defensive and reusable.

@Valkirie Valkirie merged commit 283187b into Valkirie:main Oct 18, 2025
1 of 2 checks passed
@Valkirie
Copy link
Owner

Thanks! Merged in EA as well.

Valkirie added a commit that referenced this pull request Oct 27, 2025
Valkirie added a commit that referenced this pull request Dec 8, 2025
* Refactor Overlay rendering logic to strategy design pattern

* Fix ai comments

* Add widget system with factory

* Fix some AI comments

* Add level selection for overlay widgets.
Refactor strategies (use widgets.

* Fix level for cpu widget in full overlay strategy

* - change battery left to hours and minutes format

* - add format for hours

* - fix after merge from `main`

* - little refactoring

* - add hours format

* - add return if null time left

* good to go

---------

Co-authored-by: Lesueur Benjamin <benjamin.lesueur@live.com>
(cherry picked from commit 283187b)
Valkirie added a commit that referenced this pull request Dec 8, 2025
* code cleanup

* Fix UI navigation

* build 0.26.1.0

* Misc PR (#455)

New Features

Added support for Zotac Gaming Zone devices, including a new VRAM configuration option in device settings.
Introduced controller swap functionality for Lenovo Legion Go devices, with corresponding UI controls and localization.
Added a property to indicate manufacturer platform support in device settings.
Improvements

Refined device settings UI to display panels specific to MSI Claw, Lenovo Legion Go, and Zotac Gaming Zone.
Enhanced splash screen with an animated progress indicator.
Updated controller input handling for improved consistency and mapping support.
Localization

Added new resource strings and placeholders for controller swap and VRAM settings in multiple languages.
Bug Fixes

Improved handling of device-specific settings and toggles to ensure correct UI behavior and device interaction.

* Add missing setting: LegionControllerSwap

* build 0.26.2.0

* Fixed an issue with UIGamepad focus logic when HC is starting

* Improve LibraryPage tiles layout

* misc cleanup

* Improve executable startup

- Implemented DelegateCommand with parameter(s)
- Allow user to pick Run/RunAs to start executable from profile page

* Improve IManager AddStatus and RemoveStatus

* misc

* Don't create process if you can't listen for events

* Async inputs updated (#456)

* Improve ControllerManagement event logic

I was dumb and thought RaisingAnEvent?.Invoke() would simultaneously raise event across all listeners and have their tasks to run in parallel. I was wrong...

* better

* Improve LibraryManager (#457)

- Support both IGDB and SteamGrid researches in parallel.
- Todo: Add checkboxes

* Async layout updated (#458)

* Implement async LayoutUpdated event

* Implement EventHelper.RaiseAsync()

* misc improvement to controller management

* Implement GameLib (#460)

* Make PlatformManager async and start implementing GameLib

* prevent useless power profile updates

* misc

* misc

* implement more platforms

* more work

* Add LaunchString support over StartProcessCommand

* more work

* Add profile page field: LaunchString

* improve ProfileViewModel navigation

* misc

* filter a few executables

* Update SDL3 to 3.2.20

https://github.com/libsdl-org/SDL/releases/tag/release-3.2.20

* Update LibreHardwareMonitorLib

* Update gamecontrollerdb.txt

* Implement Quick Profiles button (Edit layout)

* Implement Quicktools position: BottomCenter

* UI work

* misc

* Improve Scan Library UI with DropDownButton

* Fix process detection on QuickApplicationPage

* Improve overall QuickProfiles UI experience

Add two new buttons: Button_OpenProfilePage, Button_OpenProfileLayout

* Misc UI improvements

* Fix QT Margins

* Improve FanProfile logic

* More work on fan (both UI and backoffice)

* Improve page loading logic

* Improve Quicktools Width under several scenarios

* Misc

* Add QT animation logic

* Fix Icons

* Add FanTable restore logic to LegionGo

* Restore PL1/PL2 logic and fix values for Lunar-Lake based devices

* Update PowerProfileManager.cs

* Proper Intel MicroArchitecture detection

* hacky fix for MSI Claw gamepad

* build 0.27.0.0

* Fix: Default Power profile reset when device restart

* Fix PL1/PL2 errors

- PL2 shouldn't be inferior to PL1
- PL2 should be equal or PL1+1 (Lunar Lake)

* Fix: Open layout page in Quicktool not going to the game page (go to default profile page)

* Fix: Blank spaces on QuickHome hotkeys

* more work

* Fix: QuickToolsSlideAnimation

* more work

* prevent critical processes from being listed on Quick applications

* Filter games related executables with error in filename

* Improve MSI Claw Fan Mapping

* build 0.27.0.1

* Update README.md

* Misc UI Fix

* Fix Claw A2VM Performance PL2

* Improve profile management (#461)

* Improve profile management

* Fix: Crash on corrupted user.config

* Improve MSI Claw controller robustness

* Cleanup

* delete previous profile file on profile name changes

* build 0.27.0.2

* You can now pass initial directory to CommonFileDialog()

* Fix race condition

* Filter library apps on: uninst

* improve profile management (store path)

* Fix Quicktools style

* Add new QT settings: Apply noise to window's background

* build 0.27.0.3

* Refactor Overlay rendering logic to strategy design pattern (#1281)

* Refactor Overlay rendering logic to strategy design pattern

* Fix ai comments

* Add widget system with factory

* Fix some AI comments

* Add level selection for overlay widgets.
Refactor strategies (use widgets.

* Fix level for cpu widget in full overlay strategy

* cleanup

* Fixed: crash when managing corrupted profiles

* Improve profile sanitizer

* Fix RTSS status check

* Fixed: Incorrect IsMapped boolean check on ControllerManager Tick()

* build 0.27.0.4

* Improve process detection within StartProcessCommand

* Dramatically cuts GC pressure and CPU (#462)

* Dramatically cuts GC pressure and CPU

* Fix TriggerActions shiftSlot logic

* build 0.27.0.5

* Misc fix

* Add missing dynamic lighting capacities to MSI Claw

* build 0.27.0.6

* Implement EADesktop support through GameLib (#463)

* Implement EADesktop support through GameLib

Using custom repo: https://github.com/Valkirie/GameLib.NET/tree/EAapp

* Fix EADesktop logo missing from LibraryPage

* Ambilight: Reduce CPU consumption (#464)

* Reduce CPU usage, phase 1

* misc tweaks

* build 0.27.0.7

* Extended expected delay before profile related executable is ready

* Improve library manager SteamGrid lookup with cleaned string

* Optimizing IActions related functions (#465)

* Optimizing IActions related functions

* Pass delta to IActions to improve timed actions accuracy

* seal a few classes

* Use [MethodImpl(MethodImplOptions.AggressiveInlining)] on States

* Small State tweaks

* further improve States optimization

* build 0.27.0.8

* Reduce MSI Claw 1 rumble logic CPU usage

* Improved: Set device OEM buttons as Inherit on new profiles

* Improved: UI Navigation

- Quicktools will remember the last focused item from each page
- Quicktools navigation won't focus AppBarButton first
- Quicktools L1/R1 will automatically enter the page
- MainWindow page flow is more natural when pressing A/B

* Implement controller page related support section

* Fixed: version checking from profiles manager on older profile

* Fixed: GameBarCommands and DesktopCommands

* Improved: ROG Ally PerformanceMode and AsusFan.Mid

* Hacky: Fixed: Phantom controller filtering

* build 0.27.0.9

* Add Inherits for AllButtons and AllAxisLayoutFlags

* Update Quicktools Home and Applications UI

* Force (re)apply Quicktools transparency when changing postion

* Update libs

* oups

* Fixed: Issue when discovering non-Steam games with multiple executables

* Fixed: SDL XInput controller ignored

* Fixed: Issues when trying to trigger hotkeys

* Fixed: UI Issue when navigating into a page without IsEnabled controls

* Improved: QuickHome, QuickApplications UI

* build 0.27.0.10

* States fixes

* Improved: Removed hacky controller manager await in benefits of more robust device manager arrival logic

* Improved: Device management has new queuing logic

* Improved: Quicktools L1/R1 will now circle within menu items

* Filter SDL Events

* Fixed: Restore default fan profile when fan mode is set to Hardware

* Migrate some platform logic to PlatformManager

We should move the PlatformToProfile logic to LibraryManager or PlatformManager

* Fix Claw FanSpeed array

* Implemented: new commands ButtonCommands replacing GuideCommands

* Improve Action Type UI experience

* Fixed: Button to TriggerActions

* Improved: ButtonMapping and AxisMapping migrated to SettingsExpander and SettingsCard

* Improved: GyroMapping and TriggerMapping migrated to SettingsExpander and SettingsCard

* Improved: MouseAction Acceleration is now relying on action delta (ms) to compute velocity memory

* Misc UI tweaks

* build 0.27.0.11

* Misc UI improvements

* Fixed: OEM buttons will now properly inherit default behavior

* misc

* misc

* Fixed: Input/Hotkey injection on dummy controllers

* Revert: Improved: Device management has new queuing logic

* Fixed: Rog Ally Xbox Adaptive Controller support

* Improved: Allow users to edit default power profiles

* Edit a few default settings

* build 0.27.0.12

* Improve overall fan management and ROG Ally TDP (#466)

* (Tentative) Fix TDP/Fan issues

* Misc: migrate powerProfile management to IDevice

* update lib

* Improved: Controller management

* Implemented: Per-device hotkeys (#467)

* Improved: Controller management

* Improved: Per-device hotkeys

* build 0.27.0.13

* Fixed: Profile update when resolution or refresh rate is changed

* Misc (#468)

* Tentative fix buttons RGB control

* Fixed: Hotkey deserialization with old ButtonFlags

* code cleanup

* Fixed: missing library: YamlDotNet

* Fixed: hotkey duplication

* Updated LibreHardwareMonitorLib

* Fixed: Zotac Gaming Zone VRAM control

* Fixed: LegionR/LegionL inverted buttons on Legion Go S

* build 0.27.0.14

* Improve session and device management (#469)

* Improved: HC won't wait until session is ready anymore, except for keyboard input management

* Fixed: Device management asynchronous refresh

* Fixed: Device management asynchronous refresh

* oups

* Revert "Fixed: Profile update when resolution or refresh rate is changed"

This reverts commit 0fa4512.

* only update if necessary

* Update SDL3.dll

* Device support: Add ONEXPLAYER X1 AMD (weird ProductName: ONEXPLAYER X1z)

* Improved: Installation script to add WinRing0x64.sys and HandheldCompanion.sys to defender exclusion list

* build 0.28.0.0

* Update libraries

* Force refresh platform catalog when scanning

* Update LibreHardwareMonitorLib

* RyzenAdj 0.18.0

- Update for ryzen_smu 0.1.7
- Support: Strix Point
- Support: Dragon Range
- Support: Fire Range
- Support: HX370 (Pro)
- Support: Krackan Point

* Fixed: UI not rendering after GPU acceleration is toggled on/off

not perfect..

* DClawController to use GenericController instead of raw HidDevice

* build 0.28.0.1

* Reduce CPU usage (#470)

* Reduce cpu usage on DInputController

* Reduce CPU usage from HidLibrary

* Reduce CPU usage a pressure on ThreadPool with RaiseInputsUpdatedAsync

* Reduce CPU usage from RadioMonitor

* Update OverlayModel.xaml

* build 0.28.0.2

* Update Resources.fr-FR.resx

Traduction par: Moi952

* Improved: UI freeze workaround

* build 0.28.0.3

* Update libs

* Improve controller management

- Properly unhide (with power cycling) if HIDuncloakonclose is set
- Wait until any rumble is complete before power cycling

* ForceRecompose windows on system resume

* Add PawnIO support for LibreHardware 0.9.5

- Fixes CPU power/temperature reading

* build 0.28.0.4

* Fixed: Keyboard chord hotkey trigger on SDL-based controllers

* Improved: CPU usage on LibreHardwareLibrary

* Fixed: Setting a profile favorite subprofile

* Improved: ProfilesPage shows saved windows settings alongside live

* Revert "Fixed: Keyboard chord hotkey trigger on SDL-based controllers"

This reverts commit d0a9483.

* Improved: SDL controllers will use Tick() logic rather than inputs pumping

* Fixed: MainWindow visibility on Task View when minimized

* Updated: LibreHardwareMonitorLib

* build 0.28.0.5

* Misc

* Improved: Window State/Visibility logic

* Misc

* Improved: UIGamepad navigation with HyperlinkButton

* Implemented: New controller setting: HIDuncloakondisconnect

* Fixed: MSI Claw 10F BIOS support

* Resolve startup crash and refactor joystick input (#472)

* fix(app): Crash caused by Logger not being loaded in the App constructor.

* chore(i18n): Improve translate

* refactor(Input): Implement angle-based logic for joystick directions

* refactor(Input): Rename MotionDirection to DeflectionDirection

* Implement faster/better resume from sleep (#473)

* Tentative: speed up resume

* build 0.28.0.6

* Migrate settings to ProgramData

* Improve task manager to speed startup

* Revert "Improve task manager to speed startup"

This reverts commit c5b93cf5d36eea4ee243b729fe0a1385a0558a19.

* misc

* build 0.28.0.7

* Use LocalApplicationData

* improve resume

* Fix KeyboardChord.GetChord

* (tentative) force recompose on system resume

* misc

* wait for user to reply on settings before going further, also use Windows 11 theme

* Misc UI improvements

* misc

* misc

* More work on settings migration

* Update HotkeysManager.cs

* Update App.xaml.cs

* misc fix

* misc

* misc

* Fix AsusACPI on system resume

* Tentative: Fix stalled UI on system resume

* (tentative) fix UI not rendering on resume

* (tentative) fix UI not rendering on resume

* build 0.28.0.8

* Prevent bottom buttons from getting focus

* Implemented: New options for Layout Mapping : Trigger to Button

- Turbo, Interruptable, Toggle

* (tentative) figure detect S3/S4 sleep states resume

* restore arbitrary sleep/resume delay from long sleep

* Fix IActions variable naming and usage (HasXXX)

* Fixed: Device illustration on about page

* Fix

* Fixed: SDL trigger to L/RSoft L/RFull

* Misc fixes

* Device Support: Legion Go 2 (#459)

* WIP

* Misc

* More work

* Fixed: Controller picking logic on plug/unplug

* Fixed: Translation causing notify icon (task tray) buttons to fail when translated

* Improved: Legion Go (1, 2) performance mode TDP (25W)

* Fixed: Legion Go 2, internal gyro/accelero angles reading

* Fixed: Controller picker

* Fixed: Crash on ProcessRenderMode

* Update SDL3: 3.2.24

https://github.com/libsdl-org/SDL/releases/tag/release-3.2.24

* Fixed: AYANEO FLIP DS 1S CEcControl_SetSecDispBrightness()

* Misc

- Migrate dump crashes to {localappdata}\CrashDumps
- Create zip backup when migrating {mydocuments}\HandheldCompanion

* Prevent the application from starting while we wait for user input

* Fixed: Misc crash/exceptions

* Fixed: Support over legacy IActions

* Fixed: AYANEO Flip DS 2nd screen ON/OFF toggle

* Improved: MultimediaManager GetDisplayFriendlyName()

* build 0.28.1.0

* Device support: AYANEOFlip1SDS

* build 0.28.1.1

* Misc fixes

* Remove WinRing0 (#475)

* Remove WinRing0

* Fixed: Issue with IGDB background download

* Misc

* build 0.28.2.0

* Use LpcIO instead of LpcPort

* Update OpenLibSys.cs

* tentative

* tentative

* tentative

* tentative

Use LpcIO instead of LpcPort

Update OpenLibSys.cs

tentative

tentative

* Revert "tentative"

This reverts commit 3ce974aa7fb369b851cfbc3f9dfbdc98c226c635.

* tentative

* misc

* more work

* tentative

* more work

* Fixes

* oups

* oups

* Fix iss

* Update LibreHardwareMonitorLib.dll

* build 0.28.1.2 (#476)

- Restored WinRing0 for TDP manipulation (until we find an alternative based on PawnIO)

* Restore missing WinRing0 force unload

* Fixed: Toast hanging

* Fixed: UI hanging on startup (WHY !?)

* Fixed: Prevent GPUmanger from holding onto DeviceManager while waiting for MultimediaManager to be ready

* Improved: Offset non-UI tasks away from UI thread

* build 0.28.1.3

* Fixed: UIHelper default DispatcherPriority

* Fixed: Add missing WinRing0x64.dll

* Fixed: Prevent failed processor initialization from crippling HC startup sequence

* build 0.28.1.4

* Improved: Library UI with with Favorites profiles

* Fixed: Wrong profile name on overwrite warning (profiles page)

* Implement Msiapcfg (#477)

* Tentatively add msiapcfg support

* Misc fixes

* build 0.28.1.5

* Improved UI: SteamGrid Logo parsing and LibraryFamily checkboxes

* Update libraries (build 0.28.1.6)

* Implemented: Support over Xbox Rog Ally (X/NonX) (#478)

* Implemented: Xbox Rog Ally support (WIP)

* Fixed: Deploy default power profiles with default profile

Should have been done LONG AGO !!

* Fixed: MSI Claw (all models) max fan speed (150%)

* Update XboxROGAlly.cs

* Implemented: Add support over Xbox ROG Ally X/NonX

* Change battery overlay widget to better logic and display (#1306)

* Refactor Overlay rendering logic to strategy design pattern

* Fix ai comments

* Add widget system with factory

* Fix some AI comments

* Add level selection for overlay widgets.
Refactor strategies (use widgets.

* Fix level for cpu widget in full overlay strategy

* - change battery left to hours and minutes format

* - add format for hours

* - fix after merge from `main`

* - little refactoring

* - add hours format

* - add return if null time left

* good to go

---------

Co-authored-by: Lesueur Benjamin <benjamin.lesueur@live.com>
(cherry picked from commit 283187b)

* Fixed: Battery reading without LibreHardwareMonitor (while we wait for a fix)

* build 0.28.1.7

* Fixed: Add missing UseOpenLib declarations

* Implemented: Task view function

* Improved: Task manager commands

* build 0.28.1.8

* Fixed: AYANEO Flip 1S DS/KB compatibility

* Move to Windows 11 SDK

Windows 10 is EOL as of October 14 2025

* Add default AYANEO power profiles (Extreme, Balanced, Saving power)

* Updated: Several libraries

* Fixed: Error on null processEx

* oups

* Fixed: Incorrect overwrite message displayed when creating a new profile

* Fixed: A crash occuring on OneXPlayerMini and OneXPlayerOneXFly devices

* Fixed: A rare crash happening on InputsManager

* Update LibreHardwareMonitorLib.dll

* UI: Improve LibraryPage image sizes

* Fixed: CPU usage from LibreHardware ADLX implementation (rely on ours instead)

* Library: Update SDL to 3.3.2

* build 0.28.1.9

* Revert "Library: Update SDL to 3.3.2"

This reverts commit 6353143.

* UI: Misc improvements

* Library: Updated SDL to 3.3.2

* UI: Added Power dropdown button to Quicktools (Lock, Sleep, Shutdown, Restart)

* Compatibility: Add Moonlight virtual controller detection and support

* Misc

* build 0.28.1.10

* Fixed: Prevent empty executable paths from being added to profile

* UI: SplashScreen no longer is AlwaysOnTop

* Library: Update HidHide, Sentry and LibreHardwareMonitor

* Fixed: Touchpad support on Legion Go (1/2)

* Fixed: OneX/AOKZOE OEM button support

* Implemented: New commands Copilot Voice

* Fixed: Joystick to button/keyboard/mouse click (axis threshold range)

* Library: Updated WindowsAPICodePack

* build 0.28.1.11

* Fixed: Crash caused by a race condition from VirtualManager when waking-up system

* UI: Improve toast manager (now has ability to generate clickable toasts)

* Improvements: CopilotVoiceCommands now also resize the Copilot window

* Fixed: CPU leak when HidDevice is torn off

* Fixed: Rare crash on null Controller

* Misc

* build 0.28.1.12

* Fixed: AYANEO Flip DS missing Close() override

* Misc

* Controller: Fixed Neptune Controller IsReady, IsConnected checks

* Implement .NET10 (#479)

* (WIP) implement NET10 support

* Update install script

* Implement RyzenAdj set_coall()

* Fixed: Steam Deck GPU reading

* Update libraries to NET10: LibreHardware, ViGEm.Client

* Update Nefarius.ViGEm.Client.dll

* Device support: GPD Win 5 (WIP)

* Improved: Process manager will now ignore Taskbar and Shellhost

* Updated: Libraries

* build 0.28.2.1

* Improved: Process manager

ForegroundStaging and XamlExplorerHostIslandWindow are now Restricted

* Improved: Process manager

ApplicationManager_DesktopShellWindow is now Restricted

* build 0.28.2.2

* Library: Update iNKORE.UI.WPF.Modern

* Device support: Improve overall AOKZOE and ONEX compatibility (fixes OEM button usage and improve FAN/LED management) (#480)

* Tentative: Fix OneX button lock

* Fixed: Several issues with OneX devices and IsOpen, IsReady checks as well ad HidDevice pickup on OneXFly

* Device support: OneXPlayer G1

* Improved overall ONEX/AOKZOE device support

backported some logic from HHD

---------

Co-authored-by: Kvintilyanov Aleksandr <mops1k@users.noreply.github.com>
Co-authored-by: Sanheiii <35133371+Sanheiii@users.noreply.github.com>
Valkirie added a commit that referenced this pull request Feb 1, 2026
* build 0.27.0.5

* Misc fix

* Add missing dynamic lighting capacities to MSI Claw

* build 0.27.0.6

* Implement EADesktop support through GameLib (#463)

* Implement EADesktop support through GameLib

Using custom repo: https://github.com/Valkirie/GameLib.NET/tree/EAapp

* Fix EADesktop logo missing from LibraryPage

* Ambilight: Reduce CPU consumption (#464)

* Reduce CPU usage, phase 1

* misc tweaks

* build 0.27.0.7

* Extended expected delay before profile related executable is ready

* Improve library manager SteamGrid lookup with cleaned string

* Optimizing IActions related functions (#465)

* Optimizing IActions related functions

* Pass delta to IActions to improve timed actions accuracy

* seal a few classes

* Use [MethodImpl(MethodImplOptions.AggressiveInlining)] on States

* Small State tweaks

* further improve States optimization

* build 0.27.0.8

* Reduce MSI Claw 1 rumble logic CPU usage

* Improved: Set device OEM buttons as Inherit on new profiles

* Improved: UI Navigation

- Quicktools will remember the last focused item from each page
- Quicktools navigation won't focus AppBarButton first
- Quicktools L1/R1 will automatically enter the page
- MainWindow page flow is more natural when pressing A/B

* Implement controller page related support section

* Fixed: version checking from profiles manager on older profile

* Fixed: GameBarCommands and DesktopCommands

* Improved: ROG Ally PerformanceMode and AsusFan.Mid

* Hacky: Fixed: Phantom controller filtering

* build 0.27.0.9

* Add Inherits for AllButtons and AllAxisLayoutFlags

* Update Quicktools Home and Applications UI

* Force (re)apply Quicktools transparency when changing postion

* Update libs

* oups

* Fixed: Issue when discovering non-Steam games with multiple executables

* Fixed: SDL XInput controller ignored

* Fixed: Issues when trying to trigger hotkeys

* Fixed: UI Issue when navigating into a page without IsEnabled controls

* Improved: QuickHome, QuickApplications UI

* build 0.27.0.10

* States fixes

* Improved: Removed hacky controller manager await in benefits of more robust device manager arrival logic

* Improved: Device management has new queuing logic

* Improved: Quicktools L1/R1 will now circle within menu items

* Filter SDL Events

* Fixed: Restore default fan profile when fan mode is set to Hardware

* Migrate some platform logic to PlatformManager

We should move the PlatformToProfile logic to LibraryManager or PlatformManager

* Fix Claw FanSpeed array

* Implemented: new commands ButtonCommands replacing GuideCommands

* Improve Action Type UI experience

* Fixed: Button to TriggerActions

* Improved: ButtonMapping and AxisMapping migrated to SettingsExpander and SettingsCard

* Improved: GyroMapping and TriggerMapping migrated to SettingsExpander and SettingsCard

* Improved: MouseAction Acceleration is now relying on action delta (ms) to compute velocity memory

* Misc UI tweaks

* build 0.27.0.11

* Misc UI improvements

* Fixed: OEM buttons will now properly inherit default behavior

* misc

* misc

* Fixed: Input/Hotkey injection on dummy controllers

* Revert: Improved: Device management has new queuing logic

* Fixed: Rog Ally Xbox Adaptive Controller support

* Improved: Allow users to edit default power profiles

* Edit a few default settings

* build 0.27.0.12

* Improve overall fan management and ROG Ally TDP (#466)

* (Tentative) Fix TDP/Fan issues

* Misc: migrate powerProfile management to IDevice

* update lib

* Improved: Controller management

* Implemented: Per-device hotkeys (#467)

* Improved: Controller management

* Improved: Per-device hotkeys

* build 0.27.0.13

* Fixed: Profile update when resolution or refresh rate is changed

* Misc (#468)

* Tentative fix buttons RGB control

* Fixed: Hotkey deserialization with old ButtonFlags

* code cleanup

* Fixed: missing library: YamlDotNet

* Fixed: hotkey duplication

* Updated LibreHardwareMonitorLib

* Fixed: Zotac Gaming Zone VRAM control

* Fixed: LegionR/LegionL inverted buttons on Legion Go S

* build 0.27.0.14

* Improve session and device management (#469)

* Improved: HC won't wait until session is ready anymore, except for keyboard input management

* Fixed: Device management asynchronous refresh

* Fixed: Device management asynchronous refresh

* oups

* Revert "Fixed: Profile update when resolution or refresh rate is changed"

This reverts commit 0fa4512.

* only update if necessary

* Update SDL3.dll

* Device support: Add ONEXPLAYER X1 AMD (weird ProductName: ONEXPLAYER X1z)

* Improved: Installation script to add WinRing0x64.sys and HandheldCompanion.sys to defender exclusion list

* build 0.28.0.0

* Update libraries

* Force refresh platform catalog when scanning

* Update LibreHardwareMonitorLib

* RyzenAdj 0.18.0

- Update for ryzen_smu 0.1.7
- Support: Strix Point
- Support: Dragon Range
- Support: Fire Range
- Support: HX370 (Pro)
- Support: Krackan Point

* Fixed: UI not rendering after GPU acceleration is toggled on/off

not perfect..

* DClawController to use GenericController instead of raw HidDevice

* build 0.28.0.1

* Reduce CPU usage (#470)

* Reduce cpu usage on DInputController

* Reduce CPU usage from HidLibrary

* Reduce CPU usage a pressure on ThreadPool with RaiseInputsUpdatedAsync

* Reduce CPU usage from RadioMonitor

* Update OverlayModel.xaml

* build 0.28.0.2

* Update Resources.fr-FR.resx

Traduction par: Moi952

* Improved: UI freeze workaround

* build 0.28.0.3

* Update libs

* Improve controller management

- Properly unhide (with power cycling) if HIDuncloakonclose is set
- Wait until any rumble is complete before power cycling

* ForceRecompose windows on system resume

* Add PawnIO support for LibreHardware 0.9.5

- Fixes CPU power/temperature reading

* build 0.28.0.4

* Fixed: Keyboard chord hotkey trigger on SDL-based controllers

* Improved: CPU usage on LibreHardwareLibrary

* Fixed: Setting a profile favorite subprofile

* Improved: ProfilesPage shows saved windows settings alongside live

* Revert "Fixed: Keyboard chord hotkey trigger on SDL-based controllers"

This reverts commit d0a9483.

* Improved: SDL controllers will use Tick() logic rather than inputs pumping

* Fixed: MainWindow visibility on Task View when minimized

* Updated: LibreHardwareMonitorLib

* build 0.28.0.5

* Misc

* Improved: Window State/Visibility logic

* Misc

* Improved: UIGamepad navigation with HyperlinkButton

* Implemented: New controller setting: HIDuncloakondisconnect

* Fixed: MSI Claw 10F BIOS support

* Resolve startup crash and refactor joystick input (#472)

* fix(app): Crash caused by Logger not being loaded in the App constructor.

* chore(i18n): Improve translate

* refactor(Input): Implement angle-based logic for joystick directions

* refactor(Input): Rename MotionDirection to DeflectionDirection

* Implement faster/better resume from sleep (#473)

* Tentative: speed up resume

* build 0.28.0.6

* Migrate settings to ProgramData

* Improve task manager to speed startup

* Revert "Improve task manager to speed startup"

This reverts commit c5b93cf5d36eea4ee243b729fe0a1385a0558a19.

* misc

* build 0.28.0.7

* Use LocalApplicationData

* improve resume

* Fix KeyboardChord.GetChord

* (tentative) force recompose on system resume

* misc

* wait for user to reply on settings before going further, also use Windows 11 theme

* Misc UI improvements

* misc

* misc

* More work on settings migration

* Update HotkeysManager.cs

* Update App.xaml.cs

* misc fix

* misc

* misc

* Fix AsusACPI on system resume

* Tentative: Fix stalled UI on system resume

* (tentative) fix UI not rendering on resume

* (tentative) fix UI not rendering on resume

* build 0.28.0.8

* Prevent bottom buttons from getting focus

* Implemented: New options for Layout Mapping : Trigger to Button

- Turbo, Interruptable, Toggle

* (tentative) figure detect S3/S4 sleep states resume

* restore arbitrary sleep/resume delay from long sleep

* Fix IActions variable naming and usage (HasXXX)

* Fixed: Device illustration on about page

* Fix

* Fixed: SDL trigger to L/RSoft L/RFull

* Misc fixes

* Device Support: Legion Go 2 (#459)

* WIP

* Misc

* More work

* Fixed: Controller picking logic on plug/unplug

* Fixed: Translation causing notify icon (task tray) buttons to fail when translated

* Improved: Legion Go (1, 2) performance mode TDP (25W)

* Fixed: Legion Go 2, internal gyro/accelero angles reading

* Fixed: Controller picker

* Fixed: Crash on ProcessRenderMode

* Update SDL3: 3.2.24

https://github.com/libsdl-org/SDL/releases/tag/release-3.2.24

* Fixed: AYANEO FLIP DS 1S CEcControl_SetSecDispBrightness()

* Misc

- Migrate dump crashes to {localappdata}\CrashDumps
- Create zip backup when migrating {mydocuments}\HandheldCompanion

* Prevent the application from starting while we wait for user input

* Fixed: Misc crash/exceptions

* Fixed: Support over legacy IActions

* Fixed: AYANEO Flip DS 2nd screen ON/OFF toggle

* Improved: MultimediaManager GetDisplayFriendlyName()

* build 0.28.1.0

* Device support: AYANEOFlip1SDS

* build 0.28.1.1

* Misc fixes

* Remove WinRing0 (#475)

* Remove WinRing0

* Fixed: Issue with IGDB background download

* Misc

* build 0.28.2.0

* Use LpcIO instead of LpcPort

* Update OpenLibSys.cs

* tentative

* tentative

* tentative

* tentative

Use LpcIO instead of LpcPort

Update OpenLibSys.cs

tentative

tentative

* Revert "tentative"

This reverts commit 3ce974aa7fb369b851cfbc3f9dfbdc98c226c635.

* tentative

* misc

* more work

* tentative

* more work

* Fixes

* oups

* oups

* Fix iss

* Update LibreHardwareMonitorLib.dll

* build 0.28.1.2 (#476)

- Restored WinRing0 for TDP manipulation (until we find an alternative based on PawnIO)

* Restore missing WinRing0 force unload

* Fixed: Toast hanging

* Fixed: UI hanging on startup (WHY !?)

* Fixed: Prevent GPUmanger from holding onto DeviceManager while waiting for MultimediaManager to be ready

* Improved: Offset non-UI tasks away from UI thread

* build 0.28.1.3

* Fixed: UIHelper default DispatcherPriority

* Fixed: Add missing WinRing0x64.dll

* Fixed: Prevent failed processor initialization from crippling HC startup sequence

* build 0.28.1.4

* Improved: Library UI with with Favorites profiles

* Fixed: Wrong profile name on overwrite warning (profiles page)

* Implement Msiapcfg (#477)

* Tentatively add msiapcfg support

* Misc fixes

* build 0.28.1.5

* Improved UI: SteamGrid Logo parsing and LibraryFamily checkboxes

* Update libraries (build 0.28.1.6)

* Implemented: Support over Xbox Rog Ally (X/NonX) (#478)

* Implemented: Xbox Rog Ally support (WIP)

* Fixed: Deploy default power profiles with default profile

Should have been done LONG AGO !!

* Fixed: MSI Claw (all models) max fan speed (150%)

* Update XboxROGAlly.cs

* Implemented: Add support over Xbox ROG Ally X/NonX

* Change battery overlay widget to better logic and display (#1306)

* Refactor Overlay rendering logic to strategy design pattern

* Fix ai comments

* Add widget system with factory

* Fix some AI comments

* Add level selection for overlay widgets.
Refactor strategies (use widgets.

* Fix level for cpu widget in full overlay strategy

* - change battery left to hours and minutes format

* - add format for hours

* - fix after merge from `main`

* - little refactoring

* - add hours format

* - add return if null time left

* good to go

---------

Co-authored-by: Lesueur Benjamin <benjamin.lesueur@live.com>
(cherry picked from commit 283187b)

* Fixed: Battery reading without LibreHardwareMonitor (while we wait for a fix)

* build 0.28.1.7

* Fixed: Add missing UseOpenLib declarations

* Implemented: Task view function

* Improved: Task manager commands

* build 0.28.1.8

* Fixed: AYANEO Flip 1S DS/KB compatibility

* Move to Windows 11 SDK

Windows 10 is EOL as of October 14 2025

* Add default AYANEO power profiles (Extreme, Balanced, Saving power)

* Updated: Several libraries

* Fixed: Error on null processEx

* oups

* Fixed: Incorrect overwrite message displayed when creating a new profile

* Fixed: A crash occuring on OneXPlayerMini and OneXPlayerOneXFly devices

* Fixed: A rare crash happening on InputsManager

* Update LibreHardwareMonitorLib.dll

* UI: Improve LibraryPage image sizes

* Fixed: CPU usage from LibreHardware ADLX implementation (rely on ours instead)

* Library: Update SDL to 3.3.2

* build 0.28.1.9

* Revert "Library: Update SDL to 3.3.2"

This reverts commit 6353143.

* UI: Misc improvements

* Library: Updated SDL to 3.3.2

* UI: Added Power dropdown button to Quicktools (Lock, Sleep, Shutdown, Restart)

* Compatibility: Add Moonlight virtual controller detection and support

* Misc

* build 0.28.1.10

* Fixed: Prevent empty executable paths from being added to profile

* UI: SplashScreen no longer is AlwaysOnTop

* Library: Update HidHide, Sentry and LibreHardwareMonitor

* Fixed: Touchpad support on Legion Go (1/2)

* Fixed: OneX/AOKZOE OEM button support

* Implemented: New commands Copilot Voice

* Fixed: Joystick to button/keyboard/mouse click (axis threshold range)

* Library: Updated WindowsAPICodePack

* build 0.28.1.11

* Fixed: Crash caused by a race condition from VirtualManager when waking-up system

* UI: Improve toast manager (now has ability to generate clickable toasts)

* Improvements: CopilotVoiceCommands now also resize the Copilot window

* Fixed: CPU leak when HidDevice is torn off

* Fixed: Rare crash on null Controller

* Misc

* build 0.28.1.12

* Fixed: AYANEO Flip DS missing Close() override

* Misc

* Controller: Fixed Neptune Controller IsReady, IsConnected checks

* Implement .NET10 (#479)

* (WIP) implement NET10 support

* Update install script

* Implement RyzenAdj set_coall()

* Fixed: Steam Deck GPU reading

* Update libraries to NET10: LibreHardware, ViGEm.Client

* Update Nefarius.ViGEm.Client.dll

* Device support: GPD Win 5 (WIP)

* Improved: Process manager will now ignore Taskbar and Shellhost

* Updated: Libraries

* build 0.28.2.1

* Improved: Process manager

ForegroundStaging and XamlExplorerHostIslandWindow are now Restricted

* Improved: Process manager

ApplicationManager_DesktopShellWindow is now Restricted

* build 0.28.2.2

* Library: Update iNKORE.UI.WPF.Modern

* Device support: Improve overall AOKZOE and ONEX compatibility (fixes OEM button usage and improve FAN/LED management) (#480)

* Tentative: Fix OneX button lock

* Fixed: Several issues with OneX devices and IsOpen, IsReady checks as well ad HidDevice pickup on OneXFly

* Device support: OneXPlayer G1

* Improved overall ONEX/AOKZOE device support

backported some logic from HHD

* Device support: Add DynamicLightingSecondLEDColor to all AYANEO devices

* Implement proper voltage control (AMD, Intel) (#481)

* Implement proper voltage control (AMD, Intel)

* Misc fixes

* Misc

* Reduce Minimum values on RyzenAdj CoAll and CoGfx

* UI: Fixed an issue when toggling hotkeys with gamepad

* UI: Fixed an issue when toggling hotkeys with gamepad

* UI: Added tooltip buttons for voltage related components

* UI: Add missing tooltips

* build 0.28.2.3

* Improved: InputsManager modifier keys handling

* build 0.28.2.4

* Misc

* Fixed: hacky, fix broken profiles with Turbo and Toggle enabled across all actions

* Fixed: AYANEO Air Plus EC logic

* Device support: Implement SuiPlay 0X1 support (tentative)

* build 0.28.2.5

* Fix MYSTEN company name

* Fixed: AYANEO (Legacy, Modern) charge bypass logic

* build 0.28.2.6

* Device support: Add missing SuiPlay 0X1 image

* Fixed #1234 by @GopherTheCoder

* Misc

* Fixed: Issue where input duration slider wouldn't be displayed on layout editor

* Fixed: Rare crash issue when editing a layout

* Device: Change GPD Win 5 max TDP to 85W

* Implemented new hotkey: Controller status (Connected, Disconnected)

* Implemented new layout action: Absolute mouse position

* Updated libaries: SDL3, LibreHardwareMonitor, RAMSPDToolkit-NDD

* Added new action modifier key: LWin

* Hotkey: New command type: PowerShellCommands

* UI: Ask user before deleting hotkeys

* Misc fix

* Ported EnhancedSleep and ReSleep from SuspendedNTime from @BassemMohsen

* Fix missing ledColor vars on AYANEO CEc devices

* Fixed: ADLX Probe

* Fixed ADLX Probe

* Fixed ADLX Probe

* Tentative: Fix ADLX Probe (#482)

* Fixed: missing ryzenAdj checks

* fix: make the toggle state shared and match the real status (#1343)

Signed-off-by: Pedro Parra Ortega <pedro.parraortega@enreach.com>

* UI: Misc improvements

* feat: add support to delay action bindings (#1345)

* fix: correct shared toggle state and support delayed actions (#1347)

* fix: correct shared toggle state and support delayed actions

* Update HandheldCompanion/Actions/MouseActions.cs

ignore suggested actions

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Improve MouseActions MoveToPrevious (#483)

* tentative

* improve code

* misc

* Misc UI tweaks

* feat: add triggers support for shift actions (#1350)

* build 2.8.3.0

* feat: correct shift logic and add support for shift combiantions (#1352)

* Library: LibreHardwareMonitorLib updated to NET10

* Fixed GPD Win Max 2 (HX370) gyro/accelero axis

* code cleanup

* Feat/improve shif layouts (#1353)

* feat: correct shift logic and add support for shift combiantions

* fix: add backward compatibility

* Fixed: Gyroscope/Accelerometer angles for: GPD Win 5, GPD Win Mini (8840U, HX370)

* Misc

* Fixed an issue where a controller wouldn't properly (re)plug after power cycling

* Improved FSE compatibility. MainWindow will now properly resize, show, hide when FSE is enabled or disabled

* Fixed a rare crash on HotkeyViewModel where Hotkey command buttonflags would be null

* Misc

* Fixed Quicktools behavior once FSE was summoned

* Don't try and get artwork for explorer.exe

* build 0.28.3.1

* merge

---------

Signed-off-by: Pedro Parra Ortega <pedro.parraortega@enreach.com>
Co-authored-by: Sanheiii <35133371+Sanheiii@users.noreply.github.com>
Co-authored-by: Kvintilyanov Aleksandr <mops1k@users.noreply.github.com>
Co-authored-by: pepordev <parraortega.pedro@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Valkirie added a commit that referenced this pull request Feb 8, 2026
* Fixed: Issues when trying to trigger hotkeys

* Fixed: UI Issue when navigating into a page without IsEnabled controls

* Improved: QuickHome, QuickApplications UI

* build 0.27.0.10

* States fixes

* Improved: Removed hacky controller manager await in benefits of more robust device manager arrival logic

* Improved: Device management has new queuing logic

* Improved: Quicktools L1/R1 will now circle within menu items

* Filter SDL Events

* Fixed: Restore default fan profile when fan mode is set to Hardware

* Migrate some platform logic to PlatformManager

We should move the PlatformToProfile logic to LibraryManager or PlatformManager

* Fix Claw FanSpeed array

* Implemented: new commands ButtonCommands replacing GuideCommands

* Improve Action Type UI experience

* Fixed: Button to TriggerActions

* Improved: ButtonMapping and AxisMapping migrated to SettingsExpander and SettingsCard

* Improved: GyroMapping and TriggerMapping migrated to SettingsExpander and SettingsCard

* Improved: MouseAction Acceleration is now relying on action delta (ms) to compute velocity memory

* Misc UI tweaks

* build 0.27.0.11

* Misc UI improvements

* Fixed: OEM buttons will now properly inherit default behavior

* misc

* misc

* Fixed: Input/Hotkey injection on dummy controllers

* Revert: Improved: Device management has new queuing logic

* Fixed: Rog Ally Xbox Adaptive Controller support

* Improved: Allow users to edit default power profiles

* Edit a few default settings

* build 0.27.0.12

* Improve overall fan management and ROG Ally TDP (#466)

* (Tentative) Fix TDP/Fan issues

* Misc: migrate powerProfile management to IDevice

* update lib

* Improved: Controller management

* Implemented: Per-device hotkeys (#467)

* Improved: Controller management

* Improved: Per-device hotkeys

* build 0.27.0.13

* Fixed: Profile update when resolution or refresh rate is changed

* Misc (#468)

* Tentative fix buttons RGB control

* Fixed: Hotkey deserialization with old ButtonFlags

* code cleanup

* Fixed: missing library: YamlDotNet

* Fixed: hotkey duplication

* Updated LibreHardwareMonitorLib

* Fixed: Zotac Gaming Zone VRAM control

* Fixed: LegionR/LegionL inverted buttons on Legion Go S

* build 0.27.0.14

* Improve session and device management (#469)

* Improved: HC won't wait until session is ready anymore, except for keyboard input management

* Fixed: Device management asynchronous refresh

* Fixed: Device management asynchronous refresh

* oups

* Revert "Fixed: Profile update when resolution or refresh rate is changed"

This reverts commit 0fa4512.

* only update if necessary

* Update SDL3.dll

* Device support: Add ONEXPLAYER X1 AMD (weird ProductName: ONEXPLAYER X1z)

* Improved: Installation script to add WinRing0x64.sys and HandheldCompanion.sys to defender exclusion list

* build 0.28.0.0

* Update libraries

* Force refresh platform catalog when scanning

* Update LibreHardwareMonitorLib

* RyzenAdj 0.18.0

- Update for ryzen_smu 0.1.7
- Support: Strix Point
- Support: Dragon Range
- Support: Fire Range
- Support: HX370 (Pro)
- Support: Krackan Point

* Fixed: UI not rendering after GPU acceleration is toggled on/off

not perfect..

* DClawController to use GenericController instead of raw HidDevice

* build 0.28.0.1

* Reduce CPU usage (#470)

* Reduce cpu usage on DInputController

* Reduce CPU usage from HidLibrary

* Reduce CPU usage a pressure on ThreadPool with RaiseInputsUpdatedAsync

* Reduce CPU usage from RadioMonitor

* Update OverlayModel.xaml

* build 0.28.0.2

* Update Resources.fr-FR.resx

Traduction par: Moi952

* Improved: UI freeze workaround

* build 0.28.0.3

* Update libs

* Improve controller management

- Properly unhide (with power cycling) if HIDuncloakonclose is set
- Wait until any rumble is complete before power cycling

* ForceRecompose windows on system resume

* Add PawnIO support for LibreHardware 0.9.5

- Fixes CPU power/temperature reading

* build 0.28.0.4

* Fixed: Keyboard chord hotkey trigger on SDL-based controllers

* Improved: CPU usage on LibreHardwareLibrary

* Fixed: Setting a profile favorite subprofile

* Improved: ProfilesPage shows saved windows settings alongside live

* Revert "Fixed: Keyboard chord hotkey trigger on SDL-based controllers"

This reverts commit d0a9483.

* Improved: SDL controllers will use Tick() logic rather than inputs pumping

* Fixed: MainWindow visibility on Task View when minimized

* Updated: LibreHardwareMonitorLib

* build 0.28.0.5

* Misc

* Improved: Window State/Visibility logic

* Misc

* Improved: UIGamepad navigation with HyperlinkButton

* Implemented: New controller setting: HIDuncloakondisconnect

* Fixed: MSI Claw 10F BIOS support

* Resolve startup crash and refactor joystick input (#472)

* fix(app): Crash caused by Logger not being loaded in the App constructor.

* chore(i18n): Improve translate

* refactor(Input): Implement angle-based logic for joystick directions

* refactor(Input): Rename MotionDirection to DeflectionDirection

* Implement faster/better resume from sleep (#473)

* Tentative: speed up resume

* build 0.28.0.6

* Migrate settings to ProgramData

* Improve task manager to speed startup

* Revert "Improve task manager to speed startup"

This reverts commit c5b93cf5d36eea4ee243b729fe0a1385a0558a19.

* misc

* build 0.28.0.7

* Use LocalApplicationData

* improve resume

* Fix KeyboardChord.GetChord

* (tentative) force recompose on system resume

* misc

* wait for user to reply on settings before going further, also use Windows 11 theme

* Misc UI improvements

* misc

* misc

* More work on settings migration

* Update HotkeysManager.cs

* Update App.xaml.cs

* misc fix

* misc

* misc

* Fix AsusACPI on system resume

* Tentative: Fix stalled UI on system resume

* (tentative) fix UI not rendering on resume

* (tentative) fix UI not rendering on resume

* build 0.28.0.8

* Prevent bottom buttons from getting focus

* Implemented: New options for Layout Mapping : Trigger to Button

- Turbo, Interruptable, Toggle

* (tentative) figure detect S3/S4 sleep states resume

* restore arbitrary sleep/resume delay from long sleep

* Fix IActions variable naming and usage (HasXXX)

* Fixed: Device illustration on about page

* Fix

* Fixed: SDL trigger to L/RSoft L/RFull

* Misc fixes

* Device Support: Legion Go 2 (#459)

* WIP

* Misc

* More work

* Fixed: Controller picking logic on plug/unplug

* Fixed: Translation causing notify icon (task tray) buttons to fail when translated

* Improved: Legion Go (1, 2) performance mode TDP (25W)

* Fixed: Legion Go 2, internal gyro/accelero angles reading

* Fixed: Controller picker

* Fixed: Crash on ProcessRenderMode

* Update SDL3: 3.2.24

https://github.com/libsdl-org/SDL/releases/tag/release-3.2.24

* Fixed: AYANEO FLIP DS 1S CEcControl_SetSecDispBrightness()

* Misc

- Migrate dump crashes to {localappdata}\CrashDumps
- Create zip backup when migrating {mydocuments}\HandheldCompanion

* Prevent the application from starting while we wait for user input

* Fixed: Misc crash/exceptions

* Fixed: Support over legacy IActions

* Fixed: AYANEO Flip DS 2nd screen ON/OFF toggle

* Improved: MultimediaManager GetDisplayFriendlyName()

* build 0.28.1.0

* Device support: AYANEOFlip1SDS

* build 0.28.1.1

* Misc fixes

* Remove WinRing0 (#475)

* Remove WinRing0

* Fixed: Issue with IGDB background download

* Misc

* build 0.28.2.0

* Use LpcIO instead of LpcPort

* Update OpenLibSys.cs

* tentative

* tentative

* tentative

* tentative

Use LpcIO instead of LpcPort

Update OpenLibSys.cs

tentative

tentative

* Revert "tentative"

This reverts commit 3ce974aa7fb369b851cfbc3f9dfbdc98c226c635.

* tentative

* misc

* more work

* tentative

* more work

* Fixes

* oups

* oups

* Fix iss

* Update LibreHardwareMonitorLib.dll

* build 0.28.1.2 (#476)

- Restored WinRing0 for TDP manipulation (until we find an alternative based on PawnIO)

* Restore missing WinRing0 force unload

* Fixed: Toast hanging

* Fixed: UI hanging on startup (WHY !?)

* Fixed: Prevent GPUmanger from holding onto DeviceManager while waiting for MultimediaManager to be ready

* Improved: Offset non-UI tasks away from UI thread

* build 0.28.1.3

* Fixed: UIHelper default DispatcherPriority

* Fixed: Add missing WinRing0x64.dll

* Fixed: Prevent failed processor initialization from crippling HC startup sequence

* build 0.28.1.4

* Improved: Library UI with with Favorites profiles

* Fixed: Wrong profile name on overwrite warning (profiles page)

* Implement Msiapcfg (#477)

* Tentatively add msiapcfg support

* Misc fixes

* build 0.28.1.5

* Improved UI: SteamGrid Logo parsing and LibraryFamily checkboxes

* Update libraries (build 0.28.1.6)

* Implemented: Support over Xbox Rog Ally (X/NonX) (#478)

* Implemented: Xbox Rog Ally support (WIP)

* Fixed: Deploy default power profiles with default profile

Should have been done LONG AGO !!

* Fixed: MSI Claw (all models) max fan speed (150%)

* Update XboxROGAlly.cs

* Implemented: Add support over Xbox ROG Ally X/NonX

* Change battery overlay widget to better logic and display (#1306)

* Refactor Overlay rendering logic to strategy design pattern

* Fix ai comments

* Add widget system with factory

* Fix some AI comments

* Add level selection for overlay widgets.
Refactor strategies (use widgets.

* Fix level for cpu widget in full overlay strategy

* - change battery left to hours and minutes format

* - add format for hours

* - fix after merge from `main`

* - little refactoring

* - add hours format

* - add return if null time left

* good to go

---------

Co-authored-by: Lesueur Benjamin <benjamin.lesueur@live.com>
(cherry picked from commit 283187b)

* Fixed: Battery reading without LibreHardwareMonitor (while we wait for a fix)

* build 0.28.1.7

* Fixed: Add missing UseOpenLib declarations

* Implemented: Task view function

* Improved: Task manager commands

* build 0.28.1.8

* Fixed: AYANEO Flip 1S DS/KB compatibility

* Move to Windows 11 SDK

Windows 10 is EOL as of October 14 2025

* Add default AYANEO power profiles (Extreme, Balanced, Saving power)

* Updated: Several libraries

* Fixed: Error on null processEx

* oups

* Fixed: Incorrect overwrite message displayed when creating a new profile

* Fixed: A crash occuring on OneXPlayerMini and OneXPlayerOneXFly devices

* Fixed: A rare crash happening on InputsManager

* Update LibreHardwareMonitorLib.dll

* UI: Improve LibraryPage image sizes

* Fixed: CPU usage from LibreHardware ADLX implementation (rely on ours instead)

* Library: Update SDL to 3.3.2

* build 0.28.1.9

* Revert "Library: Update SDL to 3.3.2"

This reverts commit 6353143.

* UI: Misc improvements

* Library: Updated SDL to 3.3.2

* UI: Added Power dropdown button to Quicktools (Lock, Sleep, Shutdown, Restart)

* Compatibility: Add Moonlight virtual controller detection and support

* Misc

* build 0.28.1.10

* Fixed: Prevent empty executable paths from being added to profile

* UI: SplashScreen no longer is AlwaysOnTop

* Library: Update HidHide, Sentry and LibreHardwareMonitor

* Fixed: Touchpad support on Legion Go (1/2)

* Fixed: OneX/AOKZOE OEM button support

* Implemented: New commands Copilot Voice

* Fixed: Joystick to button/keyboard/mouse click (axis threshold range)

* Library: Updated WindowsAPICodePack

* build 0.28.1.11

* Fixed: Crash caused by a race condition from VirtualManager when waking-up system

* UI: Improve toast manager (now has ability to generate clickable toasts)

* Improvements: CopilotVoiceCommands now also resize the Copilot window

* Fixed: CPU leak when HidDevice is torn off

* Fixed: Rare crash on null Controller

* Misc

* build 0.28.1.12

* Fixed: AYANEO Flip DS missing Close() override

* Misc

* Controller: Fixed Neptune Controller IsReady, IsConnected checks

* Implement .NET10 (#479)

* (WIP) implement NET10 support

* Update install script

* Implement RyzenAdj set_coall()

* Fixed: Steam Deck GPU reading

* Update libraries to NET10: LibreHardware, ViGEm.Client

* Update Nefarius.ViGEm.Client.dll

* Device support: GPD Win 5 (WIP)

* Improved: Process manager will now ignore Taskbar and Shellhost

* Updated: Libraries

* build 0.28.2.1

* Improved: Process manager

ForegroundStaging and XamlExplorerHostIslandWindow are now Restricted

* Improved: Process manager

ApplicationManager_DesktopShellWindow is now Restricted

* build 0.28.2.2

* Library: Update iNKORE.UI.WPF.Modern

* Device support: Improve overall AOKZOE and ONEX compatibility (fixes OEM button usage and improve FAN/LED management) (#480)

* Tentative: Fix OneX button lock

* Fixed: Several issues with OneX devices and IsOpen, IsReady checks as well ad HidDevice pickup on OneXFly

* Device support: OneXPlayer G1

* Improved overall ONEX/AOKZOE device support

backported some logic from HHD

* Device support: Add DynamicLightingSecondLEDColor to all AYANEO devices

* Implement proper voltage control (AMD, Intel) (#481)

* Implement proper voltage control (AMD, Intel)

* Misc fixes

* Misc

* Reduce Minimum values on RyzenAdj CoAll and CoGfx

* UI: Fixed an issue when toggling hotkeys with gamepad

* UI: Fixed an issue when toggling hotkeys with gamepad

* UI: Added tooltip buttons for voltage related components

* UI: Add missing tooltips

* build 0.28.2.3

* Improved: InputsManager modifier keys handling

* build 0.28.2.4

* Misc

* Fixed: hacky, fix broken profiles with Turbo and Toggle enabled across all actions

* Fixed: AYANEO Air Plus EC logic

* Device support: Implement SuiPlay 0X1 support (tentative)

* build 0.28.2.5

* Fix MYSTEN company name

* Fixed: AYANEO (Legacy, Modern) charge bypass logic

* build 0.28.2.6

* Device support: Add missing SuiPlay 0X1 image

* Fixed #1234 by @GopherTheCoder

* Misc

* Fixed: Issue where input duration slider wouldn't be displayed on layout editor

* Fixed: Rare crash issue when editing a layout

* Device: Change GPD Win 5 max TDP to 85W

* Implemented new hotkey: Controller status (Connected, Disconnected)

* Implemented new layout action: Absolute mouse position

* Updated libaries: SDL3, LibreHardwareMonitor, RAMSPDToolkit-NDD

* Added new action modifier key: LWin

* Hotkey: New command type: PowerShellCommands

* UI: Ask user before deleting hotkeys

* Misc fix

* Ported EnhancedSleep and ReSleep from SuspendedNTime from @BassemMohsen

* Fix missing ledColor vars on AYANEO CEc devices

* Fixed: ADLX Probe

* Fixed ADLX Probe

* Fixed ADLX Probe

* Tentative: Fix ADLX Probe (#482)

* Fixed: missing ryzenAdj checks

* fix: make the toggle state shared and match the real status (#1343)

Signed-off-by: Pedro Parra Ortega <pedro.parraortega@enreach.com>

* UI: Misc improvements

* feat: add support to delay action bindings (#1345)

* fix: correct shared toggle state and support delayed actions (#1347)

* fix: correct shared toggle state and support delayed actions

* Update HandheldCompanion/Actions/MouseActions.cs

ignore suggested actions

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Improve MouseActions MoveToPrevious (#483)

* tentative

* improve code

* misc

* Misc UI tweaks

* feat: add triggers support for shift actions (#1350)

* build 2.8.3.0

* feat: correct shift logic and add support for shift combiantions (#1352)

* Library: LibreHardwareMonitorLib updated to NET10

* Fixed GPD Win Max 2 (HX370) gyro/accelero axis

* code cleanup

* Feat/improve shif layouts (#1353)

* feat: correct shift logic and add support for shift combiantions

* fix: add backward compatibility

* Fixed: Gyroscope/Accelerometer angles for: GPD Win 5, GPD Win Mini (8840U, HX370)

* Misc

* Fixed an issue where a controller wouldn't properly (re)plug after power cycling

* Improved FSE compatibility. MainWindow will now properly resize, show, hide when FSE is enabled or disabled

* Fixed a rare crash on HotkeyViewModel where Hotkey command buttonflags would be null

* Misc

* Fixed Quicktools behavior once FSE was summoned

* Don't try and get artwork for explorer.exe

* build 0.28.3.1

* Fixed: Crash on null ProfilesPage.selectedProfile when ControllerManaget.GetDefault() is called

* Fixed: Crash on unsynced Layout on Clone()

* Layout: Allow 100% outer deadzone on triggers to mimic clickable trigger

* Misc

* Improve controller management (logic, UI, notifications) (#485)

* WIP

* More work

* build 0.28.3.2

* feat: add axis input support for move (absolute) action and fix tick interval for start delay) (#484)

Signed-off-by: Pedro Parra Ortega <parraortega.pedro@gmail.com>

* MasterInterval slider

* Improve MasterInterval

* Fixed: SensorsManager Suspend/Resume on sleep

* SDL: Updated gamecontrollerdb

* Library: SDL 3.3.6

* feat(shift): Add support for strict and any logic (#486)

* UI: Improve UI navigation on embedded NavigationView (as seen in LayoutPage)

* Further improve UI gamepad navigation

* code cleanup

* Misc UI updates

* UI: Misc

* UI: Misc

* feat: fixed translations and added shortcut for layout (#487)

* Restore subprofiles on library page. That's an intended behavior

* Fixed: Race condition crash on TimerManager

* Fix GPD WIN 5 buttons

* Feat/improve layout settings (#489)

* feat: improve layout system

* fix: correct inherit and added missing configurations

* fix: correct visibility and conditions on layout configs (#490)

* fix: correct axis/trigger configurations visibility (#491)

* Improve Profiles page UI (#488)

* temp tests

* more work

* more work

* more work

* more work

* more work

* misc

* More work

* fix

* more work

* more work

* Misc

* Improved SteamGridDb, will now capture official artworks first

* Misc UI tweaks

* Misc fixes

* more work

* more work

* Misc UI

* Misc UI tweaks

* code cleanup

* build 0.28.3.3

---------

Signed-off-by: Pedro Parra Ortega <pedro.parraortega@enreach.com>
Signed-off-by: Pedro Parra Ortega <parraortega.pedro@gmail.com>
Co-authored-by: Sanheiii <35133371+Sanheiii@users.noreply.github.com>
Co-authored-by: Kvintilyanov Aleksandr <mops1k@users.noreply.github.com>
Co-authored-by: pepordev <parraortega.pedro@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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