mirror of
https://github.com/aristocratos/btop.git
synced 2024-09-27 22:01:29 +02:00
battery state via CoreFoundation
This commit is contained in:
parent
bbba17cd35
commit
c66b46f850
3
Makefile
3
Makefile
@ -93,6 +93,9 @@ ifdef DEBUG
|
||||
override OPTFLAGS := -O0 -g
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), OSX)
|
||||
override LDCXXFLAGS += -framework IOKit -framework CoreFoundation
|
||||
endif
|
||||
ifneq ($(ARCH),arm64)
|
||||
ifneq ($(PLATFORM),OSX)
|
||||
override LDCXXFLAGS += -fstack-protector -fstack-clash-protection
|
||||
|
@ -16,6 +16,13 @@ indent = tab
|
||||
tab-size = 4
|
||||
*/
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/IOCFSerialize.h>
|
||||
#include <IOKit/IOMessage.h>
|
||||
#include <IOKit/ps/IOPSKeys.h>
|
||||
#include <IOKit/ps/IOPowerSources.h>
|
||||
#include <IOKit/pwr_mgt/IOPM.h>
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <libproc.h>
|
||||
@ -323,32 +330,39 @@ namespace Cpu {
|
||||
auto get_battery() -> tuple<int, long, string> {
|
||||
if (not has_battery) return {0, 0, ""};
|
||||
|
||||
int percent = -1;
|
||||
uint32_t percent = -1;
|
||||
long seconds = -1;
|
||||
string status = "discharging";
|
||||
|
||||
FILE *bat = popen("pmset -g batt", "r");
|
||||
if (bat) {
|
||||
char buf[2048];
|
||||
while (fgets(buf, sizeof(buf), bat) != NULL) {
|
||||
char *perc = strstr(buf, "%");
|
||||
if (perc) {
|
||||
has_battery = true;
|
||||
perc -= 3;
|
||||
string p(perc);
|
||||
p.resize(3);
|
||||
percent = atoi(p.c_str());
|
||||
if (!strstr(buf, "discharging")) {
|
||||
if (percent < 100) {
|
||||
status = "charging";
|
||||
} else {
|
||||
CFTypeRef ps_info = IOPSCopyPowerSourcesInfo();
|
||||
if (ps_info) {
|
||||
CFArrayRef one_ps_descriptor = IOPSCopyPowerSourcesList(ps_info);
|
||||
if (one_ps_descriptor) {
|
||||
CFDictionaryRef one_ps = IOPSGetPowerSourceDescription(ps_info, CFArrayGetValueAtIndex(one_ps_descriptor, 0));
|
||||
has_battery = true;
|
||||
auto state = CFDictionaryGetValue(one_ps, CFSTR(kIOPSPowerSourceStateKey));
|
||||
CFNumberRef remaining = (CFNumberRef)CFDictionaryGetValue(one_ps, CFSTR(kIOPSTimeToEmptyKey));
|
||||
int32_t estimatedMinutesRemaining;
|
||||
if (remaining) {
|
||||
CFNumberGetValue(remaining, kCFNumberSInt32Type, &estimatedMinutesRemaining);
|
||||
seconds = estimatedMinutesRemaining * 60;
|
||||
}
|
||||
CFNumberRef charge = (CFNumberRef)CFDictionaryGetValue(one_ps, CFSTR(kIOPSCurrentCapacityKey));
|
||||
if (charge) {
|
||||
CFNumberGetValue(charge, kCFNumberSInt32Type, &percent);
|
||||
}
|
||||
CFBooleanRef charging = (CFBooleanRef)CFDictionaryGetValue(one_ps, CFSTR(kIOPSIsChargingKey));
|
||||
if (charging) {
|
||||
bool isCharging = CFBooleanGetValue(charging);
|
||||
if (isCharging) {
|
||||
status = "charging";
|
||||
if (percent == 100) {
|
||||
status = "full";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
has_battery = false;
|
||||
}
|
||||
}
|
||||
CFRelease(ps_info);
|
||||
CFRelease(one_ps_descriptor);
|
||||
}
|
||||
return {percent, seconds, status};
|
||||
}
|
||||
@ -926,7 +940,7 @@ namespace Proc {
|
||||
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
|
||||
Logger::error("Unable to get size of kproc_infos");
|
||||
}
|
||||
|
||||
uint64_t cpu_t = 0;
|
||||
processes = (struct kinfo_proc *)malloc(size);
|
||||
if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
|
||||
size_t count = size / sizeof(struct kinfo_proc);
|
||||
@ -944,10 +958,10 @@ namespace Proc {
|
||||
struct proc_taskinfo pti;
|
||||
if (sizeof(pti) == proc_pidinfo(p.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
|
||||
p.threads = pti.pti_threadnum;
|
||||
p.cpu_t = pti.pti_total_user + pti.pti_total_system;
|
||||
p.cpu_c = (double)p.cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
||||
p.cpu_p = 0;
|
||||
cpu_t = pti.pti_total_user + pti.pti_total_system;
|
||||
p.cpu_s = pti.pti_total_system;
|
||||
p.cpu_c = (double)p.cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
||||
p.mem = pti.pti_resident_size;
|
||||
}
|
||||
struct passwd *pwd = getpwuid(kproc.kp_eproc.e_ucred.cr_uid);
|
||||
p.user = pwd->pw_name;
|
||||
@ -960,6 +974,14 @@ namespace Proc {
|
||||
find_old = current_procs.end() - 1;
|
||||
no_cache = true;
|
||||
}
|
||||
//? Process cpu usage since last update
|
||||
p.cpu_p = clamp(round(cmult * 1000 * (cpu_t - p.cpu_t) / max((uint64_t)1, cputimes - old_cputimes)) / 10.0, 0.0, 100.0 * Shared::coreCount);
|
||||
|
||||
//? Process cumulative cpu usage since process start
|
||||
p.cpu_c = (double)cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
||||
|
||||
//? Update cached value with latest cpu times
|
||||
p.cpu_t = cpu_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user