mirror of
https://github.com/aristocratos/btop.git
synced 2024-05-15 09:54:33 +12:00
Compare commits
140 commits
Author | SHA1 | Date | |
---|---|---|---|
3d46dc6969 | |||
b93206f038 | |||
ac62ba9de1 | |||
3f917c0412 | |||
0127e8b3cd | |||
ebc86e9702 | |||
dd4ada7023 | |||
b48bf6ae45 | |||
3b65b3a729 | |||
255b777563 | |||
8c1a8ab4fa | |||
f8cfa70dda | |||
3a6f816396 | |||
14b388521d | |||
d200ce45ae | |||
924c3f3a72 | |||
0e07debb7d | |||
b991e6898d | |||
5d7794019a | |||
5ba45f7633 | |||
9a37395744 | |||
08f90fb4f0 | |||
b06474136b | |||
d1680735d9 | |||
a535a6eb92 | |||
b1b8249d55 | |||
4a82105547 | |||
8af8389bd0 | |||
adaea59a2a | |||
2aa2c90f41 | |||
a60c969533 | |||
c767099d76 | |||
d8c054d92f | |||
ed68589af1 | |||
c6fbfd1e27 | |||
bfe8c20ebe | |||
6c66740290 | |||
967ea1ab6f | |||
cf609175fb | |||
e1575a1fca | |||
e031cce6ba | |||
83739f84e1 | |||
fd2a2acdad | |||
37d217eeb6 | |||
f537715d8b | |||
7a058e4f42 | |||
bae006e94c | |||
c625d512e1 | |||
43af034317 | |||
5282acc149 | |||
9c34ac75dc | |||
0f224bb0e2 | |||
65f3ade9b6 | |||
e8137674b0 | |||
1d62896c9b | |||
283ad3e76e | |||
97e78ebb12 | |||
1670e1db79 | |||
67561d1994 | |||
46f6b4fe90 | |||
459cbbeb52 | |||
d460fc63dc | |||
c587c9f1e3 | |||
c7fdd8adfe | |||
77c758c349 | |||
f1f37ad6af | |||
338aa72f6f | |||
842b9f83b2 | |||
cae6c86ecd | |||
7f5b060b0c | |||
bf5618536b | |||
e0884917e6 | |||
1584ce6468 | |||
7057d7653d | |||
91e137a411 | |||
bb8c7bc35c | |||
70dec20b23 | |||
8bf88c1918 | |||
ab0bef204a | |||
ee46dba838 | |||
a0e2a5c1d2 | |||
f2ead3d3a9 | |||
57703d3087 | |||
2b09f29a1e | |||
bc0eb4291f | |||
69363487bc | |||
0bb1d4bf97 | |||
edcb68cbb9 | |||
7d3617a274 | |||
4461a431ae | |||
eab6c58137 | |||
8019e117c7 | |||
5511131572 | |||
81d09860f7 | |||
bdc8d0151d | |||
7717020197 | |||
c750543950 | |||
61105e46b7 | |||
40cdb92b8e | |||
fb994b69eb | |||
e047f88bd5 | |||
3174c83b43 | |||
67a674e850 | |||
a44ce1c3a1 | |||
57752df6fc | |||
cec251bf05 | |||
05da55c549 | |||
6a6f514f80 | |||
b2df50396b | |||
e936339038 | |||
c649369efb | |||
21fe2cc07b | |||
d063cd300e | |||
ca368c5b89 | |||
3cbb0484a4 | |||
60bd10d44c | |||
19c6099c7c | |||
4ab43fd159 | |||
b28c5ffc40 | |||
fb6af5ddb4 | |||
63ce0abc64 | |||
9dd43796fd | |||
5792216eb9 | |||
46743abab8 | |||
0c706cd20a | |||
a81b514d6d | |||
cd6c1b7294 | |||
2934138a66 | |||
578b01e06b | |||
7a188bfaaf | |||
1ad1418771 | |||
ddd4bec1c3 | |||
6e575116fe | |||
419a7d4ca3 | |||
b09f352c09 | |||
f6d8c4a044 | |||
ab294bfc10 | |||
ee61700a44 | |||
b99008f626 | |||
4c74a7c51d |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -28,10 +28,9 @@ Any bug that can be solved by just reading the [prerequisites](https://github.co
|
|||
[If applicable, add screenshots to help explain your problem.]
|
||||
|
||||
**Info (please complete the following information):**
|
||||
- btop++ version: `btop -v`
|
||||
- btop++ version: `btop --version`
|
||||
- If using snap: `snap info btop`
|
||||
- Binary: [self compiled or static binary from release]
|
||||
- (If compiled) Compiler and version:
|
||||
- Architecture: [x86_64, aarch64, etc.] `uname -m`
|
||||
- Platform: [Linux, FreeBSD, OsX]
|
||||
- (Linux) Kernel: `uname -r`
|
||||
|
|
3
.github/workflows/cmake-freebsd.yml
vendored
3
.github/workflows/cmake-freebsd.yml
vendored
|
@ -33,8 +33,7 @@ jobs:
|
|||
with:
|
||||
release: '14.0'
|
||||
usesh: true
|
||||
prepare: pkg install -y cmake ninja
|
||||
prepare: pkg install -y cmake ninja lowdown
|
||||
run: |
|
||||
CXX=clang++ cmake -B build -G Ninja -DBTOP_STATIC=ON
|
||||
cmake --build build --verbose
|
||||
|
||||
|
|
3
.github/workflows/cmake-linux.yml
vendored
3
.github/workflows/cmake-linux.yml
vendored
|
@ -30,11 +30,10 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install build tools
|
||||
run: apk add --no-cache --update clang cmake lld ninja
|
||||
run: apk add --no-cache --update clang cmake lld ninja lowdown
|
||||
|
||||
- name: Configure
|
||||
run: CXX=clang++ LDFLAGS=-fuse-ld=lld cmake -B build -G Ninja -DBTOP_STATIC=ON
|
||||
|
||||
- name: Compile
|
||||
run: cmake --build build --verbose
|
||||
|
||||
|
|
3
.github/workflows/cmake-macos.yml
vendored
3
.github/workflows/cmake-macos.yml
vendored
|
@ -32,7 +32,7 @@ jobs:
|
|||
run: |
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
brew update --quiet
|
||||
brew install --force --overwrite cmake llvm@17 ninja
|
||||
brew install --force --overwrite cmake llvm ninja lowdown
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
|
@ -44,4 +44,3 @@ jobs:
|
|||
|
||||
- name: Compile
|
||||
run: cmake --build build --verbose
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
release: '14.0'
|
||||
usesh: true
|
||||
prepare: |
|
||||
pkg install -y gmake gcc coreutils git
|
||||
pkg install -y gmake gcc coreutils git lowdown
|
||||
git config --global --add safe.directory /home/runner/work/btop/btop
|
||||
run: |
|
||||
CXX=${{ matrix.compiler }} gmake STATIC=true STRIP=true
|
||||
|
@ -59,4 +59,3 @@ jobs:
|
|||
name: btop-x86_64-freebsd-14
|
||||
path: 'bin/*'
|
||||
if-no-files-found: error
|
||||
|
||||
|
|
45
.github/workflows/continuous-build-gpu.yml
vendored
Normal file
45
.github/workflows/continuous-build-gpu.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
name: Continuous Build Gpu
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags-ignore:
|
||||
- '*.*'
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '!src/osx/**'
|
||||
- '!src/freebsd/**'
|
||||
- '!src/openbsd/**'
|
||||
- 'include/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/continuous-build-gpu.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '!src/osx/**'
|
||||
- '!src/freebsd/**'
|
||||
- '!src/openbsd/**'
|
||||
- 'include/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/continuous-build-gpu.yml'
|
||||
|
||||
jobs:
|
||||
gpu_build_linux:
|
||||
runs-on: ubuntu-latest
|
||||
container: alpine:edge
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install build tools
|
||||
run: apk add --no-cache --update gcc g++ make
|
||||
|
||||
- name: Compile
|
||||
run: make CXX=g++ GPU_SUPPORT=true
|
||||
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
release: '7.4'
|
||||
usesh: true
|
||||
prepare: |
|
||||
pkg_add gmake gcc%11 g++%11 coreutils git
|
||||
pkg_add gmake gcc%11 g++%11 coreutils git lowdown
|
||||
git config --global --add safe.directory /home/runner/work/btop/btop
|
||||
run: |
|
||||
gmake CXX=eg++ STATIC=true STRIP=true
|
||||
|
@ -55,4 +55,3 @@ jobs:
|
|||
name: btop-x86_64-openbsd-7.4
|
||||
path: 'bin/*'
|
||||
if-no-files-found: error
|
||||
|
||||
|
|
3
.github/workflows/test-snap-can-build.yml
vendored
3
.github/workflows/test-snap-can-build.yml
vendored
|
@ -1,5 +1,4 @@
|
|||
name: 🧪 Test snap can be built on x86_64
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
|
@ -28,7 +27,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
node-version: [20.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -46,9 +46,14 @@ stage/
|
|||
*.out
|
||||
*.app
|
||||
|
||||
# Compiled man page
|
||||
btop.1
|
||||
|
||||
build
|
||||
bin
|
||||
btop
|
||||
/obj/
|
||||
config.h
|
||||
.*/
|
||||
|
||||
# Optional libraries
|
||||
|
|
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -1,3 +1,25 @@
|
|||
## v1.3.2
|
||||
|
||||
Description | Author(s) | References
|
||||
--- | --- | ---
|
||||
fix: Can't detect librocm 6.0.x | @imwints, @aristocratos | #761
|
||||
|
||||
## v1.3.1
|
||||
|
||||
Description | Author(s) | References
|
||||
--- | --- | ---
|
||||
GPU: Added support for dynamic loading of ROCm v6 libraries | @aristocratos, @fxzjshm | 5511131, #737
|
||||
Increase max network interface name to 15 | @tessus | #714
|
||||
Fix OpenBSD UTF-8 locale detection | @lcheylus, @imwints | #753, #717
|
||||
Add hot-reloading of config file with CTRL+R or SIGUSR2 signal | @MartinPit | #722
|
||||
Add battery power draw for linux and freebsd | @vsey | #689
|
||||
Fix crash caused by string exception when cpu clock is exactly between 999.5 and 999.9 Mhz | @rkmcode | #735
|
||||
Write newline at end of config file | @planet36 | #743
|
||||
Add theme based on Everforest Dark Medium palette | @M-Sviridov | #746
|
||||
fix: don't mangle memory for zombie processes | @joske | #747
|
||||
Share common code from collect | @imwints | #756
|
||||
Fixed incorrect used and available memory for OSX | | 4461a43
|
||||
|
||||
## v1.3.0
|
||||
|
||||
* Added Gpu Support Linux | @romner-set | PR #529
|
||||
|
@ -158,7 +180,7 @@
|
|||
|
||||
* Fixed: Wrong memory unit when shorten and size is less than 10, by @mohi001
|
||||
|
||||
* Fixed: Use cpu cores avarage temp if missing cpu package temp for FreeBSD
|
||||
* Fixed: Use cpu cores average temp if missing cpu package temp for FreeBSD
|
||||
|
||||
* Changed: Enter symbol to a more common variant
|
||||
|
||||
|
@ -454,7 +476,7 @@
|
|||
|
||||
* Fixed: Sizing constraints bug on start and boxes can be toggled from size error screen
|
||||
|
||||
* Fixed: UTF-8 check crashing if LANG was set to non existant locale
|
||||
* Fixed: UTF-8 check crashing if LANG was set to non existent locale
|
||||
|
||||
## v1.0.4
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
|
|||
endif()
|
||||
|
||||
project("btop"
|
||||
VERSION 1.2.13
|
||||
DESCRIPTION "A monitor of resources"
|
||||
HOMEPAGE_URL "https://github.com/aristocratos/btop"
|
||||
LANGUAGES CXX
|
||||
|
@ -41,6 +40,7 @@ option(BTOP_LTO "Enable LTO" ON)
|
|||
option(BTOP_USE_MOLD "Use mold to link btop" OFF)
|
||||
option(BTOP_PEDANTIC "Enable a bunch of additional warnings" OFF)
|
||||
option(BTOP_WERROR "Compile with warnings as errors" OFF)
|
||||
option(BTOP_FORTIFY "Detect buffer overflows with _FORTIFY_SOURCE=3" ON)
|
||||
option(BTOP_GPU "Enable GPU support" ON)
|
||||
cmake_dependent_option(BTOP_RSMI_STATIC "Link statically to ROCm SMI" OFF "BTOP_GPU" OFF)
|
||||
|
||||
|
@ -64,6 +64,8 @@ if(APPLE)
|
|||
target_sources(btop PRIVATE src/osx/btop_collect.cpp src/osx/sensors.cpp src/osx/smc.cpp)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
target_sources(btop PRIVATE src/freebsd/btop_collect.cpp)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
target_sources(btop PRIVATE src/openbsd/btop_collect.cpp src/openbsd/sysctlbyname.cpp)
|
||||
elseif(LINUX)
|
||||
target_sources(btop PRIVATE src/linux/btop_collect.cpp)
|
||||
else()
|
||||
|
@ -75,6 +77,21 @@ if(NOT CXX_HAVE_RANGES)
|
|||
message(FATAL_ERROR "The compiler doesn't support <ranges>")
|
||||
endif()
|
||||
|
||||
# Generate build info
|
||||
execute_process(
|
||||
COMMAND "git" "rev-parse" "--short" "HEAD"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GIT_COMMIT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||
set(CONFIGURE_COMMAND
|
||||
"cmake -DBTOP_STATIC=${BTOP_STATIC} -DBTOP_USE_MOLD=${BTOP_USE_MOLD} -DBTOP_FORTIFY=${BTOP_FORTIFY} -DBTOP_GPU=${BTOP_GPU}"
|
||||
)
|
||||
get_filename_component(CXX_COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
|
||||
set(COMPILER "${CXX_COMPILER_BASENAME}")
|
||||
set(COMPILER_VERSION "${CMAKE_CXX_COMPILER_VERSION}")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY IMMEDIATE)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Check for and enable LTO
|
||||
check_ipo_supported(RESULT ipo_supported)
|
||||
if(ipo_supported AND BTOP_LTO)
|
||||
|
@ -97,7 +114,7 @@ if(BTOP_WERROR)
|
|||
endif()
|
||||
|
||||
if(NOT APPLE)
|
||||
target_compile_options(btop PRIVATE -fstack-clash-protection)
|
||||
target_compile_options(btop PRIVATE -fstack-clash-protection)
|
||||
endif()
|
||||
check_cxx_compiler_flag(-fstack-protector HAS_FSTACK_PROTECTOR)
|
||||
if(HAS_FSTACK_PROTECTOR)
|
||||
|
@ -109,10 +126,11 @@ if(HAS_FCF_PROTECTION)
|
|||
endif()
|
||||
|
||||
target_compile_definitions(btop PRIVATE
|
||||
FMT_HEADER_ONLY
|
||||
_FILE_OFFSET_BITS=64
|
||||
$<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1>
|
||||
# Only has an effect with optimizations enabled
|
||||
$<$<NOT:$<CONFIG:Debug>>:_FORTIFY_SOURCE=2>
|
||||
$<$<AND:$<NOT:$<CONFIG:Debug>>,$<BOOL:${BTOP_FORTIFY}>>:_FORTIFY_SOURCE=3>
|
||||
)
|
||||
|
||||
target_include_directories(btop SYSTEM PRIVATE include)
|
||||
|
@ -129,7 +147,7 @@ if(LINUX AND BTOP_GPU)
|
|||
if(BTOP_RSMI_STATIC)
|
||||
# ROCm doesn't properly add it's folders to the module path if `CMAKE_MODULE_PATH` is already
|
||||
# set
|
||||
# We could also manully append ROCm's path here
|
||||
# We could also manually append ROCm's path here
|
||||
set(_CMAKE_MODULE_PATH CMAKE_MODULE_PATH)
|
||||
unset(CMAKE_MODULE_PATH)
|
||||
|
||||
|
@ -175,15 +193,43 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
|||
INSTALL_RPATH "/usr/local/lib/gcc${GCC_VERSION_MAJOR}"
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
)
|
||||
|
||||
# The gcc compiler wrapper doesn't add '--eh-frame-hdr' on FreeBSD with static builds
|
||||
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278551
|
||||
if(BTOP_STATIC)
|
||||
target_link_options(btop PRIVATE LINKER:--eh-frame-hdr)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(devstat REQUIRED)
|
||||
target_link_libraries(btop devstat::devstat)
|
||||
find_package(kvm REQUIRED)
|
||||
target_link_libraries(btop devstat::devstat kvm::kvm)
|
||||
if(BTOP_STATIC)
|
||||
find_package(elf REQUIRED)
|
||||
find_package(kvm REQUIRED)
|
||||
target_link_libraries(btop elf::elf kvm::kvm)
|
||||
target_link_libraries(btop elf::elf)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_compile_options(btop PRIVATE -static-libstdc++)
|
||||
endif()
|
||||
find_package(kvm REQUIRED)
|
||||
target_link_libraries(btop kvm::kvm)
|
||||
endif()
|
||||
|
||||
|
||||
# Check if lowdown is installed
|
||||
find_program(LOWDOWN_EXECUTABLE lowdown)
|
||||
|
||||
if(LOWDOWN_EXECUTABLE)
|
||||
# Custom target to compile Markdown to man page using lowdown
|
||||
add_custom_target(btop.1 ALL
|
||||
COMMAND lowdown -s -Tman -o btop.1 manpage.md
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
# Install the man page
|
||||
install(FILES btop.1 DESTINATION "share/man/man1")
|
||||
else()
|
||||
message(WARNING "Command 'lowdown' not found: skipping generating man page btop.1")
|
||||
endif()
|
||||
|
||||
install(TARGETS btop RUNTIME)
|
||||
|
@ -191,4 +237,3 @@ install(FILES "btop.desktop" DESTINATION "share/applications")
|
|||
install(FILES "Img/icon.png" DESTINATION "share/icons/hicolor/48x48/apps" RENAME "btop.png")
|
||||
install(FILES "Img/icon.svg" DESTINATION "share/icons/hicolor/scalable/apps" RENAME "btop.svg")
|
||||
install(DIRECTORY "themes" DESTINATION "share/btop")
|
||||
|
||||
|
|
84
Makefile
84
Makefile
|
@ -50,6 +50,11 @@ ifeq ($(GPU_SUPPORT),true)
|
|||
override ADDFLAGS += -DGPU_SUPPORT
|
||||
endif
|
||||
|
||||
FORTIFY_SOURCE ?= true
|
||||
ifeq ($(FORTIFY_SOURCE),true)
|
||||
override ADDFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3
|
||||
endif
|
||||
|
||||
#? Compiler and Linker
|
||||
ifeq ($(shell $(CXX) --version | grep clang >/dev/null 2>&1; echo $$?),0)
|
||||
override CXX_IS_CLANG := true
|
||||
|
@ -92,17 +97,18 @@ ifneq ($(PLATFORM) $(ARCH),macos arm64)
|
|||
endif
|
||||
|
||||
ifeq ($(STATIC),true)
|
||||
ifeq ($(CXX_IS_CLANG) $(CLANG_WORKS),true true)
|
||||
ifeq ($(CXX_IS_CLANG),true)
|
||||
ifeq ($(shell $(CXX) -print-target-triple | grep gnu >/dev/null; echo $$?),0)
|
||||
$(error $(shell printf "\033[1;91mERROR: \033[97m$(CXX) can't statically link glibc\033[0m"))
|
||||
endif
|
||||
else
|
||||
override ADDFLAGS += -static-libgcc -static-libstdc++
|
||||
endif
|
||||
ifeq ($(PLATFORM_LC),linux)
|
||||
override ADDFLAGS += -DSTATIC_BUILD -static -Wl,--fatal-warnings
|
||||
else ifeq ($(PLATFORM_LC),freebsd)
|
||||
override ADDFLAGS += -DSTATIC_BUILD
|
||||
|
||||
ifeq ($(PLATFORM_LC),$(filter $(PLATFORM_LC),freebsd linux))
|
||||
override ADDFLAGS += -DSTATIC_BUILD -static
|
||||
else
|
||||
ifeq ($(CXX_IS_CLANG),false)
|
||||
override ADDFLAGS += -static-libgcc -static-libstdc++
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -125,9 +131,13 @@ else ifeq ($(PLATFORM_LC),freebsd)
|
|||
PLATFORM_DIR := freebsd
|
||||
THREADS := $(shell getconf NPROCESSORS_ONLN 2>/dev/null || echo 1)
|
||||
SU_GROUP := wheel
|
||||
override ADDFLAGS += -lm -lkvm -ldevstat -Wl,-rpath=/usr/local/lib/gcc$(CXX_VERSION_MAJOR)
|
||||
ifneq ($(STATIC),true)
|
||||
override ADDFLAGS += -lstdc++
|
||||
override ADDFLAGS += -lm -lkvm -ldevstat
|
||||
ifeq ($(STATIC),true)
|
||||
override ADDFLAGS += -lelf -Wl,--eh-frame-hdr
|
||||
endif
|
||||
|
||||
ifeq ($(CXX_IS_CLANG),false)
|
||||
override ADDFLAGS += -lstdc++ -Wl,rpath=/usr/local/lib/gcc$(CXX_VERSION_MAJOR)
|
||||
endif
|
||||
export MAKE = gmake
|
||||
else ifeq ($(PLATFORM_LC),macos)
|
||||
|
@ -138,7 +148,7 @@ else ifeq ($(PLATFORM_LC),macos)
|
|||
else ifeq ($(PLATFORM_LC),openbsd)
|
||||
PLATFORM_DIR := openbsd
|
||||
THREADS := $(shell sysctl -n hw.ncpu || echo 1)
|
||||
override ADDFLAGS += -lkvm
|
||||
override ADDFLAGS += -lkvm -static-libstdc++
|
||||
export MAKE = gmake
|
||||
SU_GROUP := wheel
|
||||
else
|
||||
|
@ -158,6 +168,12 @@ else
|
|||
LTO := $(THREADS)
|
||||
endif
|
||||
|
||||
GIT_COMMIT := $(shell git rev-parse --short HEAD 2> /dev/null || true)
|
||||
CONFIGURE_COMMAND := $(MAKE) STATIC=$(STATIC) FORTIFY_SOURCE=$(FORTIFY_SOURCE)
|
||||
ifeq ($(PLATFORM_LC),linux)
|
||||
CONFIGURE_COMMAND += GPU_SUPPORT=$(GPU_SUPPORT) RSMI_STATIC=$(RSMI_STATIC)
|
||||
endif
|
||||
|
||||
#? The Directories, Source, Includes, Objects and Binary
|
||||
SRCDIR := src
|
||||
INCDIRS := include $(wildcard lib/**/include)
|
||||
|
@ -174,10 +190,10 @@ override GOODFLAGS := $(foreach flag,$(TESTFLAGS),$(strip $(shell echo "int main
|
|||
override REQFLAGS := -std=c++20
|
||||
WARNFLAGS := -Wall -Wextra -pedantic
|
||||
OPTFLAGS := -O2 -ftree-vectorize -flto=$(LTO)
|
||||
LDCXXFLAGS := -pthread -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
|
||||
LDCXXFLAGS := -pthread -DFMT_HEADER_ONLY -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
|
||||
override CXXFLAGS += $(REQFLAGS) $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
|
||||
override LDFLAGS += $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
|
||||
INC := $(foreach incdir,$(INCDIRS),-isystem $(incdir)) -I$(SRCDIR)
|
||||
INC := $(foreach incdir,$(INCDIRS),-isystem $(incdir)) -I$(SRCDIR) -I$(BUILDDIR)
|
||||
SU_USER := root
|
||||
|
||||
ifdef DEBUG
|
||||
|
@ -217,7 +233,7 @@ endif
|
|||
|
||||
#? Default Make
|
||||
.ONESHELL:
|
||||
all: | info rocm_smi info-quiet directories btop
|
||||
all: | info rocm_smi info-quiet directories btop.1 config.h btop
|
||||
|
||||
ifneq ($(QUIET),true)
|
||||
info:
|
||||
|
@ -238,7 +254,6 @@ info:
|
|||
@true
|
||||
endif
|
||||
|
||||
|
||||
info-quiet: | info rocm_smi
|
||||
@printf "\n\033[1;92mBuilding btop++ \033[91m(\033[97mv$(BTOP_VERSION)\033[91m) \033[93m$(PLATFORM) \033[96m$(ARCH)\033[0m\n"
|
||||
|
||||
|
@ -262,6 +277,22 @@ directories:
|
|||
@$(VERBOSE) || printf "mkdir -p $(BUILDDIR)/$(PLATFORM_DIR)\n"
|
||||
@mkdir -p $(BUILDDIR)/$(PLATFORM_DIR)
|
||||
|
||||
config.h: $(BUILDDIR)/config.h
|
||||
|
||||
$(BUILDDIR)/config.h: $(SRCDIR)/config.h.in | directories
|
||||
@$(QUIET) || printf "\033[1mConfiguring $(BUILDDIR)/config.h\033[0m\n"
|
||||
@$(VERBOSE) || printf 'sed -e "s|@GIT_COMMIT@|$(GIT_COMMIT)|" -e "s|@CONFIGURE_COMMAND@|$(CONFIGURE_COMMAND)|" -e "s|@COMPILER@|$(CXX)|" -e "s|@COMPILER_VERSION@|$(CXX_VERSION)|" $< | tee $@ > /dev/null\n'
|
||||
@sed -e "s|@GIT_COMMIT@|$(GIT_COMMIT)|" -e "s|@CONFIGURE_COMMAND@|$(CONFIGURE_COMMAND)|" -e "s|@COMPILER@|$(CXX)|" -e "s|@COMPILER_VERSION@|$(CXX_VERSION)|" $< | tee $@ > /dev/null
|
||||
|
||||
#? Man page
|
||||
btop.1: manpage.md | directories
|
||||
ifeq ($(shell command -v lowdown >/dev/null; echo $$?),0)
|
||||
@printf "\n\033[1;92mGenerating man page $@\033[37m...\033[0m\n"
|
||||
lowdown -s -Tman -o $@ $<
|
||||
else
|
||||
@printf "\n\033[1;93mCommand 'lowdown' not found: skipping generating man page $@\033[0m\n"
|
||||
endif
|
||||
|
||||
#? Clean only Objects
|
||||
clean:
|
||||
@printf "\033[1;91mRemoving: \033[1;97mbuilt objects...\033[0m\n"
|
||||
|
@ -293,7 +324,11 @@ install:
|
|||
@printf "\033[1;92mInstalling SVG icon to: \033[1;97m$(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/btop.svg\n"
|
||||
@mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps
|
||||
@cp -p Img/icon.svg $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/btop.svg
|
||||
|
||||
ifneq ($(wildcard btop.1),)
|
||||
@printf "\033[1;92mInstalling man page to: \033[1;97m$(DESTDIR)$(PREFIX)/share/man/man1/btop.1\n"
|
||||
@mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
@cp -p btop.1 $(DESTDIR)$(PREFIX)/share/man/man1/btop.1
|
||||
endif
|
||||
|
||||
#? Set SUID bit for btop as $SU_USER in $SU_GROUP
|
||||
setuid:
|
||||
|
@ -303,17 +338,20 @@ setuid:
|
|||
@printf "\033[1;92mSetting SUID bit\033[0m\n"
|
||||
@chmod u+s $(DESTDIR)$(PREFIX)/bin/btop
|
||||
|
||||
# With 'rm -v' user will see what files (if any) got removed
|
||||
uninstall:
|
||||
@printf "\033[1;91mRemoving: \033[1;97m$(DESTDIR)$(PREFIX)/bin/btop\033[0m\n"
|
||||
@rm -rf $(DESTDIR)$(PREFIX)/bin/btop
|
||||
@rm -rfv $(DESTDIR)$(PREFIX)/bin/btop
|
||||
@printf "\033[1;91mRemoving: \033[1;97m$(DESTDIR)$(PREFIX)/share/btop\033[0m\n"
|
||||
@rm -rf $(DESTDIR)$(PREFIX)/share/btop
|
||||
@rm -rfv $(DESTDIR)$(PREFIX)/share/btop
|
||||
@printf "\033[1;91mRemoving: \033[1;97m$(DESTDIR)$(PREFIX)/share/applications/btop.desktop\033[0m\n"
|
||||
@rm -rf $(DESTDIR)$(PREFIX)/share/applications/btop.desktop
|
||||
@rm -rfv $(DESTDIR)$(PREFIX)/share/applications/btop.desktop
|
||||
@printf "\033[1;91mRemoving: \033[1;97m$(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/btop.png\033[0m\n"
|
||||
@rm -rf $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/btop.png
|
||||
@rm -rfv $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/btop.png
|
||||
@printf "\033[1;91mRemoving: \033[1;97m$(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/btop.svg\033[0m\n"
|
||||
@rm -rf $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/btop.svg
|
||||
@rm -rfv $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/btop.svg
|
||||
@printf "\033[1;91mRemoving: \033[1;97m$(DESTDIR)$(PREFIX)/share/man/man1/btop.1\033[0m\n"
|
||||
@rm -rfv $(DESTDIR)$(PREFIX)/share/man/man1/btop.1
|
||||
|
||||
#? Pull in dependency info for *existing* .o files
|
||||
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
|
||||
|
@ -357,7 +395,7 @@ btop: $(OBJECTS) | rocm_smi directories
|
|||
|
||||
#? Compile
|
||||
.ONESHELL:
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | rocm_smi directories
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | rocm_smi directories config.h
|
||||
@sleep 0.3 2>/dev/null || true
|
||||
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
|
||||
@$(QUIET) || printf "\033[1;97mCompiling $<\033[0m\n"
|
||||
|
@ -366,4 +404,4 @@ $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | rocm_smi directories
|
|||
@printf "\033[1;92m$$($(PROGRESS))$(P)\033[10D\033[5C-> \033[1;37m$@ \033[100D\033[38C\033[1;93m(\033[1;97m$$(du -ah $@ | cut -f1)iB\033[1;93m) \033[92m(\033[97m$$($(DATE_CMD) -d @$$(expr $$($(DATE_CMD) +%s 2>/dev/null || echo "0") - $${TSTAMP} 2>/dev/null) -u +%Mm:%Ss 2>/dev/null | sed 's/^00m://' || echo '')\033[92m)\033[0m\n"
|
||||
|
||||
#? Non-File Targets
|
||||
.PHONY: all msg help pre
|
||||
.PHONY: all config.h msg help pre
|
||||
|
|
133
README.md
133
README.md
|
@ -47,8 +47,8 @@
|
|||
|
||||
Btop release v1.3.0
|
||||
|
||||
Big release with GPU support added for Linux and platform support for OpenBSD. Big thanks to @romner-set (GPU support) and @joske (OpenBSD support) for contributions.
|
||||
And a multitude of bugfixes and small changes, see [CHANGES.md](CHANGES.md) and latest [release](https://github.com/aristocratos/btop/releases/latest) for detailed list and attributions.
|
||||
Big release with GPU support added for Linux and platform support for OpenBSD. Big thanks to [@romner-set](https://github.com/romner-set) (GPU support) and [@joske](https://github.com/joske) (OpenBSD support) for contributions.
|
||||
And a multitude of bugfixes and small changes, see [CHANGELOG.md](CHANGELOG.md) and latest [release](https://github.com/aristocratos/btop/releases/latest) for detailed list and attributions.
|
||||
|
||||
See news entry below for more information regarding GPU support.
|
||||
|
||||
|
@ -106,7 +106,7 @@ If you want to help out, test for bugs/fix bugs or just try out the branches:
|
|||
**macOS / OSX**
|
||||
```bash
|
||||
# Install and use Homebrew or MacPorts package managers for easy dependency installation
|
||||
brew install coreutils make gcc@11
|
||||
brew install coreutils make gcc@11 lowdown
|
||||
git clone https://github.com/aristocratos/btop.git
|
||||
cd btop
|
||||
git checkout OSX
|
||||
|
@ -115,7 +115,7 @@ gmake
|
|||
|
||||
**FreeBSD**
|
||||
```bash
|
||||
sudo pkg install gmake gcc11 coreutils git
|
||||
sudo pkg install gmake gcc11 coreutils git lowdown
|
||||
git clone https://github.com/aristocratos/btop.git
|
||||
cd btop
|
||||
git checkout freebsd
|
||||
|
@ -222,6 +222,22 @@ Also needs a UTF8 locale and a font that covers:
|
|||
* Unicode Block “Geometric Shapes” U+25A0 - U+25FF
|
||||
* Unicode Block "Box Drawing" and "Block Elements" U+2500 - U+259F
|
||||
|
||||
### **Optional Dependencies (Needed for GPU monitoring)**
|
||||
|
||||
GPU monitoring also requires a btop binary built with GPU support (`GPU_SUPPORT=true` flag).
|
||||
|
||||
See [GPU compatibility](#gpu-compatibility) section for more about compiling with GPU support.
|
||||
|
||||
* **NVIDIA**
|
||||
|
||||
If you have an NVIDIA GPU you must use an official NVIDIA driver, both the closed-source and open-source ones have been verified to work.
|
||||
|
||||
In addition to that you must also have the nvidia-ml dynamic library installed, which should be included with the driver package of your distribution.
|
||||
|
||||
* **AMD**
|
||||
|
||||
If you have an AMD GPU `rocm_smi_lib` is required, which may or may not be packaged for your distribution.
|
||||
|
||||
### **Notice (Text rendering issues)**
|
||||
|
||||
* If you are having problems with the characters in the graphs not looking like they do in the screenshots, it's likely a problem with your systems configured fallback font not having support for braille characters.
|
||||
|
@ -362,12 +378,12 @@ Also needs a UTF8 locale and a font that covers:
|
|||
|
||||
* **AMD**
|
||||
|
||||
AMDGPU data is queried using the [ROCm SMI](https://github.com/RadeonOpenCompute/rocm_smi_lib) library, which may or may not be packaged for your distribution. If your distribution doesn't provide a package, btop++ is statically linked to ROCm SMI with the `RSMI_STATIC=true` make flag.
|
||||
AMDGPU data is queried using the [ROCm SMI](https://github.com/rocm/rocm_smi_lib) library, which may or may not be packaged for your distribution. If your distribution doesn't provide a package, btop++ is statically linked to ROCm SMI with the `RSMI_STATIC=true` make flag.
|
||||
|
||||
This flag expects the ROCm SMI source code in `lib/rocm_smi_lib`, and compilation will fail if it's not there. The latest tested version is 5.6.x, which can be obtained with the following command:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/RadeonOpenCompute/rocm_smi_lib.git --depth 1 -b rocm-5.6.x lib/rocm_smi_lib
|
||||
git clone https://github.com/rocm/rocm_smi_lib.git --depth 1 -b rocm-5.6.x lib/rocm_smi_lib
|
||||
```
|
||||
|
||||
<details>
|
||||
|
@ -379,7 +395,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
1. **Install dependencies (example for Ubuntu 21.04 Hirsute)**
|
||||
|
||||
```bash
|
||||
sudo apt install coreutils sed git build-essential gcc-11 g++-11
|
||||
sudo apt install coreutils sed git build-essential gcc-11 g++-11 lowdown
|
||||
```
|
||||
|
||||
2. **Clone repository**
|
||||
|
@ -405,10 +421,11 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||
| `FORTIFY_SOURCE=false` | Disable fortification with `_FORTIFY_SOURCE=3` |
|
||||
| `GPU_SUPPORT=<true\|false>` | Enable/disable GPU support (Enabled by default on X86_64 Linux) |
|
||||
| `RSMI_STATIC=true` | To statically link the ROCm SMI library used for querying AMDGPU |
|
||||
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||
| `CXX=<compiler>` | Manually set which compiler to use |
|
||||
|
||||
Example: `make ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||
|
||||
|
@ -469,12 +486,12 @@ Also needs a UTF8 locale and a font that covers:
|
|||
|
||||
1. **Install build dependencies**
|
||||
|
||||
Requires Clang / GCC, CMake, Ninja and Git
|
||||
Requires Clang / GCC, CMake, Ninja, Lowdown and Git
|
||||
|
||||
For example, with Debian Bookworm:
|
||||
|
||||
```bash
|
||||
sudo apt install cmake git g++ ninja-build
|
||||
sudo apt install cmake git g++ ninja-build lowdown
|
||||
```
|
||||
|
||||
2. **Clone the repository**
|
||||
|
@ -503,6 +520,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
|
||||
| `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
|
||||
| `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
|
||||
| `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
|
||||
| `-DBTOP_GPU=<ON\|OFF>` | Enable GPU support (ON by default) |
|
||||
| `-DBTOP_RSMI_STATIC=<ON\|OFF>` | Build and link the ROCm SMI library statically (OFF by default) |
|
||||
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
|
||||
|
@ -551,7 +569,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
1. **Install dependencies (example for Homebrew)**
|
||||
|
||||
```bash
|
||||
brew install coreutils make gcc@12
|
||||
brew install coreutils make gcc@12 lowdown
|
||||
```
|
||||
|
||||
2. **Clone repository**
|
||||
|
@ -576,8 +594,9 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||
| `FORTIFY_SOURCE=false` | Disable fortification with `_FORTIFY_SOURCE=3` |
|
||||
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||
| `CXX=<compiler>` | Manually set which compiler to use |
|
||||
|
||||
Example: `gmake ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||
|
||||
|
@ -636,11 +655,11 @@ Also needs a UTF8 locale and a font that covers:
|
|||
|
||||
1. **Install build dependencies**
|
||||
|
||||
Requires Clang, CMake, Ninja and Git
|
||||
Requires Clang, CMake, Ninja, Lowdown and Git
|
||||
|
||||
```bash
|
||||
brew update --quiet
|
||||
brew install cmake git llvm ninja
|
||||
brew install cmake git llvm ninja lowdown
|
||||
```
|
||||
|
||||
2. **Clone the repository**
|
||||
|
@ -674,6 +693,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
|
||||
| `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
|
||||
| `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
|
||||
| `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
|
||||
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
|
||||
|
||||
To force any specific compiler, run `CXX=<compiler> cmake -B build -G Ninja`
|
||||
|
@ -716,7 +736,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
1. **Install dependencies**
|
||||
|
||||
```bash
|
||||
sudo pkg install gmake gcc11 coreutils git
|
||||
sudo pkg install gmake gcc11 coreutils git lowdown
|
||||
```
|
||||
|
||||
2. **Clone repository**
|
||||
|
@ -742,8 +762,9 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||
| `FORTIFY_SOURCE=false` | Disable fortification with `_FORTIFY_SOURCE=3` |
|
||||
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||
| `CXX=<compiler>` | Manually set which compiler to use |
|
||||
|
||||
Example: `gmake ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||
|
||||
|
@ -802,18 +823,18 @@ Also needs a UTF8 locale and a font that covers:
|
|||
|
||||
1. **Install build dependencies**
|
||||
|
||||
Requires Clang / GCC, CMake, Ninja and Git
|
||||
Requires Clang / GCC, CMake, Ninja, Lowdown and Git
|
||||
|
||||
_**Note:** LLVM's libc++ shipped with FreeBSD 13 is too old and cannot compile btop._
|
||||
|
||||
FreeBSD 14 and later:
|
||||
```bash
|
||||
pkg install cmake ninja
|
||||
pkg install cmake ninja lowdown
|
||||
```
|
||||
|
||||
FreeBSD 13:
|
||||
```bash
|
||||
pkg install cmake gcc13 ninja
|
||||
pkg install cmake gcc13 ninja lowdown
|
||||
```
|
||||
|
||||
2. **Clone the repository**
|
||||
|
@ -851,6 +872,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
|
||||
| `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
|
||||
| `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
|
||||
| `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
|
||||
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
|
||||
|
||||
_**Note:** Static linking does not work with GCC._
|
||||
|
@ -895,7 +917,7 @@ Also needs a UTF8 locale and a font that covers:
|
|||
1. **Install dependencies**
|
||||
|
||||
```bash
|
||||
pkg_add gmake gcc%11 g++%11 coreutils git
|
||||
pkg_add gmake gcc%11 g++%11 coreutils git lowdown
|
||||
```
|
||||
|
||||
2. **Clone repository**
|
||||
|
@ -921,8 +943,9 @@ Also needs a UTF8 locale and a font that covers:
|
|||
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||
| `FORTIFY_SOURCE=false` | Disable fortification with `_FORTIFY_SOURCE=3` |
|
||||
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||
| `CXX=<compiler>` | Manually set which compiler to use |
|
||||
|
||||
Example: `gmake ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||
|
||||
|
@ -972,6 +995,74 @@ Also needs a UTF8 locale and a font that covers:
|
|||
gmake help
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>
|
||||
|
||||
### With CMake (Community maintained)
|
||||
</summary>
|
||||
|
||||
1. **Install build dependencies**
|
||||
|
||||
Requires GCC, CMake, Ninja, Lowdown and Git
|
||||
|
||||
_**Note:** LLVM's libc++ shipped with OpenBSD 7.4 is too old and cannot compile btop._
|
||||
|
||||
```bash
|
||||
pkg_add cmake g++%11 git ninja lowdown
|
||||
```
|
||||
|
||||
2. **Clone the repository**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/aristocratos/btop.git && cd btop
|
||||
```
|
||||
|
||||
3. **Compile**
|
||||
|
||||
```bash
|
||||
# Configure
|
||||
CXX=eg++ cmake -B build -G Ninja
|
||||
# Build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
This will automatically build a release version of btop.
|
||||
|
||||
Some useful options to pass to the configure step:
|
||||
|
||||
| Configure flag | Description |
|
||||
|---------------------------------|-------------------------------------------------------------------------|
|
||||
| `-DBTOP_LTO=<ON\|OFF>` | Enables link time optimization (ON by default) |
|
||||
| `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
|
||||
| `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
|
||||
| `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
|
||||
| `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
|
||||
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
|
||||
|
||||
To force any other compiler, run `CXX=<compiler> cmake -B build -G Ninja`
|
||||
|
||||
4. **Install**
|
||||
|
||||
```bash
|
||||
cmake --install build
|
||||
```
|
||||
|
||||
May require root privileges
|
||||
|
||||
5. **Uninstall**
|
||||
|
||||
CMake doesn't generate an uninstall target by default. To remove installed files, run
|
||||
```
|
||||
cat build/install_manifest.txt | xargs rm -irv
|
||||
```
|
||||
|
||||
6. **Cleanup build directory**
|
||||
|
||||
```bash
|
||||
cmake --build build -t clean
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Installing the snap
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Find libkvm, the Kernel Data Access Library
|
||||
#
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
if(BSD)
|
||||
find_path(kvm_INCLUDE_DIR NAMES kvm.h)
|
||||
find_library(kvm_LIBRARY NAMES kvm)
|
||||
|
||||
|
|
57
manpage.md
Normal file
57
manpage.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
% btop(1) | User Commands
|
||||
%
|
||||
% "January 4 2024"
|
||||
|
||||
# NAME
|
||||
|
||||
btop - Resource monitor that shows usage and stats for processor, memory, disks, network, and processes.
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
**btop** [**-lc**] [**-t** | **+t**] [**-p** _id_] [**\-\-utf-force**]
|
||||
[**\-\-debug**] [{**-h** | **\-\-help**} | {**-v** | **\-\-version**}]
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
**btop** is a program that shows usage and stats for processor, memory, disks, network, and processes.
|
||||
|
||||
# OPTIONS
|
||||
|
||||
The program follows the usual GNU command line syntax, with long options
|
||||
starting with two dashes ('-'). A summary of options is included below.
|
||||
|
||||
**-lc**, **\-\-low-color**
|
||||
: Disable truecolor, converts 24-bit colors to 256-color.
|
||||
|
||||
**-t**, **\-\-tty_on**
|
||||
: Force (ON) tty mode, max 16 colors and tty-friendly graph symbols.
|
||||
|
||||
**+t**, **\-\-tty_off**
|
||||
: Force (OFF) tty mode.
|
||||
|
||||
**-p**, **\-\-preset _id_**
|
||||
: Start with preset, integer value between 0-9.
|
||||
|
||||
**\-\-utf-force**
|
||||
: Force start even if no UTF-8 locale was detected.
|
||||
|
||||
**\-\-debug**
|
||||
: Start in DEBUG mode: shows microsecond timer for information collect and screen draw functions and sets loglevel to DEBUG.
|
||||
|
||||
**-h**, **\-\-help**
|
||||
: Show summary of options.
|
||||
|
||||
**-v**, **\-\-version**
|
||||
: Show version of program.
|
||||
|
||||
# BUGS
|
||||
|
||||
The upstream bug tracker can be found at https://github.com/aristocratos/btop/issues.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
**top**(1), **htop**(1)
|
||||
|
||||
# AUTHOR
|
||||
|
||||
**btop** was written by Jakob P. Liljenberg a.k.a. "Aristocratos".
|
|
@ -6,7 +6,7 @@ description: |
|
|||
C++ version and continuation of bashtop and bpytop.
|
||||
license: Apache-2.0
|
||||
|
||||
base: core20
|
||||
base: core22
|
||||
grade: stable
|
||||
confinement: strict
|
||||
compression: lzo
|
||||
|
@ -49,6 +49,8 @@ parts:
|
|||
- PREFIX=/usr/local
|
||||
- STATIC=true
|
||||
- ADDFLAGS="-D SNAPPED"
|
||||
# Add 'lowdown' to build dependencies as soon at Snap builder updates from
|
||||
# Ubuntu 20.04 "Focal" to something newer that has Lowdown included
|
||||
build-packages:
|
||||
- coreutils
|
||||
- sed
|
||||
|
@ -56,7 +58,7 @@ parts:
|
|||
- build-essential
|
||||
- gcc-11
|
||||
- g++-11
|
||||
|
||||
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
snapcraftctl set-version "$(git describe --tags | sed 's/^v//' | cut -d "-" -f1)"
|
||||
|
|
107
src/btop.cpp
107
src/btop.cpp
|
@ -52,7 +52,9 @@ tab-size = 4
|
|||
#include "btop_theme.hpp"
|
||||
#include "btop_draw.hpp"
|
||||
#include "btop_menu.hpp"
|
||||
#include "config.h"
|
||||
#include "fmt/core.h"
|
||||
#include "fmt/ostream.h"
|
||||
|
||||
using std::atomic;
|
||||
using std::cout;
|
||||
|
@ -78,7 +80,7 @@ namespace Global {
|
|||
{"#801414", "██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝"},
|
||||
{"#000000", "╚═════╝ ╚═╝ ╚═════╝ ╚═╝"},
|
||||
};
|
||||
const string Version = "1.3.0";
|
||||
const string Version = "1.3.2";
|
||||
|
||||
int coreCount;
|
||||
string overlay;
|
||||
|
@ -108,6 +110,7 @@ namespace Global {
|
|||
atomic<bool> should_sleep (false);
|
||||
atomic<bool> _runner_started (false);
|
||||
atomic<bool> init_conf (false);
|
||||
atomic<bool> reload_conf (false);
|
||||
|
||||
bool arg_tty{};
|
||||
bool arg_low_color{};
|
||||
|
@ -115,6 +118,19 @@ namespace Global {
|
|||
int arg_update = 0;
|
||||
}
|
||||
|
||||
static void print_version() {
|
||||
if constexpr (GIT_COMMIT.empty()) {
|
||||
fmt::print("btop version: {}\n", Global::Version);
|
||||
} else {
|
||||
fmt::print("btop version: {}+{}\n", Global::Version, GIT_COMMIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_version_with_build_info() {
|
||||
print_version();
|
||||
fmt::print("Compiled with: {} ({})\nConfigured with: {}\n", COMPILER, COMPILER_VERSION, CONFIGURE_COMMAND);
|
||||
}
|
||||
|
||||
//* A simple argument parser
|
||||
void argumentParser(const int argc, char **argv) {
|
||||
for(int i = 1; i < argc; i++) {
|
||||
|
@ -136,8 +152,12 @@ void argumentParser(const int argc, char **argv) {
|
|||
);
|
||||
exit(0);
|
||||
}
|
||||
else if (is_in(argument, "-v", "--version")) {
|
||||
fmt::println("btop version: {}", Global::Version);
|
||||
else if (is_in(argument, "-v")) {
|
||||
print_version();
|
||||
exit(0);
|
||||
}
|
||||
else if (is_in(argument, "--version")) {
|
||||
print_version_with_build_info();
|
||||
exit(0);
|
||||
}
|
||||
else if (is_in(argument, "-lc", "--low-color")) {
|
||||
|
@ -364,9 +384,38 @@ void _signal_handler(const int sig) {
|
|||
case SIGUSR1:
|
||||
// Input::poll interrupt
|
||||
break;
|
||||
case SIGUSR2:
|
||||
Global::reload_conf = true;
|
||||
Input::interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//* Config init
|
||||
void init_config(){
|
||||
atomic_lock lck(Global::init_conf);
|
||||
vector<string> load_warnings;
|
||||
Config::load(Config::conf_file, load_warnings);
|
||||
Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
|
||||
|
||||
static bool first_init = true;
|
||||
|
||||
if (Global::debug and first_init) {
|
||||
Logger::set("DEBUG");
|
||||
Logger::debug("Running in DEBUG mode!");
|
||||
}
|
||||
else Logger::set(Config::getS("log_level"));
|
||||
|
||||
static string log_level;
|
||||
if (const string current_level = Config::getS("log_level"); log_level != current_level) {
|
||||
log_level = current_level;
|
||||
Logger::info("Logger set to " + (Global::debug ? "DEBUG" : log_level));
|
||||
}
|
||||
|
||||
for (const auto& err_str : load_warnings) Logger::warning(err_str);
|
||||
first_init = false;
|
||||
}
|
||||
|
||||
//* Manages secondary thread for collection and drawing of boxes
|
||||
namespace Runner {
|
||||
atomic<bool> active (false);
|
||||
|
@ -403,7 +452,7 @@ namespace Runner {
|
|||
}
|
||||
};
|
||||
|
||||
//* Wrapper for raising priviliges when using SUID bit
|
||||
//* Wrapper for raising privileges when using SUID bit
|
||||
class gain_priv {
|
||||
int status = -1;
|
||||
public:
|
||||
|
@ -836,7 +885,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
Global::start_time = time_s();
|
||||
|
||||
//? Save real and effective userid's and drop priviliges until needed if running with SUID bit set
|
||||
//? Save real and effective userid's and drop privileges until needed if running with SUID bit set
|
||||
Global::real_uid = getuid();
|
||||
Global::set_uid = geteuid();
|
||||
if (Global::real_uid != Global::set_uid) {
|
||||
|
@ -895,22 +944,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
//? Config init
|
||||
{
|
||||
atomic_lock lck(Global::init_conf);
|
||||
vector<string> load_warnings;
|
||||
Config::load(Config::conf_file, load_warnings);
|
||||
Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
|
||||
|
||||
if (Global::debug) {
|
||||
Logger::set("DEBUG");
|
||||
Logger::debug("Starting in DEBUG mode!");
|
||||
}
|
||||
else Logger::set(Config::getS("log_level"));
|
||||
|
||||
Logger::info("Logger set to " + (Global::debug ? "DEBUG" : Config::getS("log_level")));
|
||||
|
||||
for (const auto& err_str : load_warnings) Logger::warning(err_str);
|
||||
}
|
||||
init_config();
|
||||
|
||||
//? Try to find and set a UTF-8 locale
|
||||
if (std::setlocale(LC_ALL, "") != nullptr and not s_contains((string)std::setlocale(LC_ALL, ""), ";")
|
||||
|
@ -920,7 +954,7 @@ int main(int argc, char **argv) {
|
|||
else {
|
||||
string found;
|
||||
bool set_failure{};
|
||||
for (const auto loc_env : array{"LANG", "LC_ALL"}) {
|
||||
for (const auto loc_env : array{"LANG", "LC_ALL", "LC_CTYPE"}) {
|
||||
if (std::getenv(loc_env) != nullptr and str_to_upper(s_replace((string)std::getenv(loc_env), "-", "")).ends_with("UTF8")) {
|
||||
found = std::getenv(loc_env);
|
||||
if (std::setlocale(LC_ALL, found.c_str()) == nullptr) {
|
||||
|
@ -1035,6 +1069,7 @@ int main(int argc, char **argv) {
|
|||
std::signal(SIGCONT, _signal_handler);
|
||||
std::signal(SIGWINCH, _signal_handler);
|
||||
std::signal(SIGUSR1, _signal_handler);
|
||||
std::signal(SIGUSR2, _signal_handler);
|
||||
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
|
@ -1086,9 +1121,27 @@ int main(int argc, char **argv) {
|
|||
try {
|
||||
while (not true not_eq not false) {
|
||||
//? Check for exceptions in secondary thread and exit with fail signal if true
|
||||
if (Global::thread_exception) clean_quit(1);
|
||||
else if (Global::should_quit) clean_quit(0);
|
||||
else if (Global::should_sleep) { Global::should_sleep = false; _sleep(); }
|
||||
if (Global::thread_exception) {
|
||||
clean_quit(1);
|
||||
}
|
||||
else if (Global::should_quit) {
|
||||
clean_quit(0);
|
||||
}
|
||||
else if (Global::should_sleep) {
|
||||
Global::should_sleep = false;
|
||||
_sleep();
|
||||
}
|
||||
//? Hot reload config from CTRL + R or SIGUSR2
|
||||
else if (Global::reload_conf) {
|
||||
Global::reload_conf = false;
|
||||
if (Runner::active) Runner::stop();
|
||||
Config::unlock();
|
||||
init_config();
|
||||
Theme::updateThemes();
|
||||
Theme::setTheme();
|
||||
Draw::banner_gen(0, 0, false, true);
|
||||
Global::resized = true;
|
||||
}
|
||||
|
||||
//? Make sure terminal size hasn't changed (in case of SIGWINCH not working properly)
|
||||
term_resize(Global::resized);
|
||||
|
@ -1123,9 +1176,9 @@ int main(int argc, char **argv) {
|
|||
update_ms = Config::getI("update_ms");
|
||||
future_time = time_ms() + update_ms;
|
||||
}
|
||||
else if (future_time - current_time > update_ms)
|
||||
else if (future_time - current_time > update_ms) {
|
||||
future_time = current_time;
|
||||
|
||||
}
|
||||
//? Poll for input and process any input detected
|
||||
else if (Input::poll(min((uint64_t)1000, future_time - current_time))) {
|
||||
if (not Runner::active) Config::unlock();
|
||||
|
|
|
@ -199,6 +199,8 @@ namespace Config {
|
|||
|
||||
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
|
||||
|
||||
{"show_battery_watts", "#* Show power stats of battery next to charge indicator."},
|
||||
|
||||
{"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."},
|
||||
#ifdef GPU_SUPPORT
|
||||
|
@ -293,6 +295,7 @@ namespace Config {
|
|||
{"net_auto", true},
|
||||
{"net_sync", true},
|
||||
{"show_battery", true},
|
||||
{"show_battery_watts", true},
|
||||
{"vim_keys", false},
|
||||
{"tty_mode", false},
|
||||
{"disk_free_priv", false},
|
||||
|
@ -729,9 +732,9 @@ namespace Config {
|
|||
if (geteuid() != Global::real_uid and seteuid(Global::real_uid) != 0) return;
|
||||
std::ofstream cwrite(conf_file, std::ios::trunc);
|
||||
if (cwrite.good()) {
|
||||
cwrite << "#? Config file for btop v. " << Global::Version;
|
||||
cwrite << "#? Config file for btop v. " << Global::Version << "\n";
|
||||
for (auto [name, description] : descriptions) {
|
||||
cwrite << "\n\n" << (description.empty() ? "" : description + "\n")
|
||||
cwrite << "\n" << (description.empty() ? "" : description + "\n")
|
||||
<< name << " = ";
|
||||
if (strings.contains(name))
|
||||
cwrite << "\"" << strings.at(name) << "\"";
|
||||
|
@ -739,6 +742,7 @@ namespace Config {
|
|||
cwrite << ints.at(name);
|
||||
else if (bools.contains(name))
|
||||
cwrite << (bools.at(name) ? "True" : "False");
|
||||
cwrite << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -706,6 +706,7 @@ namespace Cpu {
|
|||
if (Config::getB("show_battery") and has_battery) {
|
||||
static int old_percent{}; // defaults to = 0
|
||||
static long old_seconds{}; // defaults to = 0
|
||||
static float old_watts{}; // defaults to = 0
|
||||
static string old_status;
|
||||
static Draw::Meter bat_meter {10, "cpu", true};
|
||||
static const std::unordered_map<string, string> bat_symbols = {
|
||||
|
@ -715,16 +716,18 @@ namespace Cpu {
|
|||
{"unknown", "○"}
|
||||
};
|
||||
|
||||
const auto& [percent, seconds, status] = current_bat;
|
||||
const auto& [percent, watts, seconds, status] = current_bat;
|
||||
|
||||
if (redraw or percent != old_percent or seconds != old_seconds or status != old_status) {
|
||||
if (redraw or percent != old_percent or (watts != old_watts and Config::getB("show_battery_watts")) or seconds != old_seconds or status != old_status) {
|
||||
old_percent = percent;
|
||||
old_watts = watts;
|
||||
old_seconds = seconds;
|
||||
old_status = status;
|
||||
const string str_time = (seconds > 0 ? sec_to_dhms(seconds, true, true) : "");
|
||||
const string str_time = (seconds > 0 ? sec_to_dhms(seconds, false, true) : "");
|
||||
const string str_percent = to_string(percent) + '%';
|
||||
const string str_watts = (watts != -1 and Config::getB("show_battery_watts") ? fmt::format("{:.2f}", watts) + 'W' : "");
|
||||
const auto& bat_symbol = bat_symbols.at((bat_symbols.contains(status) ? status : "unknown"));
|
||||
const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + to_string(Config::getI("update_ms")).size();
|
||||
const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + str_watts.size() + to_string(Config::getI("update_ms")).size();
|
||||
const int current_pos = Term::width - current_len - 17;
|
||||
|
||||
if ((bat_pos != current_pos or bat_len != current_len) and bat_pos > 0 and not redraw)
|
||||
|
@ -734,7 +737,7 @@ namespace Cpu {
|
|||
|
||||
out += Mv::to(y, bat_pos) + title_left + Theme::c("title") + Fx::b + "BAT" + bat_symbol + ' ' + str_percent
|
||||
+ (Term::width >= 100 ? Fx::ub + ' ' + bat_meter(percent) + Fx::b : "")
|
||||
+ (not str_time.empty() ? ' ' + Theme::c("title") + str_time : " ") + Fx::ub + title_right;
|
||||
+ (not str_time.empty() ? ' ' + Theme::c("title") + str_time : "") + (not str_watts.empty() ? " " + Theme::c("title") + Fx::b + str_watts : "") + Fx::ub + title_right;
|
||||
}
|
||||
}
|
||||
else if (bat_pos > 0) {
|
||||
|
@ -1361,6 +1364,7 @@ namespace Net {
|
|||
int x = 1, y, width = 20, height;
|
||||
int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height;
|
||||
bool shown = true, redraw = true;
|
||||
const int MAX_IFNAMSIZ = 15;
|
||||
string old_ip;
|
||||
std::unordered_map<string, Draw::Graph> graphs;
|
||||
string box;
|
||||
|
@ -1381,7 +1385,7 @@ namespace Net {
|
|||
out.reserve(width * height);
|
||||
const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left;
|
||||
const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right;
|
||||
const int i_size = min((int)selected_iface.size(), 10);
|
||||
const int i_size = min((int)selected_iface.size(), MAX_IFNAMSIZ);
|
||||
const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8);
|
||||
const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8);
|
||||
|
||||
|
@ -1403,7 +1407,7 @@ namespace Net {
|
|||
//? Interface selector and buttons
|
||||
|
||||
out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title")
|
||||
+ uresize(selected_iface, 10) + Theme::c("hi_fg") + " n>" + title_right
|
||||
+ uresize(selected_iface, MAX_IFNAMSIZ) + Theme::c("hi_fg") + " n>" + title_right
|
||||
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z'
|
||||
+ Theme::c("title") + "ero" + title_right;
|
||||
Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3};
|
||||
|
@ -2238,3 +2242,4 @@ namespace Draw {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace Input {
|
|||
//* Map for translating key codes to readable values
|
||||
const std::unordered_map<string, string> Key_escapes = {
|
||||
{"\033", "escape"},
|
||||
{"\x12", "ctrl_r"},
|
||||
{"\n", "enter"},
|
||||
{" ", "space"},
|
||||
{"\x7f", "backspace"},
|
||||
|
@ -258,8 +259,10 @@ namespace Input {
|
|||
Draw::calcSizes();
|
||||
Runner::run("all", false, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
} else if (is_in(key, "ctrl_r")) {
|
||||
kill(getpid(), SIGUSR2);
|
||||
return;
|
||||
} else
|
||||
keep_going = true;
|
||||
|
||||
if (not keep_going) return;
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Input {
|
|||
//* Last entered key
|
||||
extern deque<string> history;
|
||||
|
||||
//* Poll keyboard & mouse input for <timeout> ms and return input availabilty as a bool
|
||||
//* Poll keyboard & mouse input for <timeout> ms and return input availability as a bool
|
||||
bool poll(const uint64_t timeout=0);
|
||||
|
||||
//* Get a key or mouse action from input
|
||||
|
|
|
@ -177,6 +177,7 @@ namespace Menu {
|
|||
{"F2, o", "Shows options."},
|
||||
{"F1, ?, h", "Shows this window."},
|
||||
{"ctrl + z", "Sleep program and put in background."},
|
||||
{"ctrl + r", "Reloads config file from disk."},
|
||||
{"q, ctrl + c", "Quits program."},
|
||||
{"+, -", "Add/Subtract 100ms to/from update timer."},
|
||||
{"Up, Down", "Select in process list."},
|
||||
|
@ -190,7 +191,7 @@ namespace Menu {
|
|||
{"z", "Toggle totals reset for current network device"},
|
||||
{"a", "Toggle auto scaling for the network graphs."},
|
||||
{"y", "Toggle synced scaling mode for network graphs."},
|
||||
{"f, /", "To enter a process filter."},
|
||||
{"f, /", "To enter a process filter. Start with ! for regex."},
|
||||
{"delete", "Clear any entered filter."},
|
||||
{"c", "Toggle per-core cpu usage of processes."},
|
||||
{"r", "Reverse sorting order in processes box."},
|
||||
|
@ -353,6 +354,11 @@ namespace Menu {
|
|||
"Can be both batteries and UPS.",
|
||||
"",
|
||||
"\"Auto\" for auto detection."},
|
||||
{"show_battery_watts",
|
||||
"Show battery power.",
|
||||
"",
|
||||
"Show discharge power when discharging.",
|
||||
"Show charging power when charging."},
|
||||
{"log_level",
|
||||
"Set loglevel for error.log",
|
||||
"",
|
||||
|
@ -484,7 +490,7 @@ namespace Menu {
|
|||
"Kelvin, 0 = absolute zero, 1 degree change",
|
||||
"equals 1 degree change in Celsius.",
|
||||
"",
|
||||
"Rankine, 0 = abosulte zero, 1 degree change",
|
||||
"Rankine, 0 = absolute zero, 1 degree change",
|
||||
"equals 1 degree change in Fahrenheit."},
|
||||
{"show_cpu_freq",
|
||||
"Show CPU frequency.",
|
||||
|
@ -645,7 +651,7 @@ namespace Menu {
|
|||
"",
|
||||
"Begin line with \"exclude=\" to change to",
|
||||
"exclude filter.",
|
||||
"Oterwise defaults to \"most include\" filter.",
|
||||
"Otherwise defaults to \"most include\" filter.",
|
||||
"",
|
||||
"Example:",
|
||||
"\"exclude=/boot /home/user\""},
|
||||
|
|
|
@ -17,6 +17,8 @@ tab-size = 4
|
|||
*/
|
||||
|
||||
#include <ranges>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "btop_config.hpp"
|
||||
#include "btop_shared.hpp"
|
||||
|
@ -111,6 +113,22 @@ namespace Proc {
|
|||
}
|
||||
}
|
||||
|
||||
bool matches_filter(const proc_info& proc, const std::string& filter) {
|
||||
if (filter.starts_with("!")) {
|
||||
if (filter.size() == 1) {
|
||||
return true;
|
||||
}
|
||||
std::regex regex{filter.substr(1), std::regex::extended};
|
||||
return std::regex_search(std::to_string(proc.pid), regex) ||
|
||||
std::regex_search(proc.name, regex) || std::regex_match(proc.cmd, regex) ||
|
||||
std::regex_search(proc.user, regex);
|
||||
} else {
|
||||
return s_contains(std::to_string(proc.pid), filter) ||
|
||||
s_contains_ic(proc.name, filter) || s_contains_ic(proc.cmd, filter) ||
|
||||
s_contains_ic(proc.user, filter);
|
||||
}
|
||||
}
|
||||
|
||||
void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<tree_proc>& out_procs,
|
||||
int cur_depth, bool collapsed, const string& filter, bool found, bool no_update, bool should_filter) {
|
||||
auto cur_pos = out_procs.size();
|
||||
|
@ -118,10 +136,7 @@ namespace Proc {
|
|||
|
||||
//? If filtering, include children of matching processes
|
||||
if (not found and (should_filter or not filter.empty())) {
|
||||
if (not s_contains(std::to_string(cur_proc.pid), filter)
|
||||
and not s_contains_ic(cur_proc.name, filter)
|
||||
and not s_contains_ic(cur_proc.cmd, filter)
|
||||
and not s_contains_ic(cur_proc.user, filter)) {
|
||||
if (!matches_filter(cur_proc, filter)) {
|
||||
filtering = true;
|
||||
cur_proc.filtered = true;
|
||||
filter_found++;
|
||||
|
|
|
@ -25,10 +25,19 @@ tab-size = 4
|
|||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <ifaddrs.h>
|
||||
#include <unordered_map>
|
||||
#include <unistd.h>
|
||||
|
||||
// From `man 3 getifaddrs`: <net/if.h> must be included before <ifaddrs.h>
|
||||
// clang-format off
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
// clang-format on
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
# include <kvm.h>
|
||||
#endif
|
||||
|
||||
using std::array;
|
||||
using std::atomic;
|
||||
using std::deque;
|
||||
|
@ -83,6 +92,15 @@ namespace Shared {
|
|||
void init();
|
||||
|
||||
extern long coreCount, page_size, clk_tck;
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
struct KvmDeleter {
|
||||
void operator()(kvm_t* handle) {
|
||||
kvm_close(handle);
|
||||
}
|
||||
};
|
||||
using KvmPtr = std::unique_ptr<kvm_t, KvmDeleter>;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -178,7 +196,7 @@ namespace Cpu {
|
|||
extern string cpuName, cpuHz;
|
||||
extern vector<string> available_fields;
|
||||
extern vector<string> available_sensors;
|
||||
extern tuple<int, long, string> current_bat;
|
||||
extern tuple<int, float, long, string> current_bat;
|
||||
|
||||
struct cpu_info {
|
||||
std::unordered_map<string, deque<long long>> cpu_percent = {
|
||||
|
@ -213,7 +231,7 @@ namespace Cpu {
|
|||
auto get_cpuHz() -> string;
|
||||
|
||||
//* Get battery info from /sys
|
||||
auto get_battery() -> tuple<int, long, string>;
|
||||
auto get_battery() -> tuple<int, float, long, string>;
|
||||
}
|
||||
|
||||
namespace Mem {
|
||||
|
@ -289,6 +307,17 @@ namespace Net {
|
|||
bool connected{};
|
||||
};
|
||||
|
||||
class IfAddrsPtr {
|
||||
struct ifaddrs* ifaddr;
|
||||
int status;
|
||||
public:
|
||||
IfAddrsPtr() { status = getifaddrs(&ifaddr); }
|
||||
~IfAddrsPtr() { freeifaddrs(ifaddr); }
|
||||
[[nodiscard]] constexpr auto operator()() -> struct ifaddrs* { return ifaddr; }
|
||||
[[nodiscard]] constexpr auto get() -> struct ifaddrs* { return ifaddr; }
|
||||
[[nodiscard]] constexpr auto get_status() const noexcept -> int { return status; };
|
||||
};
|
||||
|
||||
extern std::unordered_map<string, net_info> current_net;
|
||||
|
||||
//* Collect net upload/download stats
|
||||
|
@ -395,6 +424,8 @@ namespace Proc {
|
|||
void tree_sort(vector<tree_proc>& proc_vec, const string& sorting,
|
||||
bool reverse, int& c_index, const int index_max, bool collapsed = false);
|
||||
|
||||
bool matches_filter(const proc_info& proc, const std::string& filter);
|
||||
|
||||
//* Generate process tree list
|
||||
void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<tree_proc>& out_procs,
|
||||
int cur_depth, bool collapsed, const string& filter,
|
||||
|
|
|
@ -381,11 +381,16 @@ namespace Theme {
|
|||
if (themefile.good()) {
|
||||
Logger::debug("Loading theme file: " + filename);
|
||||
while (not themefile.bad()) {
|
||||
if (themefile.peek() == '#') {
|
||||
themefile.ignore(SSmax, '\n');
|
||||
continue;
|
||||
}
|
||||
themefile.ignore(SSmax, '[');
|
||||
if (themefile.eof()) break;
|
||||
string name, value;
|
||||
getline(themefile, name, ']');
|
||||
if (not Default_theme.contains(name)) {
|
||||
themefile.ignore(SSmax, '\n');
|
||||
continue;
|
||||
}
|
||||
themefile.ignore(SSmax, '=');
|
||||
|
@ -394,6 +399,7 @@ namespace Theme {
|
|||
if (themefile.peek() == '"') {
|
||||
themefile.ignore(1);
|
||||
getline(themefile, value, '"');
|
||||
themefile.ignore(SSmax, '\n');
|
||||
}
|
||||
else getline(themefile, value, '\n');
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Theme {
|
|||
extern std::filesystem::path theme_dir;
|
||||
extern std::filesystem::path user_theme_dir;
|
||||
|
||||
//* Contains "Default" and "TTY" at indeces 0 and 1, otherwise full paths to theme files
|
||||
//* Contains "Default" and "TTY" at indices 0 and 1, otherwise full paths to theme files
|
||||
extern vector<string> themes;
|
||||
|
||||
//* Generate escape sequence for 24-bit or 256 color and return as a string
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace Term {
|
|||
}
|
||||
|
||||
bool refresh(bool only_check) {
|
||||
// Query dimensions of '/dev/tty' of the 'STDOUT_FILENO' isn't avaiable.
|
||||
// Query dimensions of '/dev/tty' of the 'STDOUT_FILENO' isn't available.
|
||||
// This variable is set in those cases to avoid calls to ioctl
|
||||
constinit static bool uses_dev_tty = false;
|
||||
struct winsize wsize {};
|
||||
|
@ -644,7 +644,7 @@ namespace Logger {
|
|||
size_t loglevel;
|
||||
fs::path logfile;
|
||||
|
||||
//* Wrapper for lowering priviliges if using SUID bit and currently isn't using real userid
|
||||
//* Wrapper for lowering privileges if using SUID bit and currently isn't using real userid
|
||||
class lose_priv {
|
||||
int status = -1;
|
||||
public:
|
||||
|
|
|
@ -18,6 +18,10 @@ tab-size = 4
|
|||
|
||||
#pragma once
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
# define BTOP_DEBUG
|
||||
#endif
|
||||
|
||||
#include <algorithm> // for std::ranges::count_if
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
|
@ -42,11 +46,9 @@ tab-size = 4
|
|||
#define HOST_NAME_MAX 64
|
||||
#endif
|
||||
#endif
|
||||
#define FMT_HEADER_ONLY
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "fmt/format.h"
|
||||
#include "fmt/ostream.h"
|
||||
#include "fmt/ranges.h"
|
||||
|
||||
using std::array;
|
||||
using std::atomic;
|
||||
|
@ -112,7 +114,7 @@ namespace Mv {
|
|||
//* Save cursor position
|
||||
const string save = Fx::e + "s";
|
||||
|
||||
//* Restore saved cursor postion
|
||||
//* Restore saved cursor position
|
||||
const string restore = Fx::e + "u";
|
||||
}
|
||||
|
||||
|
@ -284,7 +286,7 @@ namespace Tools {
|
|||
return is_in(str, "true", "True");
|
||||
}
|
||||
|
||||
//* Check if a string is a valid integer value (only postive)
|
||||
//* Check if a string is a valid integer value (only positive)
|
||||
inline bool isint(const string& str) {
|
||||
return all_of(str.begin(), str.end(), ::isdigit);
|
||||
}
|
||||
|
|
10
src/config.h.in
Normal file
10
src/config.h.in
Normal file
|
@ -0,0 +1,10 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
constexpr std::string_view GIT_COMMIT = "@GIT_COMMIT@";
|
||||
constexpr std::string_view COMPILER = "@COMPILER@";
|
||||
constexpr std::string_view COMPILER_VERSION = "@COMPILER_VERSION@";
|
||||
constexpr std::string_view CONFIGURE_COMMAND = "@CONFIGURE_COMMAND@";
|
|
@ -189,25 +189,13 @@ namespace Shared {
|
|||
Logger::debug("Init -> Mem::get_zpools()");
|
||||
Mem::get_zpools();
|
||||
}
|
||||
|
||||
//* RAII wrapper for kvm_openfiles
|
||||
class kvm_openfiles_wrapper {
|
||||
kvm_t* kd = nullptr;
|
||||
public:
|
||||
kvm_openfiles_wrapper(const char* execf, const char* coref, const char* swapf, int flags, char* err) {
|
||||
this->kd = kvm_openfiles(execf, coref, swapf, flags, err);
|
||||
}
|
||||
~kvm_openfiles_wrapper() { kvm_close(kd); }
|
||||
auto operator()() -> kvm_t* { return kd; }
|
||||
};
|
||||
|
||||
} // namespace Shared
|
||||
|
||||
namespace Cpu {
|
||||
string cpuName;
|
||||
string cpuHz;
|
||||
bool has_battery = true;
|
||||
tuple<int, long, string> current_bat;
|
||||
tuple<int, float, long, string> current_bat;
|
||||
|
||||
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
||||
|
||||
|
@ -277,7 +265,7 @@ namespace Cpu {
|
|||
got_sensors = true;
|
||||
int temp;
|
||||
size_t size = sizeof(temp);
|
||||
sysctlbyname("dev.cpu.0.coretemp.tjmax", &temp, &size, nullptr, 0); //asuming the max temp is same for all cores
|
||||
sysctlbyname("dev.cpu.0.coretemp.tjmax", &temp, &size, nullptr, 0); //assuming the max temp is same for all cores
|
||||
temp = (temp - 2732) / 10; // since it's an int, it's multiplied by 10, and offset to absolute zero...
|
||||
current_cpu.temp_max = temp;
|
||||
}
|
||||
|
@ -373,10 +361,11 @@ namespace Cpu {
|
|||
return core_map;
|
||||
}
|
||||
|
||||
auto get_battery() -> tuple<int, long, string> {
|
||||
if (not has_battery) return {0, 0, ""};
|
||||
auto get_battery() -> tuple<int, float, long, string> {
|
||||
if (not has_battery) return {0, 0, 0, ""};
|
||||
|
||||
long seconds = -1;
|
||||
float watts = -1;
|
||||
uint32_t percent = -1;
|
||||
size_t size = sizeof(percent);
|
||||
string status = "discharging";
|
||||
|
@ -388,6 +377,10 @@ namespace Cpu {
|
|||
if (sysctlbyname("hw.acpi.battery.time", &seconds, &size, nullptr, 0) < 0) {
|
||||
seconds = 0;
|
||||
}
|
||||
size = sizeof(watts);
|
||||
if (sysctlbyname("hw.acpi.battery.rate", &watts, &size, nullptr, 0) < 0) {
|
||||
watts = -1;
|
||||
}
|
||||
int state;
|
||||
size = sizeof(state);
|
||||
if (sysctlbyname("hw.acpi.battery.state", &state, &size, nullptr, 0) < 0) {
|
||||
|
@ -402,7 +395,7 @@ namespace Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
return {percent, seconds, status};
|
||||
return {percent, watts, seconds, status};
|
||||
}
|
||||
|
||||
auto collect(bool no_update) -> cpu_info & {
|
||||
|
@ -668,9 +661,9 @@ namespace Mem {
|
|||
|
||||
if (show_swap) {
|
||||
char buf[_POSIX2_LINE_MAX];
|
||||
Shared::kvm_openfiles_wrapper kd(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf);
|
||||
Shared::KvmPtr kd {kvm_openfiles(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf)};
|
||||
struct kvm_swap swap[16];
|
||||
int nswap = kvm_getswapinfo(kd(), swap, 16, 0);
|
||||
int nswap = kvm_getswapinfo(kd.get(), swap, 16, 0);
|
||||
int totalSwap = 0, usedSwap = 0;
|
||||
for (int i = 0; i < nswap; i++) {
|
||||
totalSwap += swap[i].ksw_total;
|
||||
|
@ -823,17 +816,6 @@ namespace Net {
|
|||
bool rescale = true;
|
||||
uint64_t timestamp = 0;
|
||||
|
||||
//* RAII wrapper for getifaddrs
|
||||
class getifaddr_wrapper {
|
||||
struct ifaddrs *ifaddr;
|
||||
|
||||
public:
|
||||
int status;
|
||||
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
|
||||
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
|
||||
auto operator()() -> struct ifaddrs * { return ifaddr; }
|
||||
};
|
||||
|
||||
auto collect(bool no_update) -> net_info & {
|
||||
auto &net = current_net;
|
||||
auto &config_iface = Config::getS("net_iface");
|
||||
|
@ -843,10 +825,10 @@ namespace Net {
|
|||
|
||||
if (not no_update and errors < 3) {
|
||||
//? Get interface list using getifaddrs() wrapper
|
||||
getifaddr_wrapper if_wrap{};
|
||||
if (if_wrap.status != 0) {
|
||||
IfAddrsPtr if_addrs {};
|
||||
if (if_addrs.get_status() != 0) {
|
||||
errors++;
|
||||
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_wrap.status));
|
||||
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_addrs.get_status()));
|
||||
redraw = true;
|
||||
return empty_net;
|
||||
}
|
||||
|
@ -858,7 +840,7 @@ namespace Net {
|
|||
string ipv4, ipv6;
|
||||
|
||||
//? Iteration over all items in getifaddrs() list
|
||||
for (auto *ifa = if_wrap(); ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
for (auto *ifa = if_addrs.get(); ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == nullptr) continue;
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
const auto &iface = ifa->ifa_name;
|
||||
|
@ -925,7 +907,7 @@ namespace Net {
|
|||
}
|
||||
}
|
||||
|
||||
//? Get total recieved and transmitted bytes + device address if no ip was found
|
||||
//? Get total received and transmitted bytes + device address if no ip was found
|
||||
for (const auto &iface : interfaces) {
|
||||
for (const string dir : {"download", "upload"}) {
|
||||
auto &saved_stat = net.at(iface).stat.at(dir);
|
||||
|
@ -1164,8 +1146,8 @@ namespace Proc {
|
|||
|
||||
int count = 0;
|
||||
char buf[_POSIX2_LINE_MAX];
|
||||
Shared::kvm_openfiles_wrapper kd(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf);
|
||||
const struct kinfo_proc* kprocs = kvm_getprocs(kd(), KERN_PROC_PROC, 0, &count);
|
||||
Shared::KvmPtr kd {kvm_openfiles(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf)};
|
||||
const struct kinfo_proc* kprocs = kvm_getprocs(kd.get(), KERN_PROC_PROC, 0, &count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
const struct kinfo_proc* kproc = &kprocs[i];
|
||||
|
@ -1192,7 +1174,7 @@ namespace Proc {
|
|||
continue;
|
||||
}
|
||||
new_proc.name = kproc->ki_comm;
|
||||
char** argv = kvm_getargv(kd(), kproc, 0);
|
||||
char** argv = kvm_getargv(kd.get(), kproc, 0);
|
||||
if (argv) {
|
||||
for (int i = 0; argv[i] and cmp_less(new_proc.cmd.size(), 1000); i++) {
|
||||
new_proc.cmd += argv[i] + " "s;
|
||||
|
@ -1257,18 +1239,13 @@ namespace Proc {
|
|||
filter_found = 0;
|
||||
for (auto& p : current_procs) {
|
||||
if (not tree and not filter.empty()) {
|
||||
if (not s_contains_ic(to_string(p.pid), filter)
|
||||
and not s_contains_ic(p.name, filter)
|
||||
and not s_contains_ic(p.cmd, filter)
|
||||
and not s_contains_ic(p.user, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
}
|
||||
else {
|
||||
p.filtered = false;
|
||||
}
|
||||
if (!matches_filter(p, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
} else {
|
||||
p.filtered = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
p.filtered = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,39 +158,49 @@ namespace Gpu {
|
|||
|
||||
//? AMD data collection
|
||||
namespace Rsmi {
|
||||
|
||||
//? RSMI defines, structs & typedefs
|
||||
#define RSMI_DEVICE_NAME_BUFFER_SIZE 128
|
||||
|
||||
#if !defined(RSMI_STATIC)
|
||||
//? RSMI defines, structs & typedefs
|
||||
#define RSMI_MAX_NUM_FREQUENCIES 32
|
||||
#define RSMI_STATUS_SUCCESS 0
|
||||
#define RSMI_MEM_TYPE_VRAM 0
|
||||
#define RSMI_TEMP_CURRENT 0
|
||||
#define RSMI_TEMP_TYPE_EDGE 0
|
||||
#define RSMI_CLK_TYPE_MEM 4
|
||||
#define RSMI_CLK_TYPE_SYS 0
|
||||
#define RSMI_TEMP_MAX 1
|
||||
#define RSMI_MAX_NUM_FREQUENCIES_V5 32
|
||||
#define RSMI_MAX_NUM_FREQUENCIES_V6 33
|
||||
#define RSMI_STATUS_SUCCESS 0
|
||||
#define RSMI_MEM_TYPE_VRAM 0
|
||||
#define RSMI_TEMP_CURRENT 0
|
||||
#define RSMI_TEMP_TYPE_EDGE 0
|
||||
#define RSMI_CLK_TYPE_MEM 4
|
||||
#define RSMI_CLK_TYPE_SYS 0
|
||||
#define RSMI_TEMP_MAX 1
|
||||
|
||||
typedef int rsmi_status_t,
|
||||
rsmi_temperature_metric_t,
|
||||
rsmi_clk_type_t,
|
||||
rsmi_memory_type_t;
|
||||
|
||||
struct rsmi_frequencies_t {uint32_t num_supported, current, frequency[RSMI_MAX_NUM_FREQUENCIES];};
|
||||
struct rsmi_version_t {uint32_t major, minor, patch; const char* build;};
|
||||
struct rsmi_frequencies_t_v5 {uint32_t num_supported, current; uint64_t frequency[RSMI_MAX_NUM_FREQUENCIES_V5];};
|
||||
struct rsmi_frequencies_t_v6 {bool has_deep_sleep; uint32_t num_supported, current; uint64_t frequency[RSMI_MAX_NUM_FREQUENCIES_V6];};
|
||||
|
||||
//? Function pointers
|
||||
rsmi_status_t (*rsmi_init)(uint64_t);
|
||||
rsmi_status_t (*rsmi_shut_down)();
|
||||
rsmi_status_t (*rsmi_version_get)(rsmi_version_t*);
|
||||
rsmi_status_t (*rsmi_num_monitor_devices)(uint32_t*);
|
||||
rsmi_status_t (*rsmi_dev_name_get)(uint32_t, char*, size_t);
|
||||
rsmi_status_t (*rsmi_dev_power_cap_get)(uint32_t, uint32_t, uint64_t*);
|
||||
rsmi_status_t (*rsmi_dev_temp_metric_get)(uint32_t, uint32_t, rsmi_temperature_metric_t, int64_t*);
|
||||
rsmi_status_t (*rsmi_dev_busy_percent_get)(uint32_t, uint32_t*);
|
||||
rsmi_status_t (*rsmi_dev_memory_busy_percent_get)(uint32_t, uint32_t*);
|
||||
rsmi_status_t (*rsmi_dev_gpu_clk_freq_get)(uint32_t, rsmi_clk_type_t, rsmi_frequencies_t*);
|
||||
rsmi_status_t (*rsmi_dev_gpu_clk_freq_get_v5)(uint32_t, rsmi_clk_type_t, rsmi_frequencies_t_v5*);
|
||||
rsmi_status_t (*rsmi_dev_gpu_clk_freq_get_v6)(uint32_t, rsmi_clk_type_t, rsmi_frequencies_t_v6*);
|
||||
rsmi_status_t (*rsmi_dev_power_ave_get)(uint32_t, uint32_t, uint64_t*);
|
||||
rsmi_status_t (*rsmi_dev_memory_total_get)(uint32_t, rsmi_memory_type_t, uint64_t*);
|
||||
rsmi_status_t (*rsmi_dev_memory_usage_get)(uint32_t, rsmi_memory_type_t, uint64_t*);
|
||||
rsmi_status_t (*rsmi_dev_pci_throughput_get)(uint32_t, uint64_t*, uint64_t*, uint64_t*);
|
||||
|
||||
uint32_t version_major = 0;
|
||||
|
||||
//? Data
|
||||
void* rsmi_dl_handle;
|
||||
#endif
|
||||
|
@ -294,7 +304,7 @@ namespace Cpu {
|
|||
string cpuName;
|
||||
string cpuHz;
|
||||
bool has_battery = true;
|
||||
tuple<int, long, string> current_bat;
|
||||
tuple<int, float, long, string> current_bat;
|
||||
|
||||
const array time_names {
|
||||
"user"s, "nice"s, "system"s, "idle"s, "iowait"s,
|
||||
|
@ -438,7 +448,7 @@ namespace Cpu {
|
|||
const int file_id = atoi(file.path().filename().c_str() + 4); // skip "temp" prefix
|
||||
string file_path = file.path();
|
||||
|
||||
if (!s_contains(file_path, file_suffix)) {
|
||||
if (!s_contains(file_path, file_suffix) or s_contains(file_path, "nvme")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -583,7 +593,7 @@ namespace Cpu {
|
|||
cpuhz += " GHz";
|
||||
}
|
||||
else if (hz > 0)
|
||||
cpuhz = to_string((int)round(hz)) + " MHz";
|
||||
cpuhz = to_string((int)hz) + " MHz";
|
||||
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
|
@ -664,13 +674,14 @@ namespace Cpu {
|
|||
}
|
||||
|
||||
struct battery {
|
||||
fs::path base_dir, energy_now, energy_full, power_now, status, online;
|
||||
fs::path base_dir, energy_now, charge_now, energy_full, charge_full, power_now, current_now, voltage_now, status, online;
|
||||
string device_type;
|
||||
bool use_energy = true;
|
||||
bool use_energy_or_charge = true;
|
||||
bool use_power = true;
|
||||
};
|
||||
|
||||
auto get_battery() -> tuple<int, long, string> {
|
||||
if (not has_battery) return {0, 0, ""};
|
||||
auto get_battery() -> tuple<int, float, long, string> {
|
||||
if (not has_battery) return {0, 0, 0, ""};
|
||||
static string auto_sel;
|
||||
static std::unordered_map<string, battery> batteries;
|
||||
|
||||
|
@ -702,19 +713,27 @@ namespace Cpu {
|
|||
}
|
||||
|
||||
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;
|
||||
else if (fs::exists(bat_dir / "charge_now")) new_bat.charge_now = bat_dir / "charge_now";
|
||||
else new_bat.use_energy_or_charge = 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;
|
||||
else if (fs::exists(bat_dir / "charge_full")) new_bat.charge_full = bat_dir / "charge_full";
|
||||
else new_bat.use_energy_or_charge = false;
|
||||
|
||||
if (not new_bat.use_energy and not fs::exists(bat_dir / "capacity")) {
|
||||
if (not new_bat.use_energy_or_charge 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 / "power_now")) {
|
||||
new_bat.power_now = bat_dir / "power_now";
|
||||
}
|
||||
else if ((fs::exists(bat_dir / "current_now")) and (fs::exists(bat_dir / "voltage_now"))) {
|
||||
new_bat.current_now = bat_dir / "current_now";
|
||||
new_bat.voltage_now = bat_dir / "voltage_now";
|
||||
}
|
||||
else {
|
||||
new_bat.use_power = false;
|
||||
}
|
||||
|
||||
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";
|
||||
|
@ -729,7 +748,7 @@ namespace Cpu {
|
|||
}
|
||||
if (batteries.empty()) {
|
||||
has_battery = false;
|
||||
return {0, 0, ""};
|
||||
return {0, 0, 0, ""};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -749,15 +768,9 @@ namespace Cpu {
|
|||
|
||||
int percent = -1;
|
||||
long seconds = -1;
|
||||
float watts = -1;
|
||||
|
||||
//? Try to get battery percentage
|
||||
if (b.use_energy) {
|
||||
try {
|
||||
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(b.base_dir / "capacity", "-1"));
|
||||
|
@ -765,9 +778,23 @@ namespace Cpu {
|
|||
catch (const std::invalid_argument&) { }
|
||||
catch (const std::out_of_range&) { }
|
||||
}
|
||||
if (b.use_energy_or_charge and percent < 0) {
|
||||
try {
|
||||
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 (b.use_energy_or_charge and percent < 0) {
|
||||
try {
|
||||
percent = round(100.0 * stoll(readfile(b.charge_now, "-1")) / stoll(readfile(b.charge_full, "1")));
|
||||
}
|
||||
catch (const std::invalid_argument&) { }
|
||||
catch (const std::out_of_range&) { }
|
||||
}
|
||||
if (percent < 0) {
|
||||
has_battery = false;
|
||||
return {0, 0, ""};
|
||||
return {0, 0, 0, ""};
|
||||
}
|
||||
|
||||
//? Get charging/discharging status
|
||||
|
@ -781,13 +808,23 @@ namespace Cpu {
|
|||
|
||||
//? Get seconds to empty
|
||||
if (not is_in(status, "charging", "full")) {
|
||||
if (b.use_energy and not b.power_now.empty()) {
|
||||
try {
|
||||
seconds = round((double)stoll(readfile(b.energy_now, "0")) / stoll(readfile(b.power_now, "1")) * 3600);
|
||||
if (b.use_energy_or_charge ) {
|
||||
if (not b.power_now.empty()) {
|
||||
try {
|
||||
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&) { }
|
||||
}
|
||||
else if (not b.current_now.empty()) {
|
||||
try {
|
||||
seconds = round((double)stoll(readfile(b.charge_now, "0")) / (double)stoll(readfile(b.current_now, "1")) * 3600);
|
||||
}
|
||||
catch (const std::invalid_argument&) { }
|
||||
catch (const std::out_of_range&) { }
|
||||
}
|
||||
catch (const std::invalid_argument&) { }
|
||||
catch (const std::out_of_range&) { }
|
||||
}
|
||||
|
||||
if (seconds < 0 and fs::exists(b.base_dir / "time_to_empty")) {
|
||||
try {
|
||||
seconds = stoll(readfile(b.base_dir / "time_to_empty", "0")) * 60;
|
||||
|
@ -797,7 +834,26 @@ namespace Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
return {percent, seconds, status};
|
||||
//? Get power draw
|
||||
if (b.use_power) {
|
||||
if (not b.power_now.empty()) {
|
||||
try {
|
||||
watts = (float)stoll(readfile(b.power_now, "-1")) / 1000000.0;
|
||||
}
|
||||
catch (const std::invalid_argument&) { }
|
||||
catch (const std::out_of_range&) { }
|
||||
}
|
||||
else if (not b.voltage_now.empty() and not b.current_now.empty()) {
|
||||
try {
|
||||
watts = (float)stoll(readfile(b.current_now, "-1")) / 1000000.0 * stoll(readfile(b.voltage_now, "1")) / 1000000.0;
|
||||
}
|
||||
catch (const std::invalid_argument&) { }
|
||||
catch (const std::out_of_range&) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {percent, watts, seconds, status};
|
||||
}
|
||||
|
||||
auto collect(bool no_update) -> cpu_info& {
|
||||
|
@ -1232,6 +1288,7 @@ namespace Gpu {
|
|||
"librocm_smi64.so",
|
||||
"librocm_smi64.so.5", // fedora
|
||||
"librocm_smi64.so.1.0", // debian
|
||||
"librocm_smi64.so.6"
|
||||
};
|
||||
|
||||
for (const auto& l : libRocAlts) {
|
||||
|
@ -1259,13 +1316,13 @@ namespace Gpu {
|
|||
|
||||
LOAD_SYM(rsmi_init);
|
||||
LOAD_SYM(rsmi_shut_down);
|
||||
LOAD_SYM(rsmi_version_get);
|
||||
LOAD_SYM(rsmi_num_monitor_devices);
|
||||
LOAD_SYM(rsmi_dev_name_get);
|
||||
LOAD_SYM(rsmi_dev_power_cap_get);
|
||||
LOAD_SYM(rsmi_dev_temp_metric_get);
|
||||
LOAD_SYM(rsmi_dev_busy_percent_get);
|
||||
LOAD_SYM(rsmi_dev_memory_busy_percent_get);
|
||||
LOAD_SYM(rsmi_dev_gpu_clk_freq_get);
|
||||
LOAD_SYM(rsmi_dev_power_ave_get);
|
||||
LOAD_SYM(rsmi_dev_memory_total_get);
|
||||
LOAD_SYM(rsmi_dev_memory_usage_get);
|
||||
|
@ -1281,6 +1338,27 @@ namespace Gpu {
|
|||
return false;
|
||||
}
|
||||
|
||||
#if !defined(RSMI_STATIC)
|
||||
//? Check version
|
||||
rsmi_version_t version;
|
||||
result = rsmi_version_get(&version);
|
||||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
Logger::warning("ROCm SMI: Failed to get version");
|
||||
return false;
|
||||
} else if (version.major == 5) {
|
||||
if ((rsmi_dev_gpu_clk_freq_get_v5 = (decltype(rsmi_dev_gpu_clk_freq_get_v5))load_rsmi_sym("rsmi_dev_gpu_clk_freq_get")) == nullptr)
|
||||
return false;
|
||||
// In the release tarballs of rocm 6.0.0 and 6.0.2 the version queried with rsmi_version_get is 7.0.0.0
|
||||
} else if (version.major == 6 || version.major == 7) {
|
||||
if ((rsmi_dev_gpu_clk_freq_get_v6 = (decltype(rsmi_dev_gpu_clk_freq_get_v6))load_rsmi_sym("rsmi_dev_gpu_clk_freq_get")) == nullptr)
|
||||
return false;
|
||||
} else {
|
||||
Logger::warning("ROCm SMI: Dynamic loading only supported for version 5 and 6");
|
||||
return false;
|
||||
}
|
||||
version_major = version.major;
|
||||
#endif
|
||||
|
||||
//? Device count
|
||||
result = rsmi_num_monitor_devices(&device_count);
|
||||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
|
@ -1321,8 +1399,8 @@ namespace Gpu {
|
|||
for (uint32_t i = 0; i < device_count; ++i) {
|
||||
if constexpr(is_init) {
|
||||
//? Device name
|
||||
char name[NVML_DEVICE_NAME_BUFFER_SIZE]; // ROCm SMI does not provide a constant for this as far as I can tell, this should be good enough
|
||||
result = rsmi_dev_name_get(i, name, NVML_DEVICE_NAME_BUFFER_SIZE);
|
||||
char name[RSMI_DEVICE_NAME_BUFFER_SIZE];
|
||||
result = rsmi_dev_name_get(i, name, RSMI_DEVICE_NAME_BUFFER_SIZE);
|
||||
if (result != RSMI_STATUS_SUCCESS)
|
||||
Logger::warning("ROCm SMI: Failed to get device name");
|
||||
else gpu_names[Nvml::device_count + i] = string(name);
|
||||
|
@ -1364,7 +1442,46 @@ namespace Gpu {
|
|||
if constexpr(is_init) gpus_slice[i].supported_functions.mem_utilization = false;
|
||||
} else gpus_slice[i].mem_utilization_percent.push_back((long long)utilization);
|
||||
}
|
||||
#if !defined(RSMI_STATIC)
|
||||
//? Clock speeds
|
||||
if (gpus_slice[i].supported_functions.gpu_clock) {
|
||||
if (version_major == 5) {
|
||||
rsmi_frequencies_t_v5 frequencies;
|
||||
result = rsmi_dev_gpu_clk_freq_get_v5(i, RSMI_CLK_TYPE_SYS, &frequencies);
|
||||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
Logger::warning("ROCm SMI: Failed to get GPU clock speed: ");
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.gpu_clock = false;
|
||||
} else gpus_slice[i].gpu_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
|
||||
}
|
||||
else if (version_major == 6 || version_major == 7) {
|
||||
rsmi_frequencies_t_v6 frequencies;
|
||||
result = rsmi_dev_gpu_clk_freq_get_v6(i, RSMI_CLK_TYPE_SYS, &frequencies);
|
||||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
Logger::warning("ROCm SMI: Failed to get GPU clock speed: ");
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.gpu_clock = false;
|
||||
} else gpus_slice[i].gpu_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
|
||||
}
|
||||
}
|
||||
|
||||
if (gpus_slice[i].supported_functions.mem_clock) {
|
||||
if (version_major == 5) {
|
||||
rsmi_frequencies_t_v5 frequencies;
|
||||
result = rsmi_dev_gpu_clk_freq_get_v5(i, RSMI_CLK_TYPE_MEM, &frequencies);
|
||||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
Logger::warning("ROCm SMI: Failed to get VRAM clock speed: ");
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
|
||||
} else gpus_slice[i].mem_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
|
||||
}
|
||||
else if (version_major == 6 || version_major == 7) {
|
||||
rsmi_frequencies_t_v6 frequencies;
|
||||
result = rsmi_dev_gpu_clk_freq_get_v6(i, RSMI_CLK_TYPE_MEM, &frequencies);
|
||||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
Logger::warning("ROCm SMI: Failed to get VRAM clock speed: ");
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
|
||||
} else gpus_slice[i].mem_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
|
||||
}
|
||||
}
|
||||
#else
|
||||
//? Clock speeds
|
||||
if (gpus_slice[i].supported_functions.gpu_clock) {
|
||||
rsmi_frequencies_t frequencies;
|
||||
|
@ -1383,6 +1500,7 @@ namespace Gpu {
|
|||
if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
|
||||
} else gpus_slice[i].mem_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
|
||||
}
|
||||
#endif
|
||||
|
||||
//? Power usage & state
|
||||
if (gpus_slice[i].supported_functions.pwr_usage) {
|
||||
|
@ -1391,7 +1509,10 @@ namespace Gpu {
|
|||
if (result != RSMI_STATUS_SUCCESS) {
|
||||
Logger::warning("ROCm SMI: Failed to get GPU power usage");
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.pwr_usage = false;
|
||||
} else gpus_slice[i].gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice[i].pwr_usage * 100.0 / (double)gpus_slice[i].pwr_max_usage), 0ll, 100ll));
|
||||
} else {
|
||||
gpus_slice[i].pwr_usage = (long long)power / 1000;
|
||||
gpus_slice[i].gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice[i].pwr_usage * 100.0 / (double)gpus_slice[i].pwr_max_usage), 0ll, 100ll));
|
||||
}
|
||||
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.pwr_state = false;
|
||||
}
|
||||
|
@ -1946,7 +2067,7 @@ namespace Mem {
|
|||
if (access(zfs_pool_stat_path.c_str(), R_OK) == 0) {
|
||||
return zfs_pool_stat_path;
|
||||
} else {
|
||||
Logger::debug("Cant access folder: " + zfs_pool_stat_path.string());
|
||||
Logger::debug("Can't access folder: " + zfs_pool_stat_path.string());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@ -2084,16 +2205,6 @@ namespace Net {
|
|||
bool rescale{true};
|
||||
uint64_t timestamp{};
|
||||
|
||||
//* RAII wrapper for getifaddrs
|
||||
class getifaddr_wrapper {
|
||||
struct ifaddrs* ifaddr;
|
||||
public:
|
||||
int status;
|
||||
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
|
||||
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
|
||||
auto operator()() -> struct ifaddrs* { return ifaddr; }
|
||||
};
|
||||
|
||||
auto collect(bool no_update) -> net_info& {
|
||||
if (Runner::stopping) return empty_net;
|
||||
auto& net = current_net;
|
||||
|
@ -2104,10 +2215,10 @@ namespace Net {
|
|||
|
||||
if (not no_update and errors < 3) {
|
||||
//? Get interface list using getifaddrs() wrapper
|
||||
getifaddr_wrapper if_wrap {};
|
||||
if (if_wrap.status != 0) {
|
||||
IfAddrsPtr if_addrs {};
|
||||
if (if_addrs.get_status() != 0) {
|
||||
errors++;
|
||||
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_wrap.status));
|
||||
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_addrs.get_status()));
|
||||
redraw = true;
|
||||
return empty_net;
|
||||
}
|
||||
|
@ -2119,7 +2230,7 @@ namespace Net {
|
|||
string ipv4, ipv6;
|
||||
|
||||
//? Iteration over all items in getifaddrs() list
|
||||
for (auto* ifa = if_wrap(); ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
for (auto* ifa = if_addrs.get(); ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == nullptr) continue;
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
const auto& iface = ifa->ifa_name;
|
||||
|
@ -2161,7 +2272,7 @@ namespace Net {
|
|||
} //else, ignoring family==AF_PACKET (see man 3 getifaddrs) which is the first one in the `for` loop.
|
||||
}
|
||||
|
||||
//? Get total recieved and transmitted bytes + device address if no ip was found
|
||||
//? Get total received and transmitted bytes + device address if no ip was found
|
||||
for (const auto& iface : interfaces) {
|
||||
if (net.at(iface).ipv4.empty() and net.at(iface).ipv6.empty())
|
||||
net.at(iface).ipv4 = readfile("/sys/class/net/" + iface + "/address");
|
||||
|
@ -2688,18 +2799,13 @@ namespace Proc {
|
|||
filter_found = 0;
|
||||
for (auto& p : current_procs) {
|
||||
if (not tree and not filter.empty()) {
|
||||
if (not s_contains_ic(to_string(p.pid), filter)
|
||||
and not s_contains_ic(p.name, filter)
|
||||
and not s_contains_ic(p.cmd, filter)
|
||||
and not s_contains_ic(p.user, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
}
|
||||
else {
|
||||
p.filtered = false;
|
||||
}
|
||||
if (!matches_filter(p, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
} else {
|
||||
p.filtered = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
p.filtered = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,25 +184,13 @@ namespace Shared {
|
|||
Mem::old_uptime = system_uptime();
|
||||
Mem::collect();
|
||||
}
|
||||
|
||||
//* RAII wrapper for kvm_openfiles
|
||||
class kvm_openfiles_wrapper {
|
||||
kvm_t* kd = nullptr;
|
||||
public:
|
||||
kvm_openfiles_wrapper(const char* execf, const char* coref, const char* swapf, int flags, char* err) {
|
||||
this->kd = kvm_openfiles(execf, coref, swapf, flags, err);
|
||||
}
|
||||
~kvm_openfiles_wrapper() { kvm_close(kd); }
|
||||
auto operator()() -> kvm_t* { return kd; }
|
||||
};
|
||||
|
||||
} // namespace Shared
|
||||
|
||||
namespace Cpu {
|
||||
string cpuName;
|
||||
string cpuHz;
|
||||
bool has_battery = true;
|
||||
tuple<int, long, string> current_bat;
|
||||
tuple<int, float, long, string> current_bat;
|
||||
|
||||
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
||||
|
||||
|
@ -385,8 +373,8 @@ namespace Cpu {
|
|||
return core_map;
|
||||
}
|
||||
|
||||
auto get_battery() -> tuple<int, long, string> {
|
||||
if (not has_battery) return {0, 0, ""};
|
||||
auto get_battery() -> tuple<int, float, long, string> {
|
||||
if (not has_battery) return {0, 0, 0, ""};
|
||||
|
||||
long seconds = -1;
|
||||
uint32_t percent = -1;
|
||||
|
@ -417,7 +405,7 @@ namespace Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
return {percent, seconds, status};
|
||||
return {percent, -1, seconds, status};
|
||||
}
|
||||
|
||||
auto collect(bool no_update) -> cpu_info & {
|
||||
|
@ -780,17 +768,6 @@ namespace Net {
|
|||
bool rescale = true;
|
||||
uint64_t timestamp = 0;
|
||||
|
||||
//* RAII wrapper for getifaddrs
|
||||
class getifaddr_wrapper {
|
||||
struct ifaddrs *ifaddr;
|
||||
|
||||
public:
|
||||
int status;
|
||||
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
|
||||
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
|
||||
auto operator()() -> struct ifaddrs * { return ifaddr; }
|
||||
};
|
||||
|
||||
auto collect(bool no_update) -> net_info & {
|
||||
auto &net = current_net;
|
||||
auto &config_iface = Config::getS("net_iface");
|
||||
|
@ -800,10 +777,10 @@ namespace Net {
|
|||
|
||||
if (not no_update and errors < 3) {
|
||||
//? Get interface list using getifaddrs() wrapper
|
||||
getifaddr_wrapper if_wrap{};
|
||||
if (if_wrap.status != 0) {
|
||||
IfAddrsPtr if_addrs {};
|
||||
if (if_addrs.get_status() != 0) {
|
||||
errors++;
|
||||
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_wrap.status));
|
||||
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_addrs.get_status()));
|
||||
redraw = true;
|
||||
return empty_net;
|
||||
}
|
||||
|
@ -815,7 +792,7 @@ namespace Net {
|
|||
string ipv4, ipv6;
|
||||
|
||||
//? Iteration over all items in getifaddrs() list
|
||||
for (auto *ifa = if_wrap(); ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
for (auto *ifa = if_addrs.get(); ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == nullptr) continue;
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
const auto &iface = ifa->ifa_name;
|
||||
|
@ -882,7 +859,7 @@ namespace Net {
|
|||
}
|
||||
}
|
||||
|
||||
//? Get total recieved and transmitted bytes + device address if no ip was found
|
||||
//? Get total received and transmitted bytes + device address if no ip was found
|
||||
for (const auto &iface : interfaces) {
|
||||
for (const string dir : {"download", "upload"}) {
|
||||
auto &saved_stat = net.at(iface).stat.at(dir);
|
||||
|
@ -1102,8 +1079,8 @@ namespace Proc {
|
|||
|
||||
int count = 0;
|
||||
char buf[_POSIX2_LINE_MAX];
|
||||
Shared::kvm_openfiles_wrapper kd(nullptr, nullptr, nullptr, KVM_NO_FILES, buf);
|
||||
const struct kinfo_proc* kprocs = kvm_getprocs(kd(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
|
||||
Shared::KvmPtr kd {kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, buf)};
|
||||
const struct kinfo_proc* kprocs = kvm_getprocs(kd.get() , KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
const struct kinfo_proc* kproc = &kprocs[i];
|
||||
|
@ -1130,7 +1107,7 @@ namespace Proc {
|
|||
continue;
|
||||
}
|
||||
new_proc.name = kproc->p_comm;
|
||||
char** argv = kvm_getargv(kd(), kproc, 0);
|
||||
char** argv = kvm_getargv(kd.get(), kproc, 0);
|
||||
if (argv) {
|
||||
for (int i = 0; argv[i] and cmp_less(new_proc.cmd.size(), 1000); i++) {
|
||||
new_proc.cmd += argv[i] + " "s;
|
||||
|
@ -1194,18 +1171,13 @@ namespace Proc {
|
|||
filter_found = 0;
|
||||
for (auto& p : current_procs) {
|
||||
if (not tree and not filter.empty()) {
|
||||
if (not s_contains_ic(to_string(p.pid), filter)
|
||||
and not s_contains_ic(p.name, filter)
|
||||
and not s_contains_ic(p.cmd, filter)
|
||||
and not s_contains_ic(p.user, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
}
|
||||
else {
|
||||
p.filtered = false;
|
||||
}
|
||||
if (!matches_filter(p, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
} else {
|
||||
p.filtered = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
p.filtered = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace Cpu {
|
|||
string cpuHz;
|
||||
bool has_battery = true;
|
||||
bool macM1 = false;
|
||||
tuple<int, long, string> current_bat;
|
||||
tuple<int, float, long, string> current_bat;
|
||||
|
||||
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
||||
|
||||
|
@ -407,8 +407,8 @@ namespace Cpu {
|
|||
~IOPSList_Wrap() { CFRelease(data); }
|
||||
};
|
||||
|
||||
auto get_battery() -> tuple<int, long, string> {
|
||||
if (not has_battery) return {0, 0, ""};
|
||||
auto get_battery() -> tuple<int, float, long, string> {
|
||||
if (not has_battery) return {0, 0, 0, ""};
|
||||
|
||||
uint32_t percent = -1;
|
||||
long seconds = -1;
|
||||
|
@ -447,7 +447,7 @@ namespace Cpu {
|
|||
has_battery = false;
|
||||
}
|
||||
}
|
||||
return {percent, seconds, status};
|
||||
return {percent, -1, seconds, status};
|
||||
}
|
||||
|
||||
auto collect(bool no_update) -> cpu_info & {
|
||||
|
@ -686,7 +686,7 @@ namespace Mem {
|
|||
if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&p, &info_size) == 0) {
|
||||
mem.stats.at("free") = p.free_count * Shared::pageSize;
|
||||
mem.stats.at("cached") = p.external_page_count * Shared::pageSize;
|
||||
mem.stats.at("used") = (p.active_count + p.inactive_count + p.wire_count) * Shared::pageSize;
|
||||
mem.stats.at("used") = (p.active_count + p.wire_count) * Shared::pageSize;
|
||||
mem.stats.at("available") = Shared::totalMem - mem.stats.at("used");
|
||||
}
|
||||
|
||||
|
@ -940,7 +940,7 @@ namespace Net {
|
|||
}
|
||||
}
|
||||
|
||||
//? Get total recieved and transmitted bytes + device address if no ip was found
|
||||
//? Get total received and transmitted bytes + device address if no ip was found
|
||||
for (const auto &iface : interfaces) {
|
||||
for (const string dir : {"download", "upload"}) {
|
||||
auto &saved_stat = net.at(iface).stat.at(dir);
|
||||
|
@ -1212,10 +1212,14 @@ namespace Proc {
|
|||
//? Get program name, command, username, parent pid, nice and status
|
||||
if (no_cache) {
|
||||
char fullname[PROC_PIDPATHINFO_MAXSIZE];
|
||||
proc_pidpath(pid, fullname, sizeof(fullname));
|
||||
const string f_name = std::string(fullname);
|
||||
size_t lastSlash = f_name.find_last_of('/');
|
||||
new_proc.name = f_name.substr(lastSlash + 1);
|
||||
int rc = proc_pidpath(pid, fullname, sizeof(fullname));
|
||||
string f_name = "<defunct>";
|
||||
if (rc != 0) {
|
||||
f_name = std::string(fullname);
|
||||
size_t lastSlash = f_name.find_last_of('/');
|
||||
f_name = f_name.substr(lastSlash + 1);
|
||||
}
|
||||
new_proc.name = f_name;
|
||||
//? Get process arguments if possible, fallback to process path in case of failure
|
||||
if (Shared::arg_max > 0) {
|
||||
std::unique_ptr<char[]> proc_chars(new char[Shared::arg_max]);
|
||||
|
@ -1245,7 +1249,11 @@ namespace Proc {
|
|||
new_proc.ppid = kproc.kp_eproc.e_ppid;
|
||||
new_proc.cpu_s = kproc.kp_proc.p_starttime.tv_sec * 1'000'000 + kproc.kp_proc.p_starttime.tv_usec;
|
||||
struct passwd *pwd = getpwuid(kproc.kp_eproc.e_ucred.cr_uid);
|
||||
new_proc.user = pwd->pw_name;
|
||||
if (pwd != nullptr) {
|
||||
new_proc.user = pwd->pw_name;
|
||||
} else {
|
||||
new_proc.user = std::to_string(kproc.kp_eproc.e_ucred.cr_uid);
|
||||
}
|
||||
}
|
||||
new_proc.p_nice = kproc.kp_proc.p_nice;
|
||||
new_proc.state = kproc.kp_proc.p_stat;
|
||||
|
@ -1297,7 +1305,7 @@ namespace Proc {
|
|||
filter_found = 0;
|
||||
for (auto &p : current_procs) {
|
||||
if (not tree and not filter.empty()) {
|
||||
if (not s_contains_ic(to_string(p.pid), filter) and not s_contains_ic(p.name, filter) and not s_contains_ic(p.cmd, filter) and not s_contains_ic(p.user, filter)) {
|
||||
if (!matches_filter(p, filter)) {
|
||||
p.filtered = true;
|
||||
filter_found++;
|
||||
} else {
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#cfd8dc"
|
|||
# Title color for boxes
|
||||
theme[title]="#ff"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#90"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#2e3436"
|
|||
# Title color for boxes
|
||||
theme[title]="#2e3436"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#1a5fb4"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#99DFFF"
|
|||
# Title color for boxes
|
||||
theme[title]="#99FFFF"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#FF7F00"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -11,7 +11,7 @@ theme[main_fg]="#eee8d5"
|
|||
# Title color for boxes
|
||||
theme[title]="#eee8d5"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#d1302c"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
92
themes/everforest-dark-medium.theme
Normal file
92
themes/everforest-dark-medium.theme
Normal file
|
@ -0,0 +1,92 @@
|
|||
# All graphs and meters can be gradients
|
||||
# For single color graphs leave "mid" and "end" variable empty.
|
||||
# Use "start" and "end" variables for two color gradient
|
||||
# Use "start", "mid" and "end" for three color gradient
|
||||
|
||||
# Main background, empty for terminal default, need to be empty if you want transparent background
|
||||
theme[main_bg]="#2d353b"
|
||||
|
||||
# Main text color
|
||||
theme[main_fg]="#d3c6aa"
|
||||
|
||||
# Title color for boxes
|
||||
theme[title]="#d3c6aa"
|
||||
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#e67e80"
|
||||
|
||||
# Background color of selected items
|
||||
theme[selected_bg]="#3d484d"
|
||||
|
||||
# Foreground color of selected items
|
||||
theme[selected_fg]="#dbbc7f"
|
||||
|
||||
# Color of inactive/disabled text
|
||||
theme[inactive_fg]="#2d353b"
|
||||
|
||||
# Color of text appearing on top of graphs, i.e uptime and current network graph scaling
|
||||
theme[graph_text]="#d3c6aa"
|
||||
|
||||
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||
theme[proc_misc]="#a7c080"
|
||||
|
||||
# Cpu box outline color
|
||||
theme[cpu_box]="#3d484d"
|
||||
|
||||
# Memory/disks box outline color
|
||||
theme[mem_box]="#3d484d"
|
||||
|
||||
# Net up/down box outline color
|
||||
theme[net_box]="#3d484d"
|
||||
|
||||
# Processes box outline color
|
||||
theme[proc_box]="#3d484d"
|
||||
|
||||
# Box divider line and small boxes line color
|
||||
theme[div_line]="#3d484d"
|
||||
|
||||
# Temperature graph colors
|
||||
theme[temp_start]="#a7c080"
|
||||
theme[temp_mid]="#dbbc7f"
|
||||
theme[temp_end]="#f85552"
|
||||
|
||||
# CPU graph colors
|
||||
theme[cpu_start]="#a7c080"
|
||||
theme[cpu_mid]="#dbbc7f"
|
||||
theme[cpu_end]="#f85552"
|
||||
|
||||
# Mem/Disk free meter
|
||||
theme[free_start]="#f85552"
|
||||
theme[free_mid]="#dbbc7f"
|
||||
theme[free_end]="#a7c080"
|
||||
|
||||
# Mem/Disk cached meter
|
||||
theme[cached_start]="#7fbbb3"
|
||||
theme[cached_mid]="#83c092"
|
||||
theme[cached_end]="#a7c080"
|
||||
|
||||
# Mem/Disk available meter
|
||||
theme[available_start]="#f85552"
|
||||
theme[available_mid]="#dbbc7f"
|
||||
theme[available_end]="#a7c080"
|
||||
|
||||
# Mem/Disk used meter
|
||||
theme[used_start]="#a7c080"
|
||||
theme[used_mid]="#dbbc7f"
|
||||
theme[used_end]="#f85552"
|
||||
|
||||
# Download graph colors
|
||||
theme[download_start]="#a7c080"
|
||||
theme[download_mid]="#83c092"
|
||||
theme[download_end]="#7fbbb3"
|
||||
|
||||
# Upload graph colors
|
||||
theme[upload_start]="#dbbc7f"
|
||||
theme[upload_mid]="#e69875"
|
||||
theme[upload_end]="#e67e80"
|
||||
|
||||
# Process box color gradient for threads, mem and cpu usage
|
||||
theme[process_start]="#a7c080"
|
||||
theme[process_mid]="#e67e80"
|
||||
theme[process_end]="#f85552"
|
||||
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#737680"
|
|||
# Title color for boxes
|
||||
theme[title]="#272a34"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#90"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#E6E6E6"
|
|||
# Title color for boxes
|
||||
theme[title]="#ff"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#90"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#bb"
|
|||
# Title color for boxes
|
||||
theme[title]="#cc"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#90"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#a89984"
|
|||
# Title color for boxes
|
||||
theme[title]="#ebdbb2"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#d79921"
|
||||
|
||||
# Background color of selected items
|
||||
|
|
89
themes/gruvbox_light.theme
Normal file
89
themes/gruvbox_light.theme
Normal file
|
@ -0,0 +1,89 @@
|
|||
# Btop gruvbox_light theme
|
||||
# by kk9uk
|
||||
|
||||
# Main background, empty for terminal default, need to be empty if you want transparent background
|
||||
theme[main_bg]="#fbf1c7"
|
||||
|
||||
# Main text color
|
||||
theme[main_fg]="#3c3836"
|
||||
|
||||
# Title color for boxes
|
||||
theme[title]="#3c3836"
|
||||
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#cc241d"
|
||||
|
||||
# Background color of selected items
|
||||
theme[selected_bg]="#f2e5bc"
|
||||
|
||||
# Foreground color of selected items
|
||||
theme[selected_fg]="#8f3f71"
|
||||
|
||||
# Color of inactive/disabled text
|
||||
theme[inactive_fg]="#ebdbb2"
|
||||
|
||||
# Color of text appearing on top of graphs, i.e uptime and current network graph scaling
|
||||
theme[graph_text]="#a89984"
|
||||
|
||||
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||
theme[proc_misc]="#98971a"
|
||||
|
||||
# Cpu box outline color
|
||||
theme[cpu_box]="#a89984"
|
||||
|
||||
# Memory/disks box outline color
|
||||
theme[mem_box]="#a89984"
|
||||
|
||||
# Net up/down box outline color
|
||||
theme[net_box]="#a89984"
|
||||
|
||||
# Processes box outline color
|
||||
theme[proc_box]="#a89984"
|
||||
|
||||
# Box divider line and small boxes line color
|
||||
theme[div_line]="#a89984"
|
||||
|
||||
# Temperature graph colors
|
||||
theme[temp_start]="#98971a"
|
||||
theme[temp_mid]=""
|
||||
theme[temp_end]="#cc241d"
|
||||
|
||||
# CPU graph colors
|
||||
theme[cpu_start]="#427b58"
|
||||
theme[cpu_mid]="#d79921"
|
||||
theme[cpu_end]="#cc241d"
|
||||
|
||||
# Mem/Disk free meter
|
||||
theme[free_start]="#cc241d"
|
||||
theme[free_mid]="#d79921"
|
||||
theme[free_end]="#427b58"
|
||||
|
||||
# Mem/Disk cached meter
|
||||
theme[cached_start]="#458588"
|
||||
theme[cached_mid]="#076678"
|
||||
theme[cached_end]="#427b58"
|
||||
|
||||
# Mem/Disk available meter
|
||||
theme[available_start]="#cc241d"
|
||||
theme[available_mid]="#d65d0e"
|
||||
theme[available_end]="#b57614"
|
||||
|
||||
# Mem/Disk used meter
|
||||
theme[used_start]="#427b58"
|
||||
theme[used_mid]="#d65d0e"
|
||||
theme[used_end]="#cc241d"
|
||||
|
||||
# Download graph colors
|
||||
theme[download_start]="#98971a"
|
||||
theme[download_mid]="#689d6a"
|
||||
theme[download_end]="#79740e"
|
||||
|
||||
# Upload graph colors
|
||||
theme[upload_start]="#cc241d"
|
||||
theme[upload_mid]="#d65d0e"
|
||||
theme[upload_end]="#b57614"
|
||||
|
||||
# Process box color gradient for threads, mem and cpu usage
|
||||
theme[process_start]="#427b58"
|
||||
theme[process_mid]="#af3a03"
|
||||
theme[process_end]="#cc241d"
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#d4be98"
|
|||
# Title color for boxes
|
||||
theme[title]="#d4be98"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#ea6962"
|
||||
|
||||
# Background color of selected items
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#F8F8F2"
|
|||
# Title color for boxes
|
||||
theme[title]="#F8F8F2"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#2eb398"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#F8F8F2"
|
|||
# Title color for boxes
|
||||
theme[title]="#F8F8F2"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#F92672"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#d6deeb"
|
|||
# Title color for boxes
|
||||
theme[title]="#ffffff"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#addb67"
|
||||
|
||||
# Background color of selected items
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#D8DEE9"
|
|||
# Title color for boxes
|
||||
theme[title]="#8FBCBB"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#5E81AC"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -10,7 +10,7 @@ theme[main_fg]="#abb2bf"
|
|||
# Title color for boxes
|
||||
theme[title]="#abb2bf"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#61afef"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -12,7 +12,7 @@ theme[main_fg]="#00"
|
|||
# Title color for boxes
|
||||
theme[title]="#00"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#CC3E28"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#eee8d5"
|
|||
# Title color for boxes
|
||||
theme[title]="#fdf6e3"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#b58900"
|
||||
|
||||
# Background color of selected items
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#586e75"
|
|||
# Title color for boxes
|
||||
theme[title]="#002b36"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#b58900"
|
||||
|
||||
# Background color of selected items
|
||||
|
|
|
@ -10,7 +10,7 @@ theme[main_fg]="#cfc9c2"
|
|||
# Title color for boxes
|
||||
theme[title]="#cfc9c2"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#7dcfff"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -10,7 +10,7 @@ theme[main_fg]="#cfc9c2"
|
|||
# Title color for boxes
|
||||
theme[title]="#cfc9c2"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#7dcfff"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#c5c8c6"
|
|||
# Title color for boxes
|
||||
theme[title]="#c5c8c6"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#81beb7"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
|
@ -18,7 +18,7 @@ theme[main_fg]="#30"
|
|||
# Title color for boxes
|
||||
theme[title]="#10"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#284d75"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
|
Loading…
Reference in a new issue