mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-08 06:25:37 -05:00
218 lines
8.2 KiB
QML
218 lines
8.2 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Services.UPower
|
|
import Quickshell.Io
|
|
pragma Singleton
|
|
pragma ComponentBehavior: Bound
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
// Debug mode for testing (disabled for now)
|
|
property bool debugMode: false
|
|
|
|
// Battery properties - using shell command method (native UPower API commented out due to issues)
|
|
property bool batteryAvailable: systemBatteryPercentage > 0
|
|
property int batteryLevel: systemBatteryPercentage
|
|
property string batteryStatus: {
|
|
return systemBatteryState === "charging" ? "Charging" :
|
|
systemBatteryState === "discharging" ? "Discharging" :
|
|
systemBatteryState === "fully-charged" ? "Full" :
|
|
systemBatteryState === "empty" ? "Empty" : "Unknown"
|
|
}
|
|
property int timeRemaining: 0 // Not implemented for shell fallback
|
|
property bool isCharging: systemBatteryState === "charging"
|
|
property bool isLowBattery: systemBatteryPercentage <= 20
|
|
|
|
/* Native UPower API (commented out - not working correctly, returns 1% instead of actual values)
|
|
property bool batteryAvailable: (UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.percentage > 0) || systemBatteryPercentage > 0
|
|
property int batteryLevel: {
|
|
if (UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.percentage > 0) {
|
|
return Math.round(UPower.displayDevice.percentage)
|
|
}
|
|
return systemBatteryPercentage
|
|
}
|
|
property string batteryStatus: {
|
|
if (UPower.displayDevice && UPower.displayDevice.ready) {
|
|
switch(UPower.displayDevice.state) {
|
|
case UPowerDeviceState.Charging: return "Charging"
|
|
case UPowerDeviceState.Discharging: return "Discharging"
|
|
case UPowerDeviceState.FullyCharged: return "Full"
|
|
case UPowerDeviceState.Empty: return "Empty"
|
|
case UPowerDeviceState.PendingCharge: return "Pending Charge"
|
|
case UPowerDeviceState.PendingDischarge: return "Pending Discharge"
|
|
case UPowerDeviceState.Unknown:
|
|
default: return "Unknown"
|
|
}
|
|
}
|
|
return systemBatteryState === "charging" ? "Charging" :
|
|
systemBatteryState === "discharging" ? "Discharging" :
|
|
systemBatteryState === "fully-charged" ? "Full" :
|
|
systemBatteryState === "empty" ? "Empty" : "Unknown"
|
|
}
|
|
property int timeRemaining: (UPower.displayDevice && UPower.displayDevice.ready) ? (UPower.displayDevice.timeToEmpty || UPower.displayDevice.timeToFull || 0) : 0
|
|
property bool isCharging: {
|
|
if (UPower.displayDevice && UPower.displayDevice.ready) {
|
|
return UPower.displayDevice.state === UPowerDeviceState.Charging
|
|
}
|
|
return systemBatteryState === "charging"
|
|
}
|
|
property bool isLowBattery: {
|
|
if (UPower.displayDevice && UPower.displayDevice.ready) {
|
|
return UPower.displayDevice.percentage <= 20
|
|
}
|
|
return systemBatteryPercentage <= 20
|
|
}
|
|
*/
|
|
property int batteryHealth: 100 // Default fallback
|
|
property string batteryTechnology: "Li-ion" // Default fallback
|
|
property int cycleCount: 0 // Not implemented for shell fallback
|
|
property int batteryCapacity: 45000 // Default fallback
|
|
property var powerProfiles: availableProfiles
|
|
property string activePowerProfile: "balanced" // Default fallback
|
|
|
|
// System battery info from shell command (primary source)
|
|
property int systemBatteryPercentage: 100 // Default value, will be updated by shell command
|
|
property string systemBatteryState: "charging" // Default value, will be updated by shell command
|
|
|
|
// Shell command fallback for battery info
|
|
Process {
|
|
id: batteryProcess
|
|
running: false
|
|
command: ["upower", "-i", "/org/freedesktop/UPower/devices/battery_BAT1"]
|
|
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
if (text.trim()) {
|
|
let output = text.trim()
|
|
let percentageMatch = output.match(/percentage:\s*(\d+)%/)
|
|
let stateMatch = output.match(/state:\s*(\w+)/)
|
|
|
|
if (percentageMatch) {
|
|
root.systemBatteryPercentage = parseInt(percentageMatch[1])
|
|
console.log("Battery percentage updated to:", root.systemBatteryPercentage)
|
|
}
|
|
if (stateMatch) {
|
|
root.systemBatteryState = stateMatch[1]
|
|
console.log("Battery state updated to:", root.systemBatteryState)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
onExited: (exitCode) => {
|
|
if (exitCode !== 0) {
|
|
console.warn("Battery process failed with exit code:", exitCode)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Timer to periodically check battery status
|
|
Timer {
|
|
interval: 5000 // Check every 5 seconds
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
batteryProcess.running = true
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
// Initial battery check
|
|
batteryProcess.running = true
|
|
// Get current power profile
|
|
getCurrentProfile()
|
|
console.log("BatteryService initialized with shell command approach")
|
|
}
|
|
|
|
property var availableProfiles: {
|
|
// Try to use power-profiles-daemon via shell command
|
|
return ["power-saver", "balanced", "performance"]
|
|
}
|
|
|
|
function setBatteryProfile(profileName) {
|
|
console.log("Setting power profile to:", profileName)
|
|
powerProfileProcess.command = ["powerprofilesctl", "set", profileName]
|
|
powerProfileProcess.running = true
|
|
}
|
|
|
|
// Process to set power profile
|
|
Process {
|
|
id: powerProfileProcess
|
|
running: false
|
|
|
|
onExited: (exitCode) => {
|
|
if (exitCode === 0) {
|
|
console.log("Power profile set successfully")
|
|
// Update current profile
|
|
getCurrentProfile()
|
|
} else {
|
|
console.warn("Failed to set power profile, exit code:", exitCode)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Process to get current power profile
|
|
Process {
|
|
id: getCurrentProfileProcess
|
|
running: false
|
|
command: ["powerprofilesctl", "get"]
|
|
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
if (text.trim()) {
|
|
root.activePowerProfile = text.trim()
|
|
console.log("Current power profile:", root.activePowerProfile)
|
|
}
|
|
}
|
|
}
|
|
|
|
onExited: (exitCode) => {
|
|
if (exitCode !== 0) {
|
|
console.warn("Failed to get current power profile, exit code:", exitCode)
|
|
}
|
|
}
|
|
}
|
|
|
|
function getCurrentProfile() {
|
|
getCurrentProfileProcess.running = true
|
|
}
|
|
|
|
function getBatteryIcon() {
|
|
if (!root.batteryAvailable) return "power"
|
|
|
|
let level = root.batteryLevel
|
|
let charging = root.isCharging
|
|
|
|
if (charging) {
|
|
if (level >= 90) return "battery_charging_full"
|
|
if (level >= 60) return "battery_charging_90"
|
|
if (level >= 30) return "battery_charging_60"
|
|
if (level >= 20) return "battery_charging_30"
|
|
return "battery_charging_20"
|
|
} else {
|
|
if (level >= 90) return "battery_full"
|
|
if (level >= 60) return "battery_6_bar"
|
|
if (level >= 50) return "battery_5_bar"
|
|
if (level >= 40) return "battery_4_bar"
|
|
if (level >= 30) return "battery_3_bar"
|
|
if (level >= 20) return "battery_2_bar"
|
|
if (level >= 10) return "battery_1_bar"
|
|
return "battery_alert"
|
|
}
|
|
}
|
|
|
|
function formatTimeRemaining() {
|
|
if (root.timeRemaining <= 0) return "Unknown"
|
|
|
|
let hours = Math.floor(root.timeRemaining / 3600)
|
|
let minutes = Math.floor((root.timeRemaining % 3600) / 60)
|
|
|
|
if (hours > 0) {
|
|
return hours + "h " + minutes + "m"
|
|
} else {
|
|
return minutes + "m"
|
|
}
|
|
}
|
|
} |