Merge branch 'main' into OSX

# Conflicts:
#	CHANGELOG.md
#	Makefile
#	src/btop.cpp
This commit is contained in:
Jos Dehaes 2021-10-20 23:10:36 +02:00
commit de62167921
12 changed files with 274 additions and 150 deletions

View file

@ -1,3 +1,7 @@
[*.{cpp,h,sh,md,cfg,sample}]
indent_style = tab
indent_size = 4
[*.{yml,yaml}]
indent_style = space
indent_size = 2

View file

@ -1,6 +1,7 @@
name: Continuous Build Linux
on:
workflow_dispatch:
push:
branches:
- main
@ -12,111 +13,97 @@ on:
- '!src/freebsd/**'
- 'include/**'
- 'Makefile'
- '.github/workflows/continuous-build.yml'
jobs:
build:
static-build:
continue-on-error: true
strategy:
matrix:
toolchain:
- aarch64-linux-musl
- aarch64_be-linux-musl
- arm-linux-musleabi
- arm-linux-musleabihf
- armeb-linux-musleabi
- armeb-linux-musleabihf
- armel-linux-musleabi
- armel-linux-musleabihf
- armv5l-linux-musleabi
- armv5l-linux-musleabihf
- armv6-linux-musleabi
- armv6-linux-musleabihf
- armv7l-linux-musleabihf
- armv7m-linux-musleabi
- armv7r-linux-musleabihf
- i486-linux-musl
- i686-linux-musl
- m68k-linux-musl
- mips-linux-musl
- mips-linux-musln32sf
- mips-linux-muslsf
- mips64-linux-musl
- mips64-linux-musln32
- mips64-linux-musln32sf
- mips64el-linux-musl
- mips64el-linux-musln32
- mips64el-linux-musln32sf
- mipsel-linux-musl
- mipsel-linux-musln32
- mipsel-linux-musln32sf
- mipsel-linux-muslsf
- or1k-linux-musl
- powerpc-linux-musl
- powerpc-linux-muslsf
- powerpc64-linux-musl
- powerpc64le-linux-musl
- powerpcle-linux-musl
- powerpcle-linux-muslsf
- riscv32-linux-musl
- riscv64-linux-musl
- s390x-linux-musl
- sh2-linux-musl
- sh2-linux-muslfdpic
- sh2eb-linux-musl
- sh2eb-linux-muslfdpic
- sh4-linux-musl
- sh4eb-linux-musl
- x86_64-linux-musl
- x86_64-linux-muslx32
runs-on: ubuntu-latest
container: ubuntu:21.04
container: muslcc/x86_64:${{ matrix.toolchain }}
steps:
- uses: actions/checkout@v2
- name: Install build tools
run: |
apt update && \
apt install coreutils sed git build-essential gcc-11 g++-11 -y
apt install -y g++-11-aarch64-linux-gnu g++-11-i686-linux-gnu \
g++-11-arm-linux-gnueabi g++-11-arm-linux-gnueabihf g++-11-riscv64-linux-gnu \
g++-11-sparc64-linux-gnu
run: apk add --no-cache coreutils git make tar zstd
mkdir -p multiarch_bin
- name: Checkout source
uses: actions/checkout@v2
git init # [fix Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).]
- name: Fix - Stopping at filesystem boundary
run: git init # [fix Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).]
- name: Compile x86_64
run: |
make CXX=g++-11 ARCH=x86_64 STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-x86_64-$GIT_HASH
make distclean
- name: Compile i686
run: |
make CXX=i686-linux-gnu-g++-11 ARCH=i686 STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-i686-$GIT_HASH
make distclean
- name: Compile aarch64
run: |
make CXX=aarch64-linux-gnu-g++-11 ARCH=aarch64 STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-aarch64-$GIT_HASH
make distclean
- name: Compile armel
run: |
make CXX=arm-linux-gnueabi-g++-11 ARCH=armel STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-armel-$GIT_HASH
make distclean
- name: Compile armhf
run: |
make CXX=arm-linux-gnueabihf-g++-11 ARCH=armhf STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-armhf-$GIT_HASH
make distclean
- name: Compile riscv64
run: |
make CXX=riscv64-linux-gnu-g++-11 ARCH=riscv64 STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-riscv64-$GIT_HASH
make distclean
- name: Compile sparc64
run: |
make CXX=sparc64-linux-gnu-g++-11 ARCH=sparc64 STATIC=true QUIET=true
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
mv bin/btop multiarch_bin/btop-sparc64-$GIT_HASH
make distclean
- name: Build
run: make STATIC=true STRIP=true QUIET=true
- name: Make executable
run: chmod +x bin/*
- name: Set up directories
run: |
chmod +x multiarch_bin/*
mkdir .artifacts
mkdir .package
- uses: actions/upload-artifact@v2
with:
name: btop-x86_64
path: 'multiarch_bin/btop-x86_64*'
- name: Create binary atrifacts
run: |
TOOLCHAIN=${{ matrix.toolchain }}
GIT_HASH=$(git rev-parse --short "${{ github.sha }}")
FILENAME=btop-${TOOLCHAIN/linux-musl/}-$GIT_HASH
cp bin/btop .artifacts/$FILENAME
- uses: actions/upload-artifact@v2
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: btop-i686
path: 'multiarch_bin/btop-i686*'
- uses: actions/upload-artifact@v2
with:
name: btop-aarch64
path: 'multiarch_bin/btop-aarch64*'
- uses: actions/upload-artifact@v2
with:
name: btop-armel
path: 'multiarch_bin/btop-armel*'
- uses: actions/upload-artifact@v2
with:
name: btop-armhf
path: 'multiarch_bin/btop-armhf*'
- uses: actions/upload-artifact@v2
with:
name: btop-riscv64
path: 'multiarch_bin/btop-riscv64*'
- uses: actions/upload-artifact@v2
with:
name: btop-sparc64
path: 'multiarch_bin/btop-sparc64*'
name: btop-${{ matrix.toolchain }}
path: '.artifacts/**'

View file

@ -1,3 +1,19 @@
## v1.0.18
* Fixed: Makefile g++ -dumpmachine failure to get platform on some distros
## v1.0.17
* Changed: Reverted mutexes back to custom atomic bool based locks
* Added: Static binaries switched to building with musl + more platforms, by @jan-guenter
* Fixed: Improved battery detection, by @jan-guenter
* Added: Displayed battery selectable in options menu
* Fixed: Battery error if non existent battery named is entered
## v1.0.16
* Fixed: atomic_wait() and atomic_lock{} use cpu pause instructions instead of thread sleep

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 1,012 B

44
Img/logo.svg Normal file
View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="341" height="90" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="red-stripes" width="341" height="90" patternUnits="userSpaceOnUse">
<rect width="341" height="16" fill="#f00"/>
<rect y="16" width="341" height="16" fill="#d70000"/>
<rect y="32" width="341" height="16" fill="#af0000"/>
<rect y="48" width="341" height="16" fill="#870000"/>
<rect y="64" width="341" height="16" fill="#5f0000"/>
</pattern>
<pattern id="gray-stripes" width="341" height="90" patternUnits="userSpaceOnUse">
<rect width="341" height="16" fill="#585858"/>
<rect y="16" width="341" height="16" fill="#4e4e4e"/>
<rect y="32" width="341" height="16" fill="#444"/>
<rect y="48" width="341" height="16" fill="#3a3a3a"/>
<rect y="64" width="341" height="16" fill="#303030"/>
<rect y="80" width="341" height="10" fill="#262626"/>
</pattern>
</defs>
<g fill="#080808">
<path d="m2,7v83h45v-16h7v-19h-7v-13h7v-19h-7v-16h-45zm17,19h18v13h-18v-13zm0,32h18v13h-18v-13z"/>
<path d="m58,7v19h21v64h17v-64h21v-19h-59z"/>
<path d="m128,7v16h-7v51h7v16h45v-16h7v-51h-7v-16h-45zm10,19h25v45h-25v-45z"/>
<path d="m184,7v83h17v-32h28v-16h7v-19h-7v-16h-45zm17,19h18v13h-18v-13z"/>
<path d="m261,23v16h-14v19h14v16h17v-16h14v-19h-14v-16h-17z"/>
<path d="m310,23v16h-14v19h14v16h17v-16h14v-19h-14v-16h-17z"/>
</g>
<g fill="url(#gray-stripes)">
<path d="m2,7v83h45v-16h7v-19h-7v-13h7v-19h-7v-16h-45zm1,1h43v16h7v17h-7v15h7v17h-7v16h-43v-81zm15,17h20v15h-20v-15zm1,1v13h18v-13h-18zm-1,31h20v15h-20v-15zm1,1v13h18v-13h-18zm-15-49v79h41v-16h7v-15h-7v-17h7v-15h-7v-16h-41zm1,1h39v16h7v13h-7v19h7v13h-7v16h-39v-77zm11,13h24v19h-24v-19zm1,1v17h22v-17h-22zm-1,31h24v19h-24v-19zm1,1v17h22v-17h-22z"/>
<path d="m58,7v19h21v64h17v-64h21v-19h-59zm1,1h57v17h-21v64h-15v-64h-21v-17zm1,1v15h21v64h13v-64h21v-15h-55zm1,1h53v13h-21v64h-11v-64h-21v-13z"/>
<path d="m128,7v16h-7v51h7v16h45v-16h7v-51h-7v-16h-45zm1,1h43v16h7v49h-7v16h-43v-16h-7v-49h7v-16zm9,18v45h25v-45h-25zm-1-1h27v47h-27v-47zm-7-16v16h-7v47h7v16h41v-16h7v-47h-7v-16h-41zm1,1h39v16h7v45h-7v16h-39v-16h-7v-45h7v-16zm5,14v49h29v-49h-29zm-1-1h31v51h-31v-51z"/>
<path d="m184,7v83h17v-32h28v-16h7v-19h-7v-16h-45zm1,1h43v16h7v17h-7v16h-28v32h-15v-81zm16,18v13h18v-13h-18zm-1-1h20v15h-20v-15zm-14-16v79h13v-32h28v-16h7v-15h-7v-16h-41zm1,1h39v16h7v13h-7v16h-28v32h-11v-77zm12,14v17h22v-17h-22zm-1-1h24v19h-24v-19z"/>
<path d="m261,23v16h-14v19h14v16h17v-16h14v-19h-14v-16h-17zm1,1h15v16h14v17h-14v16h-15v-16h-14v-17h14v-16zm1,1v16h-14v15h14v16h13v-16h14v-15h-14v-16h-13zm1,1h11v16h14v13h-14v16h-11v-16h-14v-13h14v-16z"/>
<path d="m310,23v16h-14v19h14v16h17v-16h14v-19h-14v-16h-17zm1,1h15v16h14v17h-14v16h-15v-16h-14v-17h14v-16zm1,1v16h-14v15h14v16h13v-16h14v-15h-14v-16h-13zm1,1h11v16h14v13h-14v16h-11v-16h-14v-13h14v-16z"/>
</g>
<g fill="url(#red-stripes)">
<path d="m0,0v80h42v-16h7v-16h-7v-16h7v-16h-7v-16h-42zm14,16h21v16h-21v-16zm0,32h21v16h-21v-16z"/>
<path d="m56,0v16h21v64h14v-64h21v-16h-56z"/>
<path d="m126,0v16h-7v48h7v16h42v-16h7v-48h-7v-16h-42zm7,16h28v48h-28v-48z"/>
<path d="m182,0v80h14v-32h28v-16h7v-16h-7v-16h-42zm14,16h21v16h-21v-16z"/>
<path d="m259,16v16h-14v16h14v16h14v-16h14v-16h-14v-16h-14z"/>
<path d="m308,16v16h-14v16h14v16h14v-16h14v-16h-14v-16h-14z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -1,6 +1,6 @@
#* Btop++ makefile v1.2
BANNER = \n \033[38;5;196m██████\033[38;5;240m╗ \033[38;5;196m████████\033[38;5;240m╗ \033[38;5;196m██████\033[38;5;240m╗ \033[38;5;196m██████\033[38;5;240m╗\n \033[38;5;160m██\033[38;5;239m╔══\033[38;5;160m██\033[38;5;239m╗╚══\033[38;5;160m██\033[38;5;239m╔══╝\033[38;5;160m██\033[38;5;239m╔═══\033[38;5;160m██\033[38;5;239m╗\033[38;5;160m██\033[38;5;239m╔══\033[38;5;160m██\033[38;5;239m╗ \033[38;5;160m██\033[38;5;239m╗ \033[38;5;160m██\033[38;5;239m╗\n \033[38;5;124m██████\033[38;5;238m╔╝ \033[38;5;124m██\033[38;5;238m║ \033[38;5;124m██\033[38;5;238m║ \033[38;5;124m██\033[38;5;238m║\033[38;5;124m██████\033[38;5;238m╔╝ \033[38;5;124m██████\033[38;5;238m╗\033[38;5;124m██████\033[38;5;238m╗\n \033[38;5;88m██\033[38;5;237m╔══\033[38;5;88m██\033[38;5;237m╗ \033[38;5;88m██\033[38;5;237m║ \033[38;5;88m██\033[38;5;237m║ \033[38;5;88m██\033[38;5;237m║\033[38;5;88m██\033[38;5;237m╔═══╝ ╚═\033[38;5;88m██\033[38;5;237m╔═╝╚═\033[38;5;88m██\033[38;5;237m╔═╝\n \033[38;5;52m██████\033[38;5;236m╔╝ \033[38;5;52m██\033[38;5;236m║ ╚\033[38;5;52m██████\033[38;5;236m╔╝\033[38;5;52m██\033[38;5;236m║ ╚═╝ ╚═╝\n \033[38;5;235m╚═════╝ ╚═╝ ╚═════╝ ╚═╝ \033[1;3;38;5;240mMakefile v1.2\033[0m
BANNER = \n \033[38;5;196m██████\033[38;5;240m╗ \033[38;5;196m████████\033[38;5;240m╗ \033[38;5;196m██████\033[38;5;240m╗ \033[38;5;196m██████\033[38;5;240m╗\n \033[38;5;160m██\033[38;5;239m╔══\033[38;5;160m██\033[38;5;239m╗╚══\033[38;5;160m██\033[38;5;239m╔══╝\033[38;5;160m██\033[38;5;239m╔═══\033[38;5;160m██\033[38;5;239m╗\033[38;5;160m██\033[38;5;239m╔══\033[38;5;160m██\033[38;5;239m╗ \033[38;5;160m██\033[38;5;239m╗ \033[38;5;160m██\033[38;5;239m╗\n \033[38;5;124m██████\033[38;5;238m╔╝ \033[38;5;124m██\033[38;5;238m║ \033[38;5;124m██\033[38;5;238m║ \033[38;5;124m██\033[38;5;238m║\033[38;5;124m██████\033[38;5;238m╔╝ \033[38;5;124m██████\033[38;5;238m╗\033[38;5;124m██████\033[38;5;238m╗\n \033[38;5;88m██\033[38;5;237m╔══\033[38;5;88m██\033[38;5;237m╗ \033[38;5;88m██\033[38;5;237m║ \033[38;5;88m██\033[38;5;237m║ \033[38;5;88m██\033[38;5;237m║\033[38;5;88m██\033[38;5;237m╔═══╝ ╚═\033[38;5;88m██\033[38;5;237m╔═╝╚═\033[38;5;88m██\033[38;5;237m╔═╝\n \033[38;5;52m██████\033[38;5;236m╔╝ \033[38;5;52m██\033[38;5;236m║ ╚\033[38;5;52m██████\033[38;5;236m╔╝\033[38;5;52m██\033[38;5;236m║ ╚═╝ ╚═╝\n \033[38;5;235m╚═════╝ ╚═╝ ╚═════╝ ╚═╝ \033[1;3;38;5;240mMakefile v1.3\033[0m
override BTOP_VERSION := $(shell head -n100 src/btop.cpp 2>/dev/null | grep "Version =" | cut -f2 -d"\"" || echo " unknown")
override TIMESTAMP := $(shell date +%s 2>/dev/null || echo "0")
@ -15,9 +15,14 @@ endif
PREFIX ?= /usr/local
#? NOTICE! Manually set PLATFORM and ARCH if not compiling for host system
#? Detect PLATFORM and ARCH from uname/gcc if not set
PLATFORM ?= $(shell uname -s || echo unknown)
ARCH ?= $(shell uname -m || echo unknown)
ifneq ($(filter unknown darwin, $(PLATFORM)),)
override PLATFORM := $(shell $(CXX) -dumpmachine | awk -F"-" '{ print (NF==4) ? $$3 : $$2 }')
endif
ARCH ?= $(shell $(CXX) -dumpmachine | cut -d "-" -f 1)
override PLATFORM_LC := $(shell echo $(PLATFORM) | tr '[:upper:]' '[:lower:]')
#? Make sure PLATFORM Darwin is OSX and not Darwin
ifeq ($(PLATFORM),Darwin)
@ -30,12 +35,16 @@ ifeq ($(PLATFORM),Darwin)
endif
#? Only enable fcf-protection if on x86_64
ifeq ($(ARCH),x86_64)
ifneq ($(filter x86_64 i%86, $(ARCH)),)
override ADDFLAGS += -fcf-protection
endif
ifeq ($(STATIC),true)
override ADDFLAGS += -D STATIC_BUILD -static -static-libgcc -static-libstdc++
override ADDFLAGS += -D STATIC_BUILD -static -static-libgcc -static-libstdc++ -Wl,--fatal-warnings
endif
ifeq ($(STRIP),true)
override ADDFLAGS += -s
endif
#? Compiler and Linker
@ -58,13 +67,13 @@ ifeq ($(CXX),g++)
endif
#? Pull in platform specific source files and get thread count
ifeq ($(PLATFORM),Linux)
ifeq ($(PLATFORM_LC),linux)
PLATFORM_DIR := linux
THREADS := $(shell getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)
else ifeq ($(PLATFORM),FreeBSD)
else ifeq ($(PLATFORM_LC),freebsd)
PLATFORM_DIR := freebsd
THREADS := $(shell getconf NPROCESSORS_ONLN 2>/dev/null || echo 1)
else ifeq ($(PLATFORM),OSX)
else ifeq ($(PLATFORM_LC),apple)
PLATFORM_DIR := osx
THREADS := $(shell sysctl -n hw.ncpu || echo 1)
ifeq ($(shell command -v gdate >/dev/null; echo $$?),0)

View file

@ -176,7 +176,7 @@ Also needs a UTF8 locale and a font that covers:
## Installation
**Binary release (statically compiled, for kernel 3.2.0 and newer)**
**Binary release (statically compiled with musl, for kernel 2.6.39 and newer)**
1. **Download btop-(VERSION)-(PLATFORM)-(ARCH).tbz from [latest release](https://github.com/aristocratos/btop/releases/latest) and unpack to a new folder**
@ -238,11 +238,14 @@ Also needs a UTF8 locale and a font that covers:
The makefile also needs GNU coreutils and `sed` (should already be installed on any modern distribution).
For a `cmake` based build alternative see the [fork](https://github.com/jan-guenter/btop/tree/main) by @jan-guenter
1. **Install dependencies (example for Ubuntu 21.04 Hirsute)**
Use gcc-10 g++-10 if gcc-11 isn't available
``` bash
sudo apt install coreutils sed git build-essential gcc-11 g++-11
# use gcc-10 g++-10 if gcc-11 isn't available
```
2. **Clone repository**
@ -256,15 +259,20 @@ Also needs a UTF8 locale and a font that covers:
Append `STATIC=true` to `make` command for static compilation.
Notice! If using LDAP Authentication, usernames will show as UID number for LDAP users when compiling statically.
Notice! If using LDAP Authentication, usernames will show as UID number for LDAP users if compiling statically with glibc.
Append `QUIET=true` for less verbose output.
Notice! Manually set `$ARCH` variable if cross-compiling
Append `STRIP=true` to force stripping of debug symbols (adds `-s` linker flag).
Append `ARCH=<architecture>` to manually set the target architecture.
If omitted the makefile uses the machine triple (output of `-dumpmachine` compiler parameter) to detect the target system.
Use `ADDFLAGS` variable for appending flags to both compiler and linker.
For example: `make ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
For example: `ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
If `g++` is linked to an older version of gcc on your system specify the correct version by appending `CXX=g++-10` or `CXX=g++-11`.
``` bash
make
@ -272,9 +280,11 @@ Also needs a UTF8 locale and a font that covers:
4. **Install**
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
Notice! Only use "sudo" when installing to a NON user owned directory.
``` bash
# use "make install PREFIX=/target/dir" to set target, default: /usr/local
# only use "sudo" when installing to a NON user owned directory
sudo make install
```
@ -282,9 +292,11 @@ Also needs a UTF8 locale and a font that covers:
No need for `sudo` to enable signal sending to any process and to prevent /proc read permissions problems on some systems.
Run after make install and use same PREFIX if any was used at install.
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `root`
``` bash
# run after make install and use same PREFIX if any was used at install
# set SU_USER and SU_GROUP to select user and group, default is root:root
sudo make setuid
```

View file

@ -53,7 +53,7 @@ namespace Global {
{"#801414", "██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝"},
{"#000000", "╚═════╝ ╚═╝ ╚═════╝ ╚═╝"},
};
const string Version = "1.0.16";
const string Version = "1.0.18";
int coreCount;
string overlay;

View file

@ -170,6 +170,8 @@ namespace Config {
{"show_battery", "#* Show battery stats in top right if battery is present."},
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
{"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
"#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."}
};
@ -187,6 +189,7 @@ namespace Config {
{"cpu_graph_upper", "total"},
{"cpu_graph_lower", "total"},
{"cpu_sensor", "Auto"},
{"selected_battery", "Auto"},
{"cpu_core_map", ""},
{"temp_scale", "celsius"},
{"clock_format", "%X"},
@ -265,6 +268,8 @@ namespace Config {
fs::path conf_dir;
fs::path conf_file;
vector<string> available_batteries = {"Auto"};
vector<string> current_boxes;
vector<string> preset_list = {"cpu:0:default,mem:0:default,net:0:default,proc:0:default"};
int current_preset = -1;

View file

@ -45,6 +45,7 @@ namespace Config {
extern vector<string> current_boxes;
extern vector<string> preset_list;
extern vector<string> available_batteries;
extern int current_preset;
//* Check if string only contains space seperated valid names for boxes

View file

@ -270,6 +270,13 @@ namespace Menu {
"",
"Show battery stats in the top right corner",
"if a battery is present."},
{"selected_battery",
"Select battery.",
"",
"Which battery to use if multiple are present.",
"Can be both batteries and UPS.",
"",
"\"Auto\" for auto detection."},
{"log_level",
"Set loglevel for error.log",
"",
@ -962,7 +969,8 @@ namespace Menu {
{"graph_symbol_proc", std::cref(Config::valid_graph_symbols_def)},
{"cpu_graph_upper", std::cref(Cpu::available_fields)},
{"cpu_graph_lower", std::cref(Cpu::available_fields)},
{"cpu_sensor", std::cref(Cpu::available_sensors)}
{"cpu_sensor", std::cref(Cpu::available_sensors)},
{"selected_battery", std::cref(Config::available_batteries)},
};
auto& tty_mode = Config::getB("tty_mode");
auto& vim_keys = Config::getB("vim_keys");

View file

@ -27,7 +27,7 @@ tab-size = 4
#include <ifaddrs.h>
#include <net/if.h>
#ifndef STATIC_BUILD
#if !(defined(STATIC_BUILD) && defined(__GLIBC__))
#include <pwd.h>
#endif
@ -468,61 +468,99 @@ namespace Cpu {
return core_map;
}
struct battery {
fs::path base_dir, energy_now, energy_full, power_now, status, online;
string device_type;
bool use_energy = true;
};
auto get_battery() -> tuple<int, long, string> {
if (not has_battery) return {0, 0, ""};
static fs::path bat_dir, energy_now_path, energy_full_path, power_now_path, status_path, online_path;
static bool use_energy = true;
static string auto_sel;
static unordered_flat_map<string, battery> batteries;
//? Get paths to needed files and check for valid values on first run
if (bat_dir.empty() and has_battery) {
if (batteries.empty() and has_battery) {
if (fs::exists("/sys/class/power_supply")) {
for (const auto& d : fs::directory_iterator("/sys/class/power_supply")) {
if (const string dir_name = d.path().filename(); d.is_directory() and (dir_name.starts_with("BAT") or s_contains(str_to_lower(dir_name), "battery"))) {
bat_dir = d.path();
break;
//? Only consider online power supplies of type Battery or UPS
//? see kernel docs for details on the file structure and contents
//? https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power
battery new_bat;
fs::path bat_dir;
try {
if (not d.is_directory()
or not fs::exists(d.path() / "type")
or not fs::exists(d.path() / "present")
or stoi(readfile(d.path() / "present")) != 1)
continue;
string dev_type = readfile(d.path() / "type");
if (is_in(dev_type, "Battery", "UPS")) {
bat_dir = d.path();
new_bat.base_dir = d.path();
new_bat.device_type = dev_type;
}
} catch (...) {
//? skip power supplies not conforming to the kernel standard
continue;
}
if (fs::exists(bat_dir / "energy_now")) new_bat.energy_now = bat_dir / "energy_now";
else if (fs::exists(bat_dir / "charge_now")) new_bat.energy_now = bat_dir / "charge_now";
else new_bat.use_energy = false;
if (fs::exists(bat_dir / "energy_full")) new_bat.energy_full = bat_dir / "energy_full";
else if (fs::exists(bat_dir / "charge_full")) new_bat.energy_full = bat_dir / "charge_full";
else new_bat.use_energy = false;
if (not new_bat.use_energy and not fs::exists(bat_dir / "capacity")) {
continue;
}
if (fs::exists(bat_dir / "power_now")) new_bat.power_now = bat_dir / "power_now";
else if (fs::exists(bat_dir / "current_now")) new_bat.power_now = bat_dir / "current_now";
if (fs::exists(bat_dir / "AC0/online")) new_bat.online = bat_dir / "AC0/online";
else if (fs::exists(bat_dir / "AC/online")) new_bat.online = bat_dir / "AC/online";
batteries[bat_dir.filename()] = new_bat;
Config::available_batteries.push_back(bat_dir.filename());
}
}
if (bat_dir.empty()) {
if (batteries.empty()) {
has_battery = false;
return {0, 0, ""};
}
else {
if (fs::exists(bat_dir / "energy_now")) energy_now_path = bat_dir / "energy_now";
else if (fs::exists(bat_dir / "charge_now")) energy_now_path = bat_dir / "charge_now";
else use_energy = false;
if (fs::exists(bat_dir / "energy_full")) energy_full_path = bat_dir / "energy_full";
else if (fs::exists(bat_dir / "charge_full")) energy_full_path = bat_dir / "charge_full";
else use_energy = false;
if (not use_energy and not fs::exists(bat_dir / "capacity")) {
has_battery = false;
return {0, 0, ""};
}
if (fs::exists(bat_dir / "power_now")) power_now_path = bat_dir / "power_now";
else if (fs::exists(bat_dir / "current_now")) power_now_path = bat_dir / "current_now";
if (fs::exists(bat_dir / "AC0/online")) online_path = bat_dir / "AC0/online";
else if (fs::exists(bat_dir / "AC/online")) online_path = bat_dir / "AC/online";
}
}
auto& battery_sel = Config::getS("selected_battery");
if (auto_sel.empty()) {
for (auto& [name, bat] : batteries) {
if (bat.device_type == "Battery") {
auto_sel = name;
break;
}
}
if (auto_sel.empty()) auto_sel = batteries.begin()->first;
}
auto& b = (battery_sel != "Auto" and batteries.contains(battery_sel) ? batteries.at(battery_sel) : batteries.at(auto_sel));
int percent = -1;
long seconds = -1;
//? Try to get battery percentage
if (use_energy) {
if (b.use_energy) {
try {
percent = round(100.0 * stoll(readfile(energy_now_path, "-1")) / stoll(readfile(energy_full_path, "1")));
percent = round(100.0 * stoll(readfile(b.energy_now, "-1")) / stoll(readfile(b.energy_full, "1")));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
if (percent < 0) {
try {
percent = stoll(readfile(bat_dir / "capacity", "-1"));
percent = stoll(readfile(b.base_dir / "capacity", "-1"));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
@ -533,9 +571,9 @@ namespace Cpu {
}
//? Get charging/discharging status
string status = str_to_lower(readfile(bat_dir / "status", "unknown"));
if (status == "unknown" and not online_path.empty()) {
const auto online = readfile(online_path, "0");
string status = str_to_lower(readfile(b.base_dir / "status", "unknown"));
if (status == "unknown" and not b.online.empty()) {
const auto online = readfile(b.online, "0");
if (online == "1" and percent < 100) status = "charging";
else if (online == "1") status = "full";
else status = "discharging";
@ -543,16 +581,16 @@ namespace Cpu {
//? Get seconds to empty
if (not is_in(status, "charging", "full")) {
if (use_energy and not power_now_path.empty()) {
if (b.use_energy and not b.power_now.empty()) {
try {
seconds = round((double)stoll(readfile(energy_now_path, "0")) / stoll(readfile(power_now_path, "1")) * 3600);
seconds = round((double)stoll(readfile(b.energy_now, "0")) / stoll(readfile(b.power_now, "1")) * 3600);
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
if (seconds < 0 and fs::exists(bat_dir / "time_to_empty")) {
if (seconds < 0 and fs::exists(b.base_dir / "time_to_empty")) {
try {
seconds = stoll(readfile(bat_dir / "time_to_empty", "0")) * 60;
seconds = stoll(readfile(b.base_dir / "time_to_empty", "0")) * 60;
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
@ -1437,7 +1475,7 @@ namespace Proc {
new_proc.user = uid_user.at(uid);
}
else {
#ifndef STATIC_BUILD
#if !(defined(STATIC_BUILD) && defined(__GLIBC__))
try {
struct passwd* udet;
udet = getpwuid(stoi(uid));