From 386f198622083f8b91753f3bcce75c631c3701b5 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 6 May 2026 18:12:01 -0700
Subject: [PATCH] Don't report 10% battery for Xbox controllers using XInput
---
src/joystick/windows/SDL_rawinputjoystick.c | 32 +++++++++++---------
src/joystick/windows/SDL_xinputjoystick.c | 33 ++++++++++++---------
2 files changed, 37 insertions(+), 28 deletions(-)
diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c
index c8cd9cd3a77b5..e67d9fd3e78cb 100644
--- a/src/joystick/windows/SDL_rawinputjoystick.c
+++ b/src/joystick/windows/SDL_rawinputjoystick.c
@@ -1976,20 +1976,24 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
state = SDL_POWERSTATE_ON_BATTERY;
break;
}
- switch (battery_info->BatteryLevel) {
- case BATTERY_LEVEL_EMPTY:
- percent = 10;
- break;
- case BATTERY_LEVEL_LOW:
- percent = 40;
- break;
- case BATTERY_LEVEL_MEDIUM:
- percent = 70;
- break;
- default:
- case BATTERY_LEVEL_FULL:
- percent = 100;
- break;
+ if (state == SDL_POWERSTATE_ON_BATTERY || SDL_POWERSTATE_CHARGING) {
+ switch (battery_info->BatteryLevel) {
+ case BATTERY_LEVEL_EMPTY:
+ percent = 10;
+ break;
+ case BATTERY_LEVEL_LOW:
+ percent = 40;
+ break;
+ case BATTERY_LEVEL_MEDIUM:
+ percent = 70;
+ break;
+ default:
+ case BATTERY_LEVEL_FULL:
+ percent = 100;
+ break;
+ }
+ } else {
+ percent = -1;
}
SDL_SendJoystickPowerInfo(joystick, state, percent);
}
diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c
index 8f26bcd7db25e..d7a132e1d15ca 100644
--- a/src/joystick/windows/SDL_xinputjoystick.c
+++ b/src/joystick/windows/SDL_xinputjoystick.c
@@ -300,20 +300,24 @@ static void UpdateXInputJoystickBatteryInformation(SDL_Joystick *joystick, XINPU
state = SDL_POWERSTATE_ON_BATTERY;
break;
}
- switch (pBatteryInformation->BatteryLevel) {
- case BATTERY_LEVEL_EMPTY:
- percent = 10;
- break;
- case BATTERY_LEVEL_LOW:
- percent = 40;
- break;
- case BATTERY_LEVEL_MEDIUM:
- percent = 70;
- break;
- default:
- case BATTERY_LEVEL_FULL:
- percent = 100;
- break;
+ if (state == SDL_POWERSTATE_ON_BATTERY || state == SDL_POWERSTATE_CHARGING) {
+ switch (pBatteryInformation->BatteryLevel) {
+ case BATTERY_LEVEL_EMPTY:
+ percent = 10;
+ break;
+ case BATTERY_LEVEL_LOW:
+ percent = 40;
+ break;
+ case BATTERY_LEVEL_MEDIUM:
+ percent = 70;
+ break;
+ default:
+ case BATTERY_LEVEL_FULL:
+ percent = 100;
+ break;
+ }
+ } else {
+ percent = -1;
}
SDL_SendJoystickPowerInfo(joystick, state, percent);
}
@@ -391,6 +395,7 @@ void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick)
return;
}
+ // FIXME: This does end up making a device ioctl() to query data, we shouldn't do this every update.
SDL_zero(XBatteryInformation);
if (XINPUTGETBATTERYINFORMATION) {
result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation);