BatteryManager: removed due to limited compatibility.

Might be reintroduced later if we decice on a proper back-end.
This commit is contained in:
ItsLemmy
2025-11-16 17:27:11 -05:00
parent d8adaf4d4b
commit 39fd2517c3
24 changed files with 0 additions and 978 deletions
-20
View File
@@ -363,13 +363,6 @@
"health": "Zustand: {percent}%",
"idle": "Leerlauf.",
"no-battery-detected": "Keine Batterie erkannt.",
"panel": {
"balanced": "Ausgeglichen ({percent}%)",
"disabled": "Batteriemanager deaktiviert",
"full": "Volle Kapazität ({percent}%)",
"lifespan": "Verlängerte Lebensdauer ({percent}%)",
"title": "Ladeschwelle"
},
"plugged-in": "Angeschlossen.",
"time-left": "Verbleibende Zeit: {time}.",
"time-until-full": "Zeit bis vollständig geladen: {time}."
@@ -1870,19 +1863,6 @@
"low": "Niedriger Batteriestand",
"low-desc": "Batterie ist bei {percent}%. Bitte schließen Sie das Ladegerät an."
},
"battery-manager": {
"initial-setup": "Ersteinrichtung erforderlich",
"install-failed": "Installation fehlgeschlagen",
"install-missing": "Erforderliche Dateien fehlen",
"install-success": "Erfolgreich installiert",
"install-unsupported": "System wird nicht unterstützt",
"set-failed": "Fehler beim Setzen der Batterieschwelle",
"set-success-desc": "Batterieschwelle auf {percent}% gesetzt",
"title": "Batterieschwelle",
"uninstall-failed": "Deinstallation fehlgeschlagen",
"uninstall-setup": "Deinstallation, Authentifizierung erforderlich",
"uninstall-success": "Erfolgreich deinstalliert"
},
"bluetooth": {
"disabled": "Deaktiviert",
"enabled": "Aktiviert"
-20
View File
@@ -363,13 +363,6 @@
"health": "Health: {percent}%",
"idle": "Idle.",
"no-battery-detected": "No battery detected.",
"panel": {
"balanced": "Balanced ({percent}%)",
"disabled": "Battery manager disabled",
"full": "Full capacity ({percent}%)",
"lifespan": "Extended lifespan ({percent}%)",
"title": "Charge threshold"
},
"plugged-in": "Plugged in.",
"time-left": "Time left: {time}.",
"time-until-full": "Time until full: {time}."
@@ -1870,19 +1863,6 @@
"low": "Low battery",
"low-desc": "Battery is at {percent}%. Please connect the charger."
},
"battery-manager": {
"initial-setup": "Initial setup required",
"install-failed": "Installation failed",
"install-missing": "Required files are missing",
"install-success": "Installed successfully",
"install-unsupported": "System is not supported",
"set-failed": "Failed to set battery threshold",
"set-success-desc": "Battery threshold set to {percent}%",
"title": "Battery threshold",
"uninstall-failed": "Uninstallation failed",
"uninstall-setup": "Uninstalling, authentication required",
"uninstall-success": "Uninstalled successfully"
},
"bluetooth": {
"disabled": "Disabled",
"enabled": "Enabled"
-20
View File
@@ -363,13 +363,6 @@
"health": "Salud: {percent}%",
"idle": "Inactivo.",
"no-battery-detected": "No se detectó ninguna batería.",
"panel": {
"balanced": "Equilibrado ({percent}%)",
"disabled": "Administrador de batería deshabilitado",
"full": "Capacidad total ({percent}%)",
"lifespan": "Vida útil prolongada ({percent}%)",
"title": "Umbral de carga"
},
"plugged-in": "Conectado.",
"time-left": "Tiempo restante: {time}.",
"time-until-full": "Tiempo hasta carga completa: {time}."
@@ -1870,19 +1863,6 @@
"low": "Batería baja",
"low-desc": "La batería está al {percent}%. Por favor, conecta el cargador."
},
"battery-manager": {
"initial-setup": "Configuración inicial requerida",
"install-failed": "Error en la instalación",
"install-missing": "Faltan archivos requeridos",
"install-success": "Instalado correctamente",
"install-unsupported": "El sistema no es compatible",
"set-failed": "No se pudo establecer el umbral de batería",
"set-success-desc": "Umbral de batería establecido en {percent}%",
"title": "Umbral de batería",
"uninstall-failed": "Error en la desinstalación",
"uninstall-setup": "Desinstalando, se requiere autenticación",
"uninstall-success": "Desinstalado correctamente"
},
"bluetooth": {
"disabled": "Desactivado",
"enabled": "Activado"
-20
View File
@@ -363,13 +363,6 @@
"health": "État : {percent}%",
"idle": "Inactif.",
"no-battery-detected": "Aucune batterie détectée.",
"panel": {
"balanced": "Équilibré ({percent}%)",
"disabled": "Gestionnaire de batterie désactivé",
"full": "Capacité totale ({percent}%)",
"lifespan": "Durée de vie prolongée ({percent}%)",
"title": "Seuil de charge"
},
"plugged-in": "Branché.",
"time-left": "Temps restant : {time}.",
"time-until-full": "Temps jusqu'à charge complète : {time}."
@@ -1870,19 +1863,6 @@
"low": "Batterie faible",
"low-desc": "La batterie est à {percent}%. Veuillez brancher le chargeur."
},
"battery-manager": {
"initial-setup": "Configuration initiale requise",
"install-failed": "Échec de l'installation",
"install-missing": "Fichiers requis manquants",
"install-success": "Installation réussie",
"install-unsupported": "Système non pris en charge",
"set-failed": "Échec de la définition du seuil de batterie",
"set-success-desc": "Seuil de batterie défini à {percent}%",
"title": "Seuil de batterie",
"uninstall-failed": "Échec de la désinstallation",
"uninstall-setup": "Désinstallation, authentification requise",
"uninstall-success": "Désinstallation réussie"
},
"bluetooth": {
"disabled": "Désactivé",
"enabled": "Activé"
-20
View File
@@ -363,13 +363,6 @@
"health": "Gezondheid: {percent}%",
"idle": "In rust.",
"no-battery-detected": "Geen batterij gedetecteerd.",
"panel": {
"balanced": "Gebalanceerd ({percent}%)",
"disabled": "Batterijbeheer uitgeschakeld",
"full": "Volledige capaciteit ({percent}%)",
"lifespan": "Verlengde levensduur ({percent}%)",
"title": "Batterijdrempel"
},
"plugged-in": "Op netstroom.",
"time-left": "Resterende tijd: {time}.",
"time-until-full": "Tijd tot vol: {time}."
@@ -1870,19 +1863,6 @@
"low": "Batterij bijna leeg",
"low-desc": "De batterij is op {percent}%. Sluit de oplader aan."
},
"battery-manager": {
"initial-setup": "Initiële configuratie vereist",
"install-failed": "Installatie mislukt",
"install-missing": "Vereiste bestanden ontbreken",
"install-success": "Succesvol geïnstalleerd",
"install-unsupported": "Systeem wordt niet ondersteund",
"set-failed": "Instellen van batterijdrempel mislukt",
"set-success-desc": "Batterijdrempel ingesteld op {percent}%",
"title": "Batterijdrempel",
"uninstall-failed": "Deïnstallatie mislukt",
"uninstall-setup": "Verwijderen, authenticatie vereist",
"uninstall-success": "Succesvol verwijderd"
},
"bluetooth": {
"disabled": "Uitgeschakeld",
"enabled": "Ingeschakeld"
-20
View File
@@ -363,13 +363,6 @@
"health": "Saúde: {percent}%",
"idle": "Ocioso.",
"no-battery-detected": "Nenhuma bateria detectada.",
"panel": {
"balanced": "Balanceado ({percent}%)",
"disabled": "Gerenciador de bateria desativado",
"full": "Capacidade máxima ({percent}%)",
"lifespan": "Vida útil prolongada ({percent}%)",
"title": "Limite de carga"
},
"plugged-in": "Conectado.",
"time-left": "Tempo restante: {time}.",
"time-until-full": "Tempo até carga completa: {time}."
@@ -1870,19 +1863,6 @@
"low": "Bateria Fraca",
"low-desc": "A bateria está em {percent}%. Por favor, conecte o carregador."
},
"battery-manager": {
"initial-setup": "Configuração inicial necessária",
"install-failed": "Falha na instalação",
"install-missing": "Arquivos necessários ausentes",
"install-success": "Instalado com sucesso",
"install-unsupported": "Sistema não suportado",
"set-failed": "Falha ao definir o limite da bateria",
"set-success-desc": "Limite da bateria definido para {percent}%",
"title": "Limite da bateria",
"uninstall-failed": "Falha na desinstalação",
"uninstall-setup": "Desinstalando, autenticação necessária",
"uninstall-success": "Desinstalado com sucesso"
},
"bluetooth": {
"disabled": "Desativado",
"enabled": "Ativado"
-20
View File
@@ -363,13 +363,6 @@
"health": "Здоровье: {percent}%",
"idle": "Простой.",
"no-battery-detected": "Батарея не обнаружена.",
"panel": {
"balanced": "Сбалансированный ({percent}%)",
"disabled": "Диспетчер батареи отключен",
"full": "Полная емкость ({percent}%)",
"lifespan": "Увеличенный срок службы ({percent}%)",
"title": "Порог зарядки"
},
"plugged-in": "Подключено.",
"time-left": "Осталось времени: {time}.",
"time-until-full": "Время до полной зарядки: {time}."
@@ -1870,19 +1863,6 @@
"low": "Низкий заряд батареи",
"low-desc": "Заряд батареи {percent}%. Пожалуйста, подключите зарядное устройство."
},
"battery-manager": {
"initial-setup": "Требуется начальная настройка",
"install-failed": "Сбой установки",
"install-missing": "Отсутствуют необходимые файлы",
"install-success": "Успешно установлено",
"install-unsupported": "Система не поддерживается",
"set-failed": "Не удалось установить порог зарядки батареи",
"set-success-desc": "Порог зарядки батареи установлен на {percent}%",
"title": "Порог зарядки батареи",
"uninstall-failed": "Сбой удаления",
"uninstall-setup": "Удаление, требуется аутентификация",
"uninstall-success": "Успешно удалено"
},
"bluetooth": {
"disabled": "Отключен",
"enabled": "Включен"
-20
View File
@@ -363,13 +363,6 @@
"health": "Sağlık: {percent}%",
"idle": "Boşta.",
"no-battery-detected": "Pil tespit edilmedi.",
"panel": {
"balanced": "Dengeli ({percent}%)",
"disabled": "Pil yöneticisi devre dışı",
"full": "Tam kapasite ({percent}%)",
"lifespan": "Uzatılmış ömür ({percent}%)",
"title": "Şarj eşiği"
},
"plugged-in": "Prize takılı.",
"time-left": "Kalan süre: {time}.",
"time-until-full": "Dolma süresi: {time}."
@@ -1870,19 +1863,6 @@
"low": "Düşük batarya",
"low-desc": "Batarya % {percent}. Lütfen şarj bağlantısını yapın."
},
"battery-manager": {
"initial-setup": "Başlangıç kurulumu gerekli",
"install-failed": "Kurulum başarısız oldu",
"install-missing": "Gerekli dosyalar eksik",
"install-success": "Başarıyla kuruldu",
"install-unsupported": "Sistem desteklenmiyor",
"set-failed": "Batarya eşiği ayarlanamadı",
"set-success-desc": "Batarya eşiği % {percent} olarak ayarlandı",
"title": "Batarya eşiği",
"uninstall-failed": "Kaldırma başarısız oldu",
"uninstall-setup": "Kaldırılıyor, kimlik doğrulama gerekli",
"uninstall-success": "Başarıyla kaldırıldı"
},
"bluetooth": {
"disabled": "Devre dışı",
"enabled": "Etkin"
-20
View File
@@ -363,13 +363,6 @@
"health": "Здоров'я: {percent}%",
"idle": "Бездіяльність.",
"no-battery-detected": "Батарею не виявлено.",
"panel": {
"balanced": "Збалансований ({percent}%)",
"disabled": "Менеджер батареї вимкнено",
"full": "Повна ємність ({percent}%)",
"lifespan": "Подовжений термін служби ({percent}%)",
"title": "Поріг зарядки"
},
"plugged-in": "Підключено.",
"time-left": "Залишилось часу: {time}.",
"time-until-full": "Час до повного заряду: {time}."
@@ -1870,19 +1863,6 @@
"low": "Низький заряд батареї",
"low-desc": "Батарея на {percent}%. Будь ласка, підключіть зарядний пристрій."
},
"battery-manager": {
"initial-setup": "Потрібне початкове налаштування",
"install-failed": "Помилка встановлення",
"install-missing": "Необхідні файли відсутні",
"install-success": "Встановлено успішно",
"install-unsupported": "Система не підтримується",
"set-failed": "Не вдалося встановити поріг батареї",
"set-success-desc": "Поріг батареї встановлено на {percent}%",
"title": "Поріг батареї",
"uninstall-failed": "Помилка видалення",
"uninstall-setup": "Видалення, потрібна автентифікація",
"uninstall-success": "Видалено успішно"
},
"bluetooth": {
"disabled": "Вимкнено",
"enabled": "Увімкнено"
-20
View File
@@ -363,13 +363,6 @@
"health": "健康状况:{percent}%",
"idle": "空闲。",
"no-battery-detected": "未检测到电池。",
"panel": {
"balanced": "平衡 ({percent}%)",
"disabled": "电池管理器已禁用",
"full": "完全容量 ({percent}%)",
"lifespan": "延长寿命 ({percent}%)",
"title": "充电阈值"
},
"plugged-in": "已接通电源。",
"time-left": "剩余时间:{time}。",
"time-until-full": "充满所需时间:{time}。"
@@ -1870,19 +1863,6 @@
"low": "电量低",
"low-desc": "电量为 {percent}%。请连接充电器。"
},
"battery-manager": {
"initial-setup": "需要初始设置",
"install-failed": "安装失败",
"install-missing": "缺少必要文件",
"install-success": "安装成功",
"install-unsupported": "系统不受支持",
"set-failed": "设置电池阈值失败",
"set-success-desc": "电池阈值已设置为 {percent}%",
"title": "电池阈值",
"uninstall-failed": "卸载失败",
"uninstall-setup": "正在卸载,需要身份验证",
"uninstall-success": "卸载成功"
},
"bluetooth": {
"disabled": "已禁用",
"enabled": "已启用"
-5
View File
@@ -1,5 +0,0 @@
# Battery charge control paths
# Add one path per line
/sys/class/power_supply/BAT0/charge_control_end_threshold
/sys/class/power_supply/BAT1/charge_control_end_threshold
/sys/class/power_supply/BAT0/charge_stop_threshold
@@ -1,178 +0,0 @@
#!/usr/bin/env bash
set -e
SUCCESS=0
FAILURE=1
MISSING_FILES=2
UNSUPPORTED=3
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
print_error() {
echo -e "$1" >&2
}
print_info() {
echo -e "$1"
}
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run with root privileges"
exit $FAILURE
fi
print_info "Installing Battery Manager..."
echo
if [ -n "$PKEXEC_UID" ]; then
ACTUAL_USER=$(getent passwd "$PKEXEC_UID" | cut -d: -f1)
else
ACTUAL_USER="$SUDO_USER"
fi
if [ -z "$ACTUAL_USER" ]; then
print_error "Could not determine the actual user"
exit $FAILURE
fi
print_info "Installing for user: $ACTUAL_USER"
echo
print_info "Checking required files..."
MISSING_FILES_LIST=()
if [ ! -f "$SCRIPT_DIR/battery-paths.conf" ]; then
MISSING_FILES_LIST+=("battery-paths.conf")
fi
if [ ! -f "$SCRIPT_DIR/templates/battery-manager.sh" ]; then
MISSING_FILES_LIST+=("battery-manager.sh")
fi
if [ ! -f "$SCRIPT_DIR/templates/battery-manager.policy" ]; then
MISSING_FILES_LIST+=("battery-manager.policy")
fi
if [ ! -f "$SCRIPT_DIR/templates/battery-manager.rules" ]; then
MISSING_FILES_LIST+=("battery-manager.rules")
fi
if [ ${#MISSING_FILES_LIST[@]} -gt 0 ]; then
print_error "Missing required files in $SCRIPT_DIR:"
for file in "${MISSING_FILES_LIST[@]}"; do
print_error " - $file"
done
exit $MISSING_FILES
fi
print_info "All required files found"
print_info "Checking battery paths..."
BATTERY_PATHS=($(grep -v '^#' "$SCRIPT_DIR/battery-paths.conf" | grep -v '^$'))
EXISTING_PATHS=()
for path in "${BATTERY_PATHS[@]}"; do
if [ -f "$path" ]; then
EXISTING_PATHS+=("$path")
fi
done
if [ ${#EXISTING_PATHS[@]} -eq 0 ]; then
print_error "None of the battery control files exist. Please check your hardware compatibility."
exit $UNSUPPORTED
fi
print_info "Found ${#EXISTING_PATHS[@]} compatible battery control file(s)"
print_info "Installing battery manager script..."
BATTERY_MANAGER_SCRIPT="/usr/bin/battery-manager-$ACTUAL_USER"
SHEBANG=$(head -n 1 "$SCRIPT_DIR/templates/battery-manager.sh")
echo "$SHEBANG" > "$BATTERY_MANAGER_SCRIPT"
echo "" >> "$BATTERY_MANAGER_SCRIPT"
echo "BATTERY_PATHS=(" >> "$BATTERY_MANAGER_SCRIPT"
for path in "${EXISTING_PATHS[@]}"; do
echo " \"$path\"" >> "$BATTERY_MANAGER_SCRIPT"
done
echo ")" >> "$BATTERY_MANAGER_SCRIPT"
echo "" >> "$BATTERY_MANAGER_SCRIPT"
tail -n +2 "$SCRIPT_DIR/templates/battery-manager.sh" >> "$BATTERY_MANAGER_SCRIPT"
chmod +x "$BATTERY_MANAGER_SCRIPT"
print_info "Battery manager script created from $SCRIPT_DIR/templates/battery-manager.sh with compatible paths"
print_info "Script installed at $BATTERY_MANAGER_SCRIPT"
print_info "Creating log file..."
touch /var/log/battery-manager.log
chmod 644 /var/log/battery-manager.log
print_info "Log file created at /var/log/battery-manager.log"
print_info "Creating polkit policy..."
POLICY_FILE="/usr/share/polkit-1/actions/com.local.battery-manager.$ACTUAL_USER.policy"
sed -e "s/ACTUAL_USER_PLACEHOLDER/$ACTUAL_USER/g" \
"$SCRIPT_DIR/templates/battery-manager.policy" > "$POLICY_FILE"
print_info "Polkit policy copied from $SCRIPT_DIR/templates/battery-manager.policy"
print_info "Polkit policy created at $POLICY_FILE"
print_info "Creating polkit rule..."
RULES_FILE="/etc/polkit-1/rules.d/50-battery-manager-$ACTUAL_USER.rules"
sed "s/ACTUAL_USER_PLACEHOLDER/$ACTUAL_USER/g" \
"$SCRIPT_DIR/templates/battery-manager.rules" > "$RULES_FILE"
print_info "Polkit rule copied from $SCRIPT_DIR/templates/battery-manager.rules"
print_info "Polkit rule created for user: $ACTUAL_USER at $RULES_FILE"
print_info "Restarting polkit..."
if systemctl restart polkit 2>/dev/null; then
print_info "Polkit restarted"
else
print_info "Could not restart polkit automatically, you may need to reboot"
fi
print_info "Creating uninstall script..."
UNINSTALL_SCRIPT="$SCRIPT_DIR/uninstall-battery-manager.sh"
if [ -f "$SCRIPT_DIR/templates/uninstall-template" ]; then
SHEBANG=$(head -n 1 "$SCRIPT_DIR/templates/uninstall-template")
else
SHEBANG="#!/usr/bin/env bash"
fi
echo "$SHEBANG" > "$UNINSTALL_SCRIPT"
echo "" >> "$UNINSTALL_SCRIPT"
cat >> "$UNINSTALL_SCRIPT" << EOF
SCRIPT_PATH="$BATTERY_MANAGER_SCRIPT"
POLICY_PATH="$POLICY_FILE"
RULE_PATH="$RULES_FILE"
LOG_PATH="/var/log/battery-manager.log"
EOF
if [ -f "$SCRIPT_DIR/templates/uninstall-template" ]; then
tail -n +2 "$SCRIPT_DIR/templates/uninstall-template" >> "$UNINSTALL_SCRIPT"
fi
chmod 744 "$UNINSTALL_SCRIPT"
chown root:root "$UNINSTALL_SCRIPT"
print_info "Uninstall script created at $UNINSTALL_SCRIPT"
echo
print_info "Installation complete!"
echo
print_info "Log file: /var/log/battery-manager.log"
print_info "User-specific script: $BATTERY_MANAGER_SCRIPT"
print_info "User-specific policy: $POLICY_FILE"
print_info "User-specific rules: $RULES_FILE"
print_info "User-specific uninstall script: $UNINSTALL_SCRIPT"
@@ -1,86 +0,0 @@
#!/usr/bin/env bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SUPPRESS_NOTIFICATIONS=false
print_error() {
echo -e "$1" >&2
}
print_info() {
echo -e "$1"
}
send_notification() {
local urgency="$1"
local title="$2"
local message="$3"
if [ "$SUPPRESS_NOTIFICATIONS" = false ] && command -v notify-send >/dev/null 2>&1; then
notify-send -u "$urgency" "$title" "$message"
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
-q|--quiet)
SUPPRESS_NOTIFICATIONS=true
shift
;;
-*)
print_error "Unknown option: $1"
echo "Usage: $0 [OPTIONS] <number>" >&2
echo "Options:" >&2
echo " -q, --quiet Suppress notifications" >&2
exit 1
;;
*)
BATTERY_LEVEL="$1"
shift
;;
esac
done
if [ -z "$BATTERY_LEVEL" ]; then
print_error "Battery level not specified"
echo "Usage: $0 [OPTIONS] <number>" >&2
echo "Options:" >&2
echo " -q, --quiet Suppress notifications" >&2
exit 1
fi
if ! [[ "$BATTERY_LEVEL" =~ ^[0-9]+$ ]] || [ "$BATTERY_LEVEL" -gt 100 ] || [ "$BATTERY_LEVEL" -lt 0 ]; then
print_error "Battery level must be a number between 0-100"
echo "Usage: $0 [OPTIONS] <number>" >&2
echo "Options:" >&2
echo " -q, --quiet Suppress notifications" >&2
exit 1
fi
CURRENT_USER="$USER"
if [ -z "$CURRENT_USER" ]; then
CURRENT_USER="$(whoami)"
fi
BATTERY_MANAGER_PATH="/usr/bin/battery-manager-$CURRENT_USER"
SUCCESS=0
MISSING_FILES=2
if [ ! -f "$BATTERY_MANAGER_PATH" ]; then
print_error "Battery manager components missing for user $CURRENT_USER!"
exit $MISSING_FILES
fi
print_info "Setting battery charging threshold to $BATTERY_LEVEL% for user $CURRENT_USER..."
if pkexec "$BATTERY_MANAGER_PATH" "$BATTERY_LEVEL"; then
print_info "Battery charging threshold set to $BATTERY_LEVEL%"
send_notification "normal" "Battery Threshold Updated" \
"Battery charging threshold has been set to $BATTERY_LEVEL%"
else
print_error "Failed to set battery charging threshold"
send_notification "critical" "Battery Threshold Failed" \
"Failed to set battery charging threshold to $BATTERY_LEVEL%"
exit 1
fi
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="com.local.battery-manager.ACTUAL_USER_PLACEHOLDER">
<description>Manage battery settings for ACTUAL_USER_PLACEHOLDER</description>
<message>Authentication is required to manage battery settings</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/battery-manager-ACTUAL_USER_PLACEHOLDER</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
@@ -1,14 +0,0 @@
polkit.addRule(function(action, subject) {
if (action.id == "com.local.battery-manager.ACTUAL_USER_PLACEHOLDER" &&
subject.user == "ACTUAL_USER_PLACEHOLDER") {
// Check if the parent process is quickshell or set-battery-threshold
var pid = subject.pid;
var ppid = polkit.spawn(["ps", "-o", "ppid=", "-p", pid.toString()]).trim();
var parentCmd = polkit.spawn(["ps", "-o", "comm=", "-p", ppid]).trim();
if (parentCmd.indexOf("quickshell") !== -1 || parentCmd.indexOf("set-battery-treshold") !== -1) {
return polkit.Result.YES;
}
}
});
@@ -1,53 +0,0 @@
#!/usr/bin/env bash
LOG_FILE="/var/log/battery-manager.log"
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
if [ -z "$1" ]; then
echo "Error: No battery level provided" >&2
log_message "ERROR: No battery level provided"
exit 1
fi
BATTERY_LEVEL="$1"
if ! [[ "$BATTERY_LEVEL" =~ ^[0-9]+$ ]] || [ "$BATTERY_LEVEL" -gt 100 ] || [ "$BATTERY_LEVEL" -lt 0 ]; then
echo "Error: Invalid battery level. Must be 0-100" >&2
log_message "ERROR: Invalid battery level: $BATTERY_LEVEL"
exit 1
fi
SUCCESS_COUNT=0
FAIL_COUNT=0
for path in "${BATTERY_PATHS[@]}"; do
[[ -z "$path" || "$path" =~ ^# ]] && continue
if [ -f "$path" ] && [ -w "$path" ]; then
if echo "$BATTERY_LEVEL" > "$path" 2>/dev/null; then
echo "Updated: $path"
log_message "SUCCESS: Updated $path to $BATTERY_LEVEL"
((SUCCESS_COUNT++))
else
echo "Failed to write: $path" >&2
log_message "ERROR: Failed to write to $path"
((FAIL_COUNT++))
fi
else
echo "Skipped (not found/writable): $path"
log_message "INFO: Skipped $path (not found or not writable)"
fi
done
log_message "SUMMARY: Updated $SUCCESS_COUNT file(s), failed $FAIL_COUNT, battery level: $BATTERY_LEVEL"
if [ "$SUCCESS_COUNT" -eq 0 ]; then
echo "Error: No battery files were updated" >&2
exit 1
fi
echo "Successfully updated $SUCCESS_COUNT battery file(s)"
exit 0
@@ -1,30 +0,0 @@
#!/usr/bin/env bash
if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run as root"
exit 1
fi
echo "Uninstalling battery manager..."
if [ -f "$SCRIPT_PATH" ]; then
rm -f "$SCRIPT_PATH"
echo "Removed script from $SCRIPT_PATH"
fi
if [ -f "$POLICY_PATH" ]; then
rm -f "$POLICY_PATH"
echo "Removed policy file from $POLICY_PATH"
fi
if [ -f "$RULE_PATH" ]; then
rm -f "$RULE_PATH"
echo "Removed udev rule from $RULE_PATH"
fi
if [ -f "$LOG_PATH" ]; then
rm -f "$LOG_PATH"
echo "Removed log file from $LOG_PATH"
fi
echo "Uninstallation completed successfully"
-1
View File
@@ -95,7 +95,6 @@ Item {
autoHide: false
forceOpen: isReady && (testMode || battery.isLaptopBattery) && displayMode === "alwaysShow"
forceClose: displayMode === "alwaysHide" || !isReady || (!testMode && !battery.isLaptopBattery)
onClicked: PanelService.getPanel("batteryPanel", screen)?.toggle(this)
tooltipText: {
let lines = [];
if (testMode) {
@@ -71,13 +71,6 @@ Item {
backgroundColor: panelBackgroundColor
}
// Battery
PanelBackground {
panel: root.windowRoot.batteryPanelPlaceholder
shapeContainer: backgroundsShape
backgroundColor: panelBackgroundColor
}
// Bluetooth
PanelBackground {
panel: root.windowRoot.bluetoothPanelPlaceholder
-14
View File
@@ -10,7 +10,6 @@ import qs.Commons
import qs.Modules.Bar
import qs.Modules.Bar.Extras
import qs.Modules.Panels.Audio
import qs.Modules.Panels.Battery
import qs.Modules.Panels.Bluetooth
import qs.Modules.Panels.Calendar
import qs.Modules.Panels.ControlCenter
@@ -32,7 +31,6 @@ PanelWindow {
// Expose panels as readonly property aliases
readonly property alias audioPanel: audioPanel
readonly property alias batteryPanel: batteryPanel
readonly property alias bluetoothPanel: bluetoothPanel
readonly property alias calendarPanel: calendarPanel
readonly property alias controlCenterPanel: controlCenterPanel
@@ -47,7 +45,6 @@ PanelWindow {
// Expose panel placeholders for AllBackgrounds
readonly property var audioPanelPlaceholder: audioPanel.panelPlaceholder
readonly property var batteryPanelPlaceholder: batteryPanel.panelPlaceholder
readonly property var bluetoothPanelPlaceholder: bluetoothPanel.panelPlaceholder
readonly property var calendarPanelPlaceholder: calendarPanel.panelPlaceholder
readonly property var controlCenterPanelPlaceholder: controlCenterPanel.panelPlaceholder
@@ -170,17 +167,6 @@ PanelWindow {
}
}
BatteryPanel {
id: batteryPanel
screen: root.screen
z: 50
Component.onCompleted: {
objectName = "batteryPanel-" + (screen?.name || "unknown");
PanelService.registerPanel(batteryPanel);
}
}
BluetoothPanel {
id: bluetoothPanel
screen: root.screen
-157
View File
@@ -1,157 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import qs.Commons
import qs.Modules.MainScreen
import qs.Services.Hardware
import qs.Widgets
SmartPanel {
id: root
property var optionsModel: []
function updateOptionsModel() {
let newOptions = [
{
"id": BatteryService.ChargingMode.Full,
"label": "battery.panel.full"
},
{
"id": BatteryService.ChargingMode.Balanced,
"label": "battery.panel.balanced"
},
{
"id": BatteryService.ChargingMode.Lifespan,
"label": "battery.panel.lifespan"
}
];
root.optionsModel = newOptions;
}
onOpened: {
updateOptionsModel();
}
ButtonGroup {
id: batteryGroup
}
Component {
id: optionsComponent
ColumnLayout {
spacing: Style.marginM
Repeater {
model: root.optionsModel
delegate: NRadioButton {
ButtonGroup.group: batteryGroup
required property var modelData
text: I18n.tr(modelData.label, {
"percent": BatteryService.getThresholdValue(modelData.id)
})
checked: BatteryService.chargingMode === modelData.id
onClicked: {
BatteryService.setChargingMode(modelData.id);
}
Layout.fillWidth: true
}
}
}
}
Component {
id: disabledComponent
ColumnLayout {
anchors.centerIn: parent
spacing: Style.marginM
NIcon {
icon: "recharging"
pointSize: 48
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("battery.panel.disabled")
pointSize: Style.fontSizeL
color: Color.mOnSurfaceVariant
wrapMode: Text.WordWrap
Layout.alignment: Qt.AlignHCenter
}
}
}
panelContent: Item {
anchors.fill: parent
property real contentPreferredWidth: Math.round(340 * Style.uiScaleRatio)
property real contentPreferredHeight: Math.round(mainLayout.implicitHeight + Style.marginM * 2)
ColumnLayout {
id: mainLayout
anchors.centerIn: parent
width: parent.contentPreferredWidth - Style.marginM * 2
anchors.margins: Style.marginM
spacing: Style.marginM
// HEADER
NBox {
Layout.fillWidth: true
Layout.preferredHeight: header.implicitHeight + Style.marginM * 2
RowLayout {
id: header
anchors.fill: parent
anchors.margins: Style.marginM
spacing: Style.marginM
NIcon {
icon: "battery-4"
pointSize: Style.fontSizeXXL
color: Color.mPrimary
}
NText {
text: I18n.tr("battery.panel.title")
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.fillWidth: true
}
NToggle {
id: batteryManagerSwitch
checked: BatteryService.chargingMode !== BatteryService.ChargingMode.Disabled
onToggled: checked => BatteryService.toggleEnabled(checked)
baseSize: Style.baseWidgetSize * 0.65
}
NIconButton {
icon: "close"
tooltipText: I18n.tr("tooltips.close")
baseSize: Style.baseWidgetSize * 0.8
onClicked: {
root.close();
}
}
}
}
NBox {
Layout.fillWidth: true
Layout.preferredHeight: loader.implicitHeight + Style.marginM * 2
Loader {
id: loader
anchors.centerIn: parent
width: parent.width - Style.marginM * 2
sourceComponent: BatteryService.chargingMode === BatteryService.ChargingMode.Disabled ? disabledComponent : optionsComponent
}
}
}
}
}
-215
View File
@@ -9,21 +9,6 @@ import qs.Services.UI
Singleton {
id: root
enum ChargingMode {
Disabled = 0,
Full,
Balanced,
Lifespan
}
property int chargingMode: Settings.data.battery.chargingMode
readonly property string batterySetterScript: Quickshell.shellDir + '/Bin/battery-manager/set-battery-treshold.sh'
readonly property string batteryInstallerScript: Quickshell.shellDir + '/Bin/battery-manager/install-battery-manager.sh'
readonly property string batteryUninstallerScript: Quickshell.shellDir + '/Bin/battery-manager/uninstall-battery-manager.sh'
// This is used to omit toast message and writing mode to settings on startup
property bool initialSetter: true
// Choose icon based on charge and charging state
function getIcon(percent, charging, isReady) {
if (!isReady) {
@@ -44,204 +29,4 @@ Singleton {
return "battery";
}
}
function getThresholdValue(chargingMode) {
switch (chargingMode) {
case BatteryService.ChargingMode.Full:
return "100";
case BatteryService.ChargingMode.Balanced:
return "80";
case BatteryService.ChargingMode.Lifespan:
return "60";
}
}
function toggleEnabled(enabled) {
if (enabled) {
setChargingMode(BatteryService.ChargingMode.Full);
} else {
BatteryService.initialSetter = true;
ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.uninstall-setup"));
PanelService.getPanel("batteryPanel", screen)?.toggle(this);
uninstallerProcess.running = true;
}
}
function setChargingMode(newMode) {
if (newMode !== BatteryService.ChargingMode.Full && newMode !== BatteryService.ChargingMode.Balanced && newMode !== BatteryService.ChargingMode.Lifespan) {
Logger.w("BatteryService", `Invalid charging mode set ${newMode}`);
return;
}
BatteryService.chargingMode = newMode;
BatteryService.applyChargingMode();
}
function cycleModes() {
// Cycles charging modes from full to lifespan while skipping disabled
const nextMode = (chargingMode % 3) + 1;
setChargingMode(nextMode);
}
function applyChargingMode() {
let command = [batterySetterScript];
// Currently the script sends notifications by default but quickshell
// uses toast messages so the flag is passed to supress notifs
command.push("-q");
command.push(BatteryService.getThresholdValue(BatteryService.chargingMode));
setterProcess.command = command;
setterProcess.running = true;
}
function runInstaller() {
installerProcess.command = ["pkexec", batteryInstallerScript];
installerProcess.running = true;
}
function init() {
if (BatteryService.chargingMode !== BatteryService.ChargingMode.Disabled && BatteryService.chargingMode !== BatteryService.ChargingMode.Full) {
BatteryService.applyChargingMode();
}
}
Process {
id: setterProcess
workingDirectory: Quickshell.shellDir
running: false
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
Logger.i("BatteryService", "Battery threshold set successfully");
if (BatteryService.initialSetter) {
BatteryService.initialSetter = false;
return;
}
ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.set-success-desc", {
"percent": BatteryService.getThresholdValue(BatteryService.chargingMode)
}), "battery");
Settings.data.battery.chargingMode = BatteryService.chargingMode;
} else if (exitCode === 2) {
ToastService.showWarning(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.initial-setup"));
PanelService.getPanel("batteryPanel", null)?.toggle(this);
BatteryService.runInstaller();
} else {
ToastService.showError(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.set-failed"));
Logger.e("BatteryService", `Setter process failed with exit code: ${exitCode}`);
}
}
stderr: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.w("BatteryService", "SetterProcess stderr:", this.text);
}
}
}
stdout: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.i("BatteryService", "SetterProcess stdout:", this.text);
}
}
}
}
// Installer process - installs battery manager components
Process {
id: installerProcess
workingDirectory: Quickshell.shellDir
running: false
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.install-success"));
BatteryService.applyChargingMode();
} else if (exitCode === 2) {
ToastService.showError(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.install-missing"));
} else if (exitCode === 3) {
ToastService.showError(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.install-unsupported"));
} else {
ToastService.showError(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.install-failed"));
}
if (exitCode !== 0) {
BatteryService.chargingMode = BatteryService.ChargingMode.Disabled;
}
}
stderr: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.w("BatteryService", "InstallerProcess stderr:", this.text);
}
}
}
stdout: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.i("BatteryService", "InstallerProcess stdout:", this.text);
}
}
}
}
Process {
id: uninstallerProcess
workingDirectory: Quickshell.shellDir
command: ["pkexec", batteryUninstallerScript]
running: false
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
Logger.i("BatteryService", "Battery Manager uninstalled successfully");
ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.uninstall-success"));
Settings.data.battery.chargingMode = BatteryService.chargingMode;
BatteryService.chargingMode = BatteryService.ChargingMode.Disabled;
cleanupProcess.running = true;
} else {
ToastService.showError(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.uninstall-failed"));
Logger.e("BatteryService", `Uninstaller process failed with exit code: ${exitCode}`);
}
}
stderr: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.w("BatteryService", "UninstallerProcess stderr:", this.text);
}
}
}
stdout: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.i("BatteryService", "UninstallerProcess stdout:", this.text);
}
}
}
}
// Cleanup process - deletes uninstaller after it sucessfull ;
Process {
id: cleanupProcess
workingDirectory: Quickshell.shellDir
command: ["rm", "-rf", batteryUninstallerScript]
running: false
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
Logger.i("BatteryService", "Battery Manager uninstalled successfully");
} else {
Logger.e("BatteryService", `Cleanup process failed with exit code: ${exitCode}`);
}
}
stderr: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.w("BatteryService", "CleanupProcess stderr:", this.text);
}
}
}
stdout: StdioCollector {
onStreamFinished: {
if (this.text) {
Logger.i("BatteryService", "CleanupProcess stdout:", this.text);
}
}
}
}
}
-1
View File
@@ -76,7 +76,6 @@ ShellRoot {
DarkModeService.init();
HooksService.init();
BluetoothService.init();
BatteryService.init();
IdleInhibitorService.init();
PowerProfileService.init();
HostService.init();