Repository navigation
CmdPal: Redesign the Performance Monitor Battery card - #51220
Open
Clint Rutkas (crutkas) wants to merge 1 commit into
Open
Clint Rutkas (crutkas) wants to merge 1 commit into
Clint Rutkas (crutkas) wants to merge 1 commit into
Conversation
🧭 PR intakeVisual evidence: Not needed — The changed files do not indicate a visible UI change. Visual evidence was detected in the PR description. Recommendation
✅ Ready for reviewThis PR passed the automated intake checks and is ready for maintainer review. Automated PR intake; PowerToys maintainers make final decisions. |
2 of 11 tasks
4 of 11 tasks
Redraw the Battery card with the native Adaptive Cards elements from the layers below: a Chart.Gauge of the charge, which fills in warning below 50% and attention below 20%, next to a status badge with a battery icon (Charging, Plugged in, or On battery) and the time remaining. Tiles below show the charge or discharge rate, the battery's health, and its full charge capacity, each only when Windows reports it. BatteryStats now reads the aggregate battery report for the charge rate, design capacity, and full charge capacity. Health is the full charge capacity as a percentage of the design capacity. The card shows the charge rate only while charging, and the discharge rate only on battery power: plugged in and idle, small readings come and go. Layer 11 of 13 in a stack that splits #51125.
Mike Griese (zadjii-msft)
force-pushed
the
crutkas-stack-11-battery-card
branch
from
October 15, 2026 11:15
a3bc95d to
a40a583
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
Layer 11 of 13 in a stack that splits #51125 (native Adaptive Cards charts and redesigned Performance Monitor cards) into reviewable PRs. See #51125 for the full picture. This layer is based on layer 10 (#51219,
crutkas-stack-10-gauge-donut-pie-charts), so the diff shows only this layer. The Overview card and dock band follow in layer 12.This layer redesigns the Performance Monitor Battery card with the native elements from the layers below:
Chart.Gauge, layer 10). Its scale has attention (0–20%), warning (20–50%), and good (50–100%) segments, and the fill takes the color of the segment the charge is in.mainThe test machine was plugged in and fully charged, so the live card above has no rate tile. These states use sample data; see Screenshots:
PR Checklist
Battery_Widget_Template/*strings in the extension'sResources.resw)Detailed Description of the Pull Request / Additional comments
The card
SystemBatteryTemplate.jsonis rewritten withChart.Gauge(layer 10), andBadgeand rounded, borderedContainertiles (layer 3). The gauge falls back to the charge as large text, and the badge to the status as bold text.SystemBatteryUsageWidgetPagefills it:batteryPercent: the charge as a number for the gauge, or 0 when it's unknown or there's no battery.batteryStatusStyle: the badge's style:goodwhile charging,informativewhen plugged in, andaccenton battery power.batteryIcon:BatteryChargewhile charging, otherwiseBattery0toBattery10by charge (GetChargeIconName). An unknown charge has no icon.batteryColor:goodwhile charging or above 50%, thenwarningabove 20%, thenattention, oraccentwhen the charge is unknown (GetChargeColor). This card's gauge takes its colors from its segments; the Overview card in layer 12 usesbatteryColor.batteryRateLabelandbatteryRate:Charge rateorDischarge rate, in watts, such as9.6 W(GetDisplayedRate).batteryHealth: the full charge capacity as a percentage of the design capacity, at most 100%.batteryFullCapacity: the full charge capacity, such as86.3 Wh. The page also setsbatteryDesignCapacity, as CmdPal: Native Adaptive Cards charts and redesigned Performance Monitor cards #51125 does, though no template uses it.The
Statuslabel goes, since the badge shows the status.Battery report
BatteryStats.ReadReport(new) reads the charge rate, design capacity, and full charge capacity fromBattery.AggregateBattery.GetReport()(Windows.Devices.Power), which combines all of the device's batteries. The page reads it with each update, once a second while the Battery item, dock band, or card is showing, and only when there's a battery. If it throws, the three values are null and their tiles are hidden. The charge, status, and time remaining still come fromGetSystemPowerStatus, as onmain.Charge and discharge rates
The report's rate is positive while charging and negative while discharging. Plugged in with a full battery, the battery is idle, and small readings in either direction come and go. So
GetDisplayedRateshows a rate only while charging (a positive rate) or on battery power (a negative rate). A reading that disagrees with the charging state, a zero, or no reading isn't shown.Strings
4 new
Battery_Widget_Template/*strings in the extension'sResources.resw, each with a comment for translators:Charge rate,Discharge rate,Health, andFull charge capacity.Screenshots
The screenshots come from a local card harness (not in the repo). It renders the real template through
IncrementalAdaptiveCardUpdater, with the polyfills registered,main's host config, and the realCardOverrideStylesfromContentFormControl.xaml. The cards are 776 px wide. #51205's host config isn't part of this stack, so padding and spacing aremain's.main's card ismain's template, which this branch's base still has, rendered with the same live data; the page sets the three values it uses asmaindoes.The test machine, a Surface, was plugged in and fully charged. The sample states render the real template with data built the way
SystemBatteryUsageWidgetPagebuilds it, with itsGetChargeColor,GetChargeIconName, andGetDisplayedRate, and this machine's capacities. Their charge levels, rates, and times remaining are made up.Validation Steps Performed
Validated on layer 10's head (
b69e2cc134, with layer 9's two fixes).The 2 files taken whole are identical to their versions at #51125's head (
8858a9e0a7):BatteryStats.csandSystemBatteryTemplate.json. So areSystemBatteryUsageWidgetPage, the 4 strings, and the 3 tests inCardFormattingTests.cs. Other files differ from #51125 only where other PRs change them: the Overview card's code, strings, and test (layer 12), and layer 9's decimal bit rates.ARM64 Debug builds, run from a
substdrive (common build options:-nologo -m -restore -t:Build -v:minimal -p:Configuration=Debug -p:Platform=ARM64 -p:RuntimeIdentifier=win-arm64 -p:CIBuild=false -p:GeneratePackageLocally=false -p:GenerateAppxPackageOnBuild=false -p:PublishAppxPackage=false -p:SkipLongPathsCheck=true):MSBuild.exe src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.PerformanceMonitor\Microsoft.CmdPal.Ext.PerformanceMonitor.csproj <options>, with-t:Rebuild: exit code 0. The only warning isLNK4075from the nativeMicrosoft.CommandPalette.Extensions.vcxprojdependency. The extension importsCommon.Dotnet.AotCompatibility.props, so the trim and AOT analyzers run over the new code.MSBuild.exe src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests.csproj <options>: exit code 0, no warnings from the extension or its tests.vstest.console.arm64.exe ARM64\Debug\WinUI3Apps\CmdPal\tests\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests.dll /Platform:ARM64: 173 passed, 0 failed. 3 are new, inCardFormattingTests.cs:ChargeColorReflectsTheChargeLevel.ChargeIconReflectsTheChargeLevel.RateIsShownOnlyWhileChargingOrOnBattery: charging, on battery, plugged in and idle in both directions, readings that disagree with the state, no reading, and zero.Card harness under JIT, dark and light:
The Battery card for 8 seconds: no parse warnings or missing strings, and it renders as shown. All 12 updates patched the card in place; none replaced it.
Every card this branch has, for 8 seconds: CPU, Memory, GPU, Disk, Network, Battery, the gauges card, and the
Iconfallback card. No strings are missing. The only parse warnings are for the fallback card'sBoticon, which has no glyph on purpose. No update replaced the Memory, GPU, Disk, Network, Battery, gauges, or fallback card. The CPU card was replaced once in each theme, when its top processes and per-core chart first appeared.A simulated Aquatic contrast theme: the card takes the contrast colors, and the gauge draws its segments full width with a needle.
The values match Windows. A script polled
GetSystemPowerStatus(through .NET'sSystemInformation.PowerStatus), the aggregate battery report, and WMI'sBatteryStatusonce a second while the harness ran. This table compares the card's capture at 12:18:47 with the script's reading in the same second:GetSystemPowerStatus: 100%Idle, 0 mW. WMI: charge and discharge rates 0powercfg /batteryreport: 86,340 mWhSettings > System > Power & battery said "Your battery is fully charged. The remaining battery life is 100%" at 12:20:58, and the card showed 100% at 12:21:01. Settings doesn't show a health percentage on this build. The card truncates percentages, as the other cards do (
FloatToPercentString), so 96.7% shows as 96%.Not run: a native AOT publish of the harness; the extension's trim and AOT analyzers pass. The charge and discharge rates weren't seen live, since the machine stayed plugged in and full; the unit tests and the sample states cover them.