Skip to content

Releases: keyokku/SurfaceChargingTray

v1.4.3

28 May 00:37

Choose a tag to compare

Maintenance release on top of v1.4.2.

Low-battery warning failsafe

The configurable low-battery warning added in v1.4.2 only fired while Windows reported the device as on battery. In the rare USB-C Power-Delivery failure mode where the Surface firmware gets stuck in a battery-as-power state while still reporting PowerLineStatus.Online, the warning stayed silent even as the battery drained to zero.

In v1.4.3 the warning fires purely on percentage and the existing watch-zone / once-per-cycle guard, regardless of plug-state. The toast wording adapts:

  • On battery: same as before — "Battery is at X%. Consider plugging in."
  • AC reported but battery still dropping: "Battery is at X% even though Windows reports AC connected. Charging may not be working — try unplugging and replugging the cable." (The cable replug is a useful first step because that's the visible signature of a PD-negotiation failure.)

Original on-battery behavior is preserved exactly. No new settings, no new UI; this is a trigger-condition fix only.

All v1.4.2 features (multi-slot scheduler, battery health, tray badge, update checker, calibration reminder, error-log viewer, export/import settings, multi-monitor sleep-dismiss fix) carry forward unchanged.

Downloads

Package For
SurfaceChargingTray-v1.4.3-arm64.zip Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
SurfaceChargingTray-v1.4.3-x64.zip Intel-based Surfaces (most common). Also runs on Snapdragon via Prism emulation.
SurfaceChargingTrayDiagnostic.zip Optional diagnostic tool — both arch exes inside, run if your device isn't detected.

Backward-compatible with all v1.3.x and v1.4.x settings.

v1.4.2 — configurable low-battery warning

25 May 23:50

Choose a tag to compare

Adds a user-configurable low-battery warning. Everything from v1.4.1 (and the v1.4.0 feature set) carried forward unchanged.

Low-battery warning

  • Settings → General: "Warn when battery drops to [10 / 15 / 20 / 25 / 30]%" + enable toggle. Default 20%, on.
  • Fires a toast ("Battery is at X%. Consider plugging in.") when battery reaches your threshold while on battery. Once per discharge cycle — resets when you plug in or climb back above the threshold.
  • Independent of Windows' own low-battery notification (which defaults to ~10%), so you get a reliable alert at the level you choose.
  • Adaptive polling: normally rides the existing 5-min timer (no new continuous polling); ramps to a 60-second poll only when near the threshold, then stands down. Reading battery status is an OS-cached value, so the power cost is negligible.

Also in the v1.4.x line

  • Multi-slot scheduler (up to 3 timed changes, 3-option auto-exit)
  • Battery health in the tray menu
  • Color-coded tray mode badge + Power-mode tooltip line
  • Update checker, battery calibration reminder, error-log viewer, export/import settings
  • Multi-monitor simulated-sleep dismiss fix (from v1.4.1)

Downloads

File For
SurfaceChargingTray-v1.4.2-arm64.zip Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
SurfaceChargingTray-v1.4.2-x64.zip Intel Surfaces (also Snapdragon via Prism)
SurfaceChargingTrayDiagnostic.zip Diagnostic tool

Requires .NET 8 Desktop Runtime. Drop-in replacement for v1.3.x / v1.4.x — settings carry over.

See CHANGELOG.md for full detail.

v1.4.1 — multi-monitor simulated-sleep fix (+ all v1.4.0 features)

24 May 02:56

Choose a tag to compare

If you're on v1.4.0, upgrade to this. Same feature set as v1.4.0 plus a critical multi-monitor fix.

Bug fix — multi-monitor simulated-sleep dismiss

On systems with 2 or more monitors, the per-monitor black overlays fought each other for foreground in an infinite focus-war that saturated the UI thread — the overlays became unresponsive to clicks/keys, and the only escape was alt-tab + manually closing the windows (which also left brightness/power-mode unrestored).

  • "Stay on top" now only reasserts when focus left all of our overlays — they no longer fight each other. Click/key dismiss works on any number of monitors.
  • Closing an overlay externally (alt-F4 / taskbar) now properly restores brightness, Windows Power mode, and the wake-lock.

Single-monitor users were unaffected (one overlay, no war) — which is why earlier overnight runs worked.

Features (from v1.4.0)

  • Multi-slot scheduler — up to 3 timed charging-mode changes in one simulated-sleep run, with a 3-option auto-exit (Stay / after first / after all)
  • Battery health in the tray menu (retention %, cycles, capacity; click to refresh)
  • Color-coded tray badge — green = Adaptive/Smart, blue = 80%, orange = 100%
  • Tray tooltip shows the current Windows Power mode
  • Update checker (24h-throttled), battery calibration reminder (30-day), error-log viewer in Show-last-error, and export/import settings
  • Backward-compatible with v1.3.x settings

Downloads

File For
SurfaceChargingTray-v1.4.1-arm64.zip Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
SurfaceChargingTray-v1.4.1-x64.zip Intel Surfaces (also Snapdragon via Prism)
SurfaceChargingTrayDiagnostic.zip Diagnostic tool

Requires .NET 8 Desktop Runtime. Drop-in replacement for v1.3.x / v1.4.0 — settings carry over.

See CHANGELOG.md for full detail.

v1.4.0 — multi-slot scheduler, battery health, tray badge & more

21 May 18:57

Choose a tag to compare

⚠️ SUPERSEDED — do not use this release

v1.4.0 has a multi-monitor bug: the simulated-sleep black overlay can become unresponsive to clicks/keys on systems with 2+ monitors. Fixed in v1.4.1 — please download that instead. The download files on this release have been removed.


Feature release. No changes to variant detection or charging-mode mechanisms — fully backward-compatible with v1.3.x settings.

Multi-slot scheduler

Schedule up to 3 timed charging-mode changes in a single simulated-sleep run — e.g. flip to 100% at 06:00 and back to 80% at 09:00.

  • Settings → Schedule: dynamic slot rows with + Add schedule (capped at 3) and per-row Remove
  • New 3-option auto-exit: Stay / Exit after the first change / Exit only after all changes
  • Existing single-slot schedules migrate automatically

Battery health

  • New Battery health tray-menu item: retention %, cycle count, full capacity detail on hover (click to refresh)
  • Tooltip notes the value is a fluctuating fuel-gauge estimate — watch the trend, not a single reading

Tray icon mode badge

  • Small color-coded corner badge on the tray icon: green = Adaptive/Smart Charging, blue = Limit to 80%, orange = Charge to 100%

Tray tooltip

  • Hover now shows the current Windows Power mode on a second line

Update checker

  • Launch-time check (throttled to once/24h) against GitHub Releases; balloon if a newer version is available. Silent on failure, no auto-install.

Battery calibration reminder

  • One-time midday reminder if the battery hasn't reached 100% in 30 days (common on Smart-Charging-80%), suggesting a full cycle to keep the fuel gauge accurate

Error dialog improvements

  • "Show last error" now includes a scrollable view of recent log entries, Copy log to clipboard and Open GitHub issues links, in a larger resizable dialog

Settings export / import

  • Export settings / Import settings links in the Settings dialog (export is timestamped; import backs up your current settings first)

Downloads

File For
SurfaceChargingTray-v1.4.0-arm64.zip Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
SurfaceChargingTray-v1.4.0-x64.zip Intel Surfaces (also Snapdragon via Prism)
SurfaceChargingTrayDiagnostic.zip Diagnostic tool

Requires .NET 8 Desktop Runtime. Drop-in replacement for v1.3.x — settings carry over.

See CHANGELOG.md for full detail.

v1.3.1 — fake-sleep safety watchdogs + Settings dark-mode polish

17 May 05:08

Choose a tag to compare

Safety + polish release on top of v1.3.0. No functional regressions — same variant detection and scheduler behavior as v1.3.0, with hardening against a specific overnight-drain failure mode and a thorough dark-mode pass on the Settings dialog.

Fake-sleep safety watchdogs

After an incident where USB-C Power Delivery silently failed mid-night on a Surface Pro 12 — adapter stopped delivering power while Windows still reported "AC plugged in" — the device drained overnight to a hard shutdown. v1.3.1 adds four guards that run on a single 60-second timer only while simulated sleep is active. They can't prevent the underlying firmware/PD failure (Windows/Surface side, we're a user-mode app) but they bound the damage: any sustained "supposedly plugged in but battery dropping" condition force-exits simulated sleep within minutes, letting Windows enter real Modern Standby which often resets the stuck PD state.

Guard Trigger
AC-health Battery dropping ≥3% over 10 min with 3+ consistent samples while plugged in. Tiered: only active below 80% (Smart-Charging-80% will legitimately discharge from 100% down to the cap).
AC-disconnect PowerLineStatus.Offline mid-run.
Low-battery floor Battery ≤30%.
Hard duration cap Simulated sleep running >23 hours.

When any guard fires, the user gets a balloon notification explaining why and the reason is logged to surface-error.log. Zero impact on variant A users who don't use the scheduler — the watchdog timer only exists while fake-sleep is active.

Settings dialog dark-mode pass

The Settings dialog had partial dark-mode coverage in v1.3.0 — main background was dark but TabControl chrome, ComboBox dropdown buttons, scrollbars, and CheckBox/RadioButton glyphs still rendered as system-light. v1.3.1 does a thorough pass:

  • DarkTabControl subclass replaces plain TabControl when dark mode is active. Suppresses WM_ERASEBKGND, fills client area dark in OnPaint, owner-draws tabs, renders a subtle #555 border around the content area.
  • ComboBox arrow chrome dark via SetWindowTheme(..., "DarkMode_CFD"). Switched from FlatStyle.Flat to FlatStyle.Standard so the native theme takes effect.
  • ComboBox dropdown list scrollbars dark via hook on DropDown event.
  • Scrollable panels dark via SetWindowTheme(..., "DarkMode_Explorer").
  • CheckBox + RadioButton glyphs dark via the same theme.
  • Tab handle forcing so themes apply to inactive tabs at first paint.

All dark-mode code paths early-return when DarkMode.IsAppsDarkMode() is false — light mode is entirely untouched.

Minor

  • Tab renamed: "Hotkeys" → "General" (the tab has more than just hotkeys: run-at-login toggle, variant banner with Re-detect button, plus the hotkey grid).
  • Re-detect button taller (40px instead of 32) so the text descender doesn't clip at high DPI.

Downloads

File For
SurfaceChargingTray-v1.3.1-arm64.zip Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
SurfaceChargingTray-v1.3.1-x64.zip Intel Surfaces (also Snapdragon via Prism)
SurfaceChargingTrayDiagnostic.zip Diagnostic tool with v1.3.0 variant report

Requires .NET 8 Desktop Runtime. Drop-in replacement for v1.3.0 — settings.ini unchanged.

See CHANGELOG.md for full detail.

v1.3.0 — auto-detects two Surface UI variants

16 May 05:37

Choose a tag to compare

Auto-detects two distinct Surface app UI shapes and shapes the entire tray menu, hotkeys, and scheduler around what your device actually supports.

Backward compatibility

  • Three-mode UI users (variant A) — most modern Surfaces (Pro 9/10/11/12, Laptop 5/6/7, Laptop Studio 2): zero UX change from v1.2.2. First refresh after upgrade detects + caches variant A; all menus, hotkeys, and scheduler behavior identical.
  • Single-button override UI users (variant B) — older Surfaces (Laptop Studio 1, Pro 7, and similar): now supported. Tray menu reshapes to a single Charge to 100% override action with live state tracking (greyed when not currently available, enabled when Smart Charging is actively limiting your battery).
  • Existing settings.ini files are forward-compatible.

New for variant B

  • Tray menu: single Charge to 100% override item, greyed when not actionable. Hover shows the reason.
  • Tray icon hover tooltip: Surface Charging: Smart (Smart Charging limiting) / Surface Charging: To 100% (override active or already at 100%).
  • Scheduler: same simulated-sleep engine variant A uses, with a Charge to 100% (one-shot) target action.
  • New oneshot hotkey slot (default Ctrl+Shift+1) registered automatically when device is detected as variant B.
  • Live state tracking: app uses cheap Win32 power signals (AC/DC, battery %) to keep the menu item synchronized without polling the Surface app on a timer — only probes at meaningful battery / power transitions.

Diagnostic tool

  • SurfaceChargingTrayDiagnostic.zip updated to include a Detected variant: A | B | Unknown line in its report.

Downloads

File For
SurfaceChargingTray-v1.3.0-arm64.zip Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
SurfaceChargingTray-v1.3.0-x64.zip Intel Surfaces (also Snapdragon via Prism)
SurfaceChargingTrayDiagnostic.zip Diagnostic tool with v1.3.0 variant report

Requires .NET 8 Desktop Runtime.

See CHANGELOG.md for full detail.

v1.3.0-beta1 — older Surface UI test build

14 May 05:36

Choose a tag to compare

Beta release for users whose Surface app shows only a 'Charge to 100%' override button (no Adaptive / 80% / 100% radios). Typically older Surface Laptop Studio gen 1 and similar devices where Smart Charging is managed implicitly.

image

Regular users on Pro 9/10/11/12, Laptop 5/6/7, etc.: stay on v1.2.2. v1.3.0 is not promoted to stable until variant B testers confirm the new path works on real hardware.

What's new

v1.3.0 auto-detects whether your Surface has the three-radio classic UI (variant A) or the single-button override UI (variant B), then reshapes the entire tray menu, settings dialog, hotkeys, and scheduler around what your device actually supports. Variant A behavior is preserved exactly from v1.2.2.

See CHANGELOG.md for full detail.

Variant B testers

If your Surface app shows only the one-shot override (you previously reported this on issue #2), please download, install, and let us know:

  • Does the tray menu show only Charge to 100% as the charging action?
  • Does clicking it work, and the menu item disable itself after?
  • Can the scheduler fire a 100% override at a chosen time overnight (with simulated sleep)?

Report results on issue #2.

Downloads

File For
`SurfaceChargingTray-v1.3.0-beta1-arm64.zip` Snapdragon Surfaces (Pro X / 11 / 12, Laptop 7 Snapdragon)
`SurfaceChargingTray-v1.3.0-beta1-x64.zip` Intel Surfaces (also Snapdragon via Prism)
`SurfaceChargingTrayDiagnostic.zip` Updated diagnostic with v1.3.0 variant report

Requires .NET 8 Desktop Runtime.

v1.2.2 — Diagnostic tool + better error-state guidance

12 May 13:41

Choose a tag to compare

Patch on top of v1.2.1. Same feature set; fully backward-compatible with v1.2.x settings. Targeted at users whose Surface model isn't detected by the main app — gives them a one-click path to send the developer the info needed to add support in a future update.

New: standalone diagnostic tool

SurfaceChargingTrayDiagnostic.zip is attached to this release as a separate download. It's a small standalone tool that:

  • Launches the Surface app if it isn't already running
  • Captures a PrintWindow screenshot of the Surface app's window
  • Walks the full UIA tree (unlimited depth, 1500-element cap, 30s budget) with each element's control type, name, AutomationId, supported patterns, enabled / offscreen state
  • Collects system fingerprint: Windows version + locale, device model, CPU, .NET version, battery state
  • Writes a .txt + .png next to the .exe

Users post both files as a comment on the diagnostic-results thread (issue #2) so I can support their Surface model in a future update.

The diagnostic zip bundles both arm64 and x64 .exes flat plus a small README.txt. The download is versionless on purpose — the same zip is reusable across future releases without modification.

Main app

  • Custom error dialog replaces the plain MessageBox when Show last error surfaces a detection-failure ("card not found", "appear selected"). The new dialog explains what happened and offers two clickable buttons: Download diagnostic tool (deep-links to the latest Release) and Open GitHub thread (deep-links to issues/2). Non-detection errors still get the simple display.
  • Added German locale variant "Akku und Laden" to the Battery & charging name list (observed on Surface Laptop Studio 1's Surface app build).
  • UIA tree snapshot in surface-error.log now goes 5 levels deep and captures up to 120 elements (was 3 / 60). Surface app cards live at depth ~4-5; the previous limit cut off exactly where the useful info began.

Compatibility

Same OS / device requirements as v1.2.1. .NET 8 Desktop Runtime required.

Download

  • SurfaceChargingTray-v1.2.2-arm64.zip — Snapdragon Surfaces
  • SurfaceChargingTray-v1.2.2-x64.zip — Intel-based Surfaces (also works on Snapdragon via Prism emulation)
  • SurfaceChargingTrayDiagnostic.zip — only needed if your Surface model isn't detected and you'd like to help me support it

Full notes: CHANGELOG.md

v1.2.1 — Detection-and-discovery hardening

12 May 06:15

Choose a tag to compare

Patch on top of v1.2.0. Same feature set (charging-mode scheduler via simulated sleep); fully backward-compatible with v1.2.0 settings. Targeted at users whose Surface device / locale / Surface app build wasn't recognized by the v1.2.0 baseline.

Detection hardening

  • More lenient structural search for the Battery & charging card. Used to require exactly a Group with 3+ RadioButton descendants. Now tries: 3+ radios → 2+ radios → any element whose AutomationId contains Battery / Charging / ChargeMode → walk-up from any RadioButton whose Name matches a known charging mode.
  • Multi-pattern selection detection. When reading which mode is currently active, the tool now tries SelectionItemPattern.IsSelected (canonical) and then TogglePattern.ToggleState == On. Fixes the "None of the three radios appear selected" error on Surface app builds that use toggle-buttons.
  • Cache-poisoning recovery. If a cached card leads to "radio not found" or "no selection" downstream, the tool clears the cache, forces fresh discovery, and retries once. Recovers from a wrong-card cache without needing to delete settings.ini.
  • More multi-language Names for the Battery card (newer Microsoft terminology: Smart charging, Charging mode, Battery Smart Charging) plus more locale entries.
  • Multi-language window title when finding the Surface app process on launch (de-DE, ru-RU, tr-TR, ja-katakana, zh-literal, ko-KR, ar, etc.). Was previously hardcoded English-only.
  • Multi-language DisplayName in the package-discovery scan. Was previously English-only.

Diagnostics

  • UIA tree snapshot is now written to surface-error.log when the "card not found" or "no radio selected" errors fire. Captures the top 3 levels of the Surface app's UI tree (up to 60 elements) with each element's ControlType, Name, and AutomationId. Makes future bug reports actionable.

WMI brightness

  • SetBrightness now snaps requested values to the closest level the display driver advertises via WmiMonitorBrightness.Levels. Behavior unchanged on Surface built-in displays; fixes a latent issue on certain external monitors / non-Surface laptops.

Download

  • SurfaceChargingTray-v1.2.1-arm64.zip — Snapdragon Surfaces
  • SurfaceChargingTray-v1.2.1-x64.zip — Intel-based Surfaces (also works on Snapdragon via Prism emulation)

Requires .NET 8 Desktop Runtime (Windows offers a direct download link on first launch if missing).

Full notes: CHANGELOG.md

v1.2.0 — Charging-mode scheduler (simulated sleep)

11 May 15:13

Choose a tag to compare

Schedule a charging-mode switch overnight on its own — no Windows Task Scheduler, no waking the device.

No AHK package this release. The .exe builds are the only distribution from v1.2.0 onward. Existing AHK users can continue running v1.1.1 indefinitely. See the v1.1.1 release notes for context.

What's new

  • Charging-mode scheduler with a "simulated sleep" mechanic. Press a hotkey before bed; the tool covers every monitor with a black overlay, drops brightness to 0, sets Windows Power mode to Best efficiency, and holds SetThreadExecutionState(SYSTEM | DISPLAY) so Windows treats the device as awake (without permanently editing your Sleep / Screen-off timeouts). At your scheduled time, the Surface app's charging mode flips in the background while the overlay stays up. Full why-and-how in the README.
  • After-fire options: Stay in simulated sleep (overlay stays until you press a key) or Exit and allow real sleep timeouts (overlay tears down, brightness restores, Windows' actual Sleep / Screen-off timers fire — the device falls into real sleep on its own).
  • Settings dialog Schedule tab with mode dropdown, duration (for 100%), hour/minute dropdowns (no free-text — can't enter an invalid time), Clear link, after-fire radio buttons, dedicated schedule-toggle hotkey row. Inline red-text validation; Save disables when time is incomplete.
  • Tray menu gets a Schedule item showing the saved schedule (e.g. Schedule: 05:30 — 100% 1d). Click it to jump straight to the Schedule tab.
  • Plugged-in guard. Refuses to enter simulated sleep on battery. Modal warning dialog rather than a balloon-tip, so Focus Assist / DnD can't suppress it.
  • Crash recovery. Brightness and Power-mode originals persist to a recovery file before mutation; if the tray crashes mid-simulated-sleep, the next launch silently restores them.
  • Run at Windows login moved into Settings (out of tray menu).

Distribution change

Switched from self-contained (~70 MB) to framework-dependent single-file (~25 MB on disk, ~6 MB zipped). Requires .NET 8 Desktop Runtime — if you don't have it, Windows pops up a dialog with a direct download link on first launch. Many modern Windows apps (PowerToys, Files, Windows Terminal) already use .NET 8, so you may already have it.

Compatibility

  • Windows 10 build 19041 (May 2020) or newer
  • Surface device with the modern Battery & charging UI (Pro 8 / Laptop 5 onward)
  • Plugged in required for the scheduler (refuses on battery)

Download

  • SurfaceChargingTray-v1.2.0-arm64.zip — Snapdragon Surfaces (Pro 12, Pro X, Pro 11 / Laptop 7 Snapdragon)
  • SurfaceChargingTray-v1.2.0-x64.zip — Intel-based Surfaces (also works on Snapdragon via Prism emulation)

Find your CPU: Settings → System → About → System type.

Full release notes: CHANGELOG.md