mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
248 lines
8.2 KiB
QML
248 lines
8.2 KiB
QML
pragma Singleton
|
|
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Services.UPower
|
|
import qs.Commons
|
|
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) {
|
|
return "battery-exclamation";
|
|
}
|
|
|
|
if (charging) {
|
|
return "battery-charging";
|
|
} else {
|
|
if (percent >= 90)
|
|
return "battery-4";
|
|
if (percent >= 50)
|
|
return "battery-3";
|
|
if (percent >= 25)
|
|
return "battery-2";
|
|
if (percent >= 0)
|
|
return "battery-1";
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|