summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/btop.cpp13
-rw-r--r--src/btop_config.cpp184
-rw-r--r--src/btop_config.hpp16
-rw-r--r--src/btop_draw.hpp1
-rw-r--r--src/btop_linux.cpp49
-rw-r--r--src/btop_shared.hpp3
-rw-r--r--src/btop_theme.cpp96
-rw-r--r--src/btop_theme.hpp7
-rw-r--r--src/btop_tools.hpp2
-rw-r--r--themes/adapta.theme89
-rw-r--r--themes/default.theme-sample100
-rw-r--r--themes/dracula.theme89
-rw-r--r--themes/dusklight.theme95
-rw-r--r--themes/flat-remix-light.theme89
-rw-r--r--themes/flat-remix.theme89
-rw-r--r--themes/greyscale.theme89
-rw-r--r--themes/gruvbox_dark.theme92
-rw-r--r--themes/kyli0x.theme92
-rw-r--r--themes/matcha-dark-sea.theme92
-rw-r--r--themes/monokai.theme92
-rw-r--r--themes/nord.theme89
-rw-r--r--themes/solarized_dark.theme89
-rw-r--r--themes/whiteout.theme89
23 files changed, 1525 insertions, 121 deletions
diff --git a/src/btop.cpp b/src/btop.cpp
index 0cf42b6..75eb4b3 100644
--- a/src/btop.cpp
+++ b/src/btop.cpp
@@ -67,7 +67,7 @@ namespace Global {
{"#801414", "██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝"},
{"#000000", "╚═════╝ ╚═╝ ╚═════╝ ╚═╝"},
};
- std::string Version = "0.0.21";
+ const std::string Version = "0.0.21";
int coreCount;
}
@@ -178,7 +178,7 @@ void _signal_handler(int sig) {
void banner_gen() {
size_t z = 0;
string b_color, bg, fg, oc, letter;
- bool truecolor = Config::getB("truecolor");
+ auto& truecolor = Config::getB("truecolor");
int bg_i;
Global::banner.clear();
Global::banner_width = 0;
@@ -186,7 +186,7 @@ void banner_gen() {
for (auto line: Global::Banner_src) {
if (auto w = ulen(line[1]); w > Global::banner_width) Global::banner_width = w;
fg = Theme::hex_to_color(line[0], !truecolor);
- bg_i = 120-z*12;
+ bg_i = 120 - z * 12;
bg = Theme::dec_to_color(bg_i, bg_i, bg_i, !truecolor);
for (size_t i = 0; i < line[1].size(); i += 3) {
if (line[1][i] == ' ') {
@@ -238,7 +238,6 @@ int main(int argc, char **argv){
#if defined(LINUX)
Global::coreCount = sysconf(_SC_NPROCESSORS_ONLN);
if (Global::coreCount < 1) Global::coreCount = 1;
-
{
std::error_code ec;
Global::self_path = fs::read_symlink("/proc/self/exe", ec).remove_filename();
@@ -327,7 +326,7 @@ int main(int argc, char **argv){
auto thts = time_ms();
//? Generate the theme
- Theme::set(Theme::Default_theme);
+ Theme::set("Default");
//? Create the btop++ banner
banner_gen();
@@ -407,7 +406,7 @@ int main(int argc, char **argv){
exit(0);
}
- if (false) {
+ if (true) {
vector<long long> mydata;
for (long long i = 0; i <= 100; i++) mydata.push_back(i);
@@ -589,7 +588,7 @@ int main(int argc, char **argv){
cmd_cond = p.cmd.substr(0, std::min(p.cmd.find(' '), p.cmd.size()));
cmd_cond = cmd_cond.substr(std::min(cmd_cond.find_last_of('/') + 1, cmd_cond.size()));
}
- ostring += Mv::r(1) + greyscale[lc] + ljust(p.prefix + to_string(p.pid) + " " + p.name + " " + (!cmd_cond.empty() && cmd_cond != p.name ? "(" + cmd_cond + ")" : ""), Term::width - 40, true) + " "
+ ostring += Mv::r(1) + (Config::getB("tty_mode") ? " " : greyscale[lc]) + ljust(p.prefix + to_string(p.pid) + " " + p.name + " " + (!cmd_cond.empty() && cmd_cond != p.name ? "(" + cmd_cond + ")" : ""), Term::width - 40, true) + " "
+ rjust(to_string(p.threads), 5) + " " + ljust(p.user, 10) + " " + rjust(floating_humanizer(p.mem, true), 5) + string(11, ' ')
+ (p.cpu_p < 10 || p.cpu_p >= 100 ? rjust(to_string(p.cpu_p), 3) + " " : rjust(to_string(p.cpu_p), 4))
+ "\n";
diff --git a/src/btop_config.cpp b/src/btop_config.cpp
index 89c7046..f2b90ea 100644
--- a/src/btop_config.cpp
+++ b/src/btop_config.cpp
@@ -39,69 +39,120 @@ namespace Config {
bool write_new;
vector<array<string, 2>> descriptions = {
- {"color_theme", "#* Color theme, looks for a .theme file in \"/usr/[local/]share/bpytop/themes\" and \"~/.config/bpytop/themes\", \"Default\" for builtin default theme.\n"
- "#* Prefix name by a plus sign (+) for a theme located in user themes folder, i.e. color_theme=\"+monokai\"." },
- {"theme_background", "#* If the theme set background should be shown, set to False if you want terminal background transparency."},
- {"truecolor", "#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false."},
- {"graph_symbol", "#* Default symbols to use for graph creation, \"braille\", \"block\" or \"tty\".\n"
- "#* \"braille\" offers the highest resolution but might not be included in all fonts.\n"
- "#* \"block\" has half the resolution of braille but uses more common characters.\n"
- "#* \"tty\" uses only 3 different symbols but will work with most fonts and should work in a real TTY.\n"
- "#* Note that \"tty\" only has half the horizontal resolution of the other two, so will show a shorter historical view."},
- {"graph_symbol_cpu", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
- {"graph_symbol_mem", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
- {"graph_symbol_net", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
- {"graph_symbol_proc", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
- {"force_tty", "#* Set to true to true to force tty mode regardless if a real tty has been detected or not."},
- {"shown_boxes", "#* Manually set which boxes to show. Available values are \"cpu mem net proc\", separate values with whitespace."},
- {"update_ms", "#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs."},
+ {"color_theme", "#* Color theme, looks for a .theme file in \"/usr/[local/]share/bpytop/themes\" and \"~/.config/bpytop/themes\", \"Default\" for builtin default theme.\n"
+ "#* Prefix name by a plus sign (+) for a theme located in user themes folder, i.e. color_theme=\"+monokai\"." },
+
+ {"theme_background", "#* If the theme set background should be shown, set to False if you want terminal background transparency."},
+
+ {"truecolor", "#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false."},
+
+ {"force_tty", "#* Set to true to force tty mode regardless if a real tty has been detected or not.\n"
+ "#* Will force 16-color mode, set all graph symbols to \"tty\" and swap out other non tty friendly symbols."},
+
+ {"graph_symbol", "#* Default symbols to use for graph creation, \"braille\", \"block\" or \"tty\".\n"
+ "#* \"braille\" offers the highest resolution but might not be included in all fonts.\n"
+ "#* \"block\" has half the resolution of braille but uses more common characters.\n"
+ "#* \"tty\" uses only 3 different symbols but will work with most fonts and should work in a real TTY.\n"
+ "#* Note that \"tty\" only has half the horizontal resolution of the other two, so will show a shorter historical view."},
+
+ {"graph_symbol_cpu", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
+
+ {"graph_symbol_mem", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
+
+ {"graph_symbol_net", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
+
+ {"graph_symbol_proc", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
+
+ {"shown_boxes", "#* Manually set which boxes to show. Available values are \"cpu mem net proc\", separate values with whitespace."},
+
+ {"update_ms", "#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs."},
+
{"proc_update_mult", "#* Processes update multiplier, sets how often the process list is updated as a multiplier of \"update_ms\".\n"
"#* Set to 2 or higher to greatly decrease bpytop cpu usage. (Only integers)."},
- {"proc_sorting", "#* Processes sorting, \"pid\" \"program\" \"arguments\" \"threads\" \"user\" \"memory\" \"cpu lazy\" \"cpu responsive\",\n"
- "#* \"cpu lazy\" updates top process over time, \"cpu responsive\" updates top process directly."},
- {"proc_reversed", "#* Reverse sorting order, True or False."},
- {"proc_tree", "#* Show processes as a tree."},
- {"proc_colors", "#* Use the cpu graph colors in the process list."},
- {"proc_gradient", "#* Use a darkening gradient in the process list."},
- {"proc_per_core", "#* If process cpu usage should be of the core it's running on or usage of the total available cpu power."},
- {"proc_mem_bytes", "#* Show process memory as bytes instead of percent."},
- {"cpu_graph_upper", "#* Sets the CPU stat shown in upper half of the CPU graph, \"total\" is always available.\n"
- "#* Select from a list of detected attributes from the options menu."},
- {"cpu_graph_lower", "#* Sets the CPU stat shown in lower half of the CPU graph, \"total\" is always available.\n"
- "#* Select from a list of detected attributes from the options menu."},
- {"cpu_invert_lower", "#* Toggles if the lower CPU graph should be inverted."},
- {"cpu_single_graph", "#* Set to True to completely disable the lower CPU graph."},
- {"show_uptime", "#* Shows the system uptime in the CPU box."},
- {"check_temp", "#* Show cpu temperature."},
- {"cpu_sensor", "#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors."},
- {"show_coretemp", "#* Show temperatures for cpu cores also if check_temp is True and sensors has been found."},
- {"temp_scale", "#* Which temperature scale to use, available values: \"celsius\", \"fahrenheit\", \"kelvin\" and \"rankine\"."},
- {"show_cpu_freq", "#* Show CPU frequency."},
- {"draw_clock", "#* Draw a clock at top of screen, formatting according to strftime, empty string to disable."},
- {"background_update", "#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort."},
- {"custom_cpu_name", "#* Custom cpu model name, empty string to disable."},
- {"disks_filter", "#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with a comma \",\".\n"
- "#* Begin line with \"exclude=\" to change to exclude filter, otherwise defaults to \"most include\" filter. Example: disks_filter=\"exclude=/boot, /home/user\"."},
- {"mem_graphs", "#* Show graphs instead of meters for memory values."},
- {"show_swap", "#* If swap memory should be shown in memory box."},
- {"swap_disk", "#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk."},
- {"show_disks", "#* If mem box should be split to also show disks info."},
- {"only_physical", "#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar."},
- {"use_fstab", "#* Read disks list from /etc/fstab. This also disables only_physical."},
- {"show_io_stat", "#* Toggles if io stats should be shown in regular disk usage view."},
- {"io_mode", "#* Toggles io mode for disks, showing only big graphs for disk read/write speeds."},
- {"io_graph_combined", "#* Set to True to show combined read/write io graphs in io mode."},
- {"io_graph_speeds", "#* Set the top speed for the io graphs in MiB/s (10 by default), use format \"device:speed\" separate disks with a comma \",\".\n"
- "#* Example: \"/dev/sda:100, /dev/sdb:20\"."},
- {"net_download", "#* Set fixed values for network graphs, default \"10M\" = 10 Mibibytes, possible units \"K\", \"M\", \"G\", append with \"bit\" for bits instead of bytes, i.e \"100mbit\"."},
+
+ {"proc_sorting", "#* Processes sorting, \"pid\" \"program\" \"arguments\" \"threads\" \"user\" \"memory\" \"cpu lazy\" \"cpu responsive\",\n"
+ "#* \"cpu lazy\" updates top process over time, \"cpu responsive\" updates top process directly."},
+
+ {"proc_reversed", "#* Reverse sorting order, True or False."},
+
+ {"proc_tree", "#* Show processes as a tree."},
+
+ {"proc_colors", "#* Use the cpu graph colors in the process list."},
+
+ {"proc_gradient", "#* Use a darkening gradient in the process list."},
+
+ {"proc_per_core", "#* If process cpu usage should be of the core it's running on or usage of the total available cpu power."},
+
+ {"proc_mem_bytes", "#* Show process memory as bytes instead of percent."},
+
+ {"cpu_graph_upper", "#* Sets the CPU stat shown in upper half of the CPU graph, \"total\" is always available.\n"
+ "#* Select from a list of detected attributes from the options menu."},
+
+ {"cpu_graph_lower", "#* Sets the CPU stat shown in lower half of the CPU graph, \"total\" is always available.\n"
+ "#* Select from a list of detected attributes from the options menu."},
+
+ {"cpu_invert_lower", "#* Toggles if the lower CPU graph should be inverted."},
+
+ {"cpu_single_graph", "#* Set to True to completely disable the lower CPU graph."},
+
+ {"show_uptime", "#* Shows the system uptime in the CPU box."},
+
+ {"check_temp", "#* Show cpu temperature."},
+
+ {"cpu_sensor", "#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors."},
+
+ {"show_coretemp", "#* Show temperatures for cpu cores also if check_temp is True and sensors has been found."},
+
+ {"temp_scale", "#* Which temperature scale to use, available values: \"celsius\", \"fahrenheit\", \"kelvin\" and \"rankine\"."},
+
+ {"show_cpu_freq", "#* Show CPU frequency."},
+
+ {"draw_clock", "#* Draw a clock at top of screen, formatting according to strftime, empty string to disable."},
+
+ {"background_update", "#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort."},
+
+ {"custom_cpu_name", "#* Custom cpu model name, empty string to disable."},
+
+ {"disks_filter", "#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with a comma \",\".\n"
+ "#* Begin line with \"exclude=\" to change to exclude filter, otherwise defaults to \"most include\" filter. Example: disks_filter=\"exclude=/boot, /home/user\"."},
+
+ {"mem_graphs", "#* Show graphs instead of meters for memory values."},
+
+ {"show_swap", "#* If swap memory should be shown in memory box."},
+
+ {"swap_disk", "#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk."},
+
+ {"show_disks", "#* If mem box should be split to also show disks info."},
+
+ {"only_physical", "#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar."},
+
+ {"use_fstab", "#* Read disks list from /etc/fstab. This also disables only_physical."},
+
+ {"show_io_stat", "#* Toggles if io stats should be shown in regular disk usage view."},
+
+ {"io_mode", "#* Toggles io mode for disks, showing only big graphs for disk read/write speeds."},
+
+ {"io_graph_combined", "#* Set to True to show combined read/write io graphs in io mode."},
+
+ {"io_graph_speeds", "#* Set the top speed for the io graphs in MiB/s (10 by default), use format \"device:speed\" separate disks with a comma \",\".\n"
+ "#* Example: \"/dev/sda:100, /dev/sdb:20\"."},
+
+ {"net_download", "#* Set fixed values for network graphs, default \"10M\" = 10 Mibibytes, possible units \"K\", \"M\", \"G\", append with \"bit\" for bits instead of bytes, i.e \"100mbit\"."},
+
{"net_upload", ""},
- {"net_auto", "#* Start in network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest."},
- {"net_sync", "#* Sync the scaling for download and upload to whichever currently has the highest scale."},
- {"net_color_fixed", "#* If the network graphs color gradient should scale to bandwidth usage or auto scale, bandwidth usage is based on \"net_download\" and \"net_upload\" values."},
- {"net_iface", "#* Starts with the Network Interface specified here."},
- {"show_battery", "#* Show battery stats in top right if battery is present."},
- {"log_level", "#* Set loglevel for \"~/.config/bpytop/error.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
- "#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."}
+
+ {"net_auto", "#* Start in network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest."},
+
+ {"net_sync", "#* Sync the scaling for download and upload to whichever currently has the highest scale."},
+
+ {"net_color_fixed", "#* If the network graphs color gradient should scale to bandwidth usage or auto scale, bandwidth usage is based on \"net_download\" and \"net_upload\" values."},
+
+ {"net_iface", "#* Starts with the Network Interface specified here."},
+
+ {"show_battery", "#* Show battery stats in top right if battery is present."},
+
+ {"log_level", "#* Set loglevel for \"~/.config/bpytop/error.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
+ "#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."}
};
unordered_flat_map<string, string> strings = {
@@ -180,42 +231,35 @@ namespace Config {
fs::path conf_dir;
fs::path conf_file;
- vector<string> valid_graph_symbols = { "braille", "block", "tty" };
+ const vector<string> valid_graph_symbols = { "braille", "block", "tty" };
- //* Return bool config value <name>
const bool& getB(string name){
return bools.at(name);
}
- //* Return integer config value <name>
const int& getI(string name){
return ints.at(name);
}
- //* Return string config value <name>
const string& getS(string name){
return strings.at(name);
}
- //* Set config value <name> to bool <value>
void set(string name, bool value){
if (_locked(name)) boolsTmp.insert_or_assign(name, value);
else bools.at(name) = value;
}
- //* Set config value <name> to int <value>
void set(string name, int value){
if (_locked(name)) intsTmp.insert_or_assign(name, value);
ints.at(name) = value;
}
- //* Set config value <name> to string <value>
void set(string name, string value){
if (_locked(name)) stringsTmp.insert_or_assign(name, value);
else strings.at(name) = value;
}
- //* Flip config bool <name>
void flip(string name){
if (_locked(name)) {
if (boolsTmp.contains(name)) boolsTmp.at(name) = !boolsTmp.at(name);
@@ -224,12 +268,10 @@ namespace Config {
else bools.at(name) = !bools.at(name);
}
- //* Wait if locked then lock config and cache changes until unlock
void lock(){
atomic_wait_set(locked);
}
- //* Unlock config and write any cached values to config
void unlock(){
atomic_wait_set(writelock);
@@ -252,7 +294,6 @@ namespace Config {
writelock = false;
}
- //* Load the config file from disk
void load(fs::path conf_file, vector<string>& load_errors){
if (conf_file.empty())
return;
@@ -319,7 +360,6 @@ namespace Config {
}
}
- //* Write the config file to disk
void write(){
if (conf_file.empty() || !write_new) return;
Logger::debug("Writing new config file");
diff --git a/src/btop_config.hpp b/src/btop_config.hpp
index 98e239c..31b4e28 100644
--- a/src/btop_config.hpp
+++ b/src/btop_config.hpp
@@ -30,27 +30,27 @@ namespace Config {
extern std::filesystem::path conf_dir;
extern std::filesystem::path conf_file;
- extern vector<string> valid_graph_symbols;
+ extern const vector<string> valid_graph_symbols;
- //* Return bool config value <name>
+ //* Return bool for config key <name>
const bool& getB(string name);
- //* Return integer config value <name>
+ //* Return integer for config key <name>
const int& getI(string name);
- //* Return string config value <name>
+ //* Return string for config key <name>
const string& getS(string name);
- //* Set config value <name> to bool <value>
+ //* Set config key <name> to bool <value>
void set(string name, bool value);
- //* Set config value <name> to int <value>
+ //* Set config key <name> to int <value>
void set(string name, int value);
- //* Set config value <name> to string <value>
+ //* Set config key <name> to string <value>
void set(string name, string value);
- //* Flip config bool <name>
+ //* Flip config key bool <name>
void flip(string name);
//* Wait if locked then lock config and cache changes until unlock
diff --git a/src/btop_draw.hpp b/src/btop_draw.hpp
index de3d8db..afcd1bb 100644
--- a/src/btop_draw.hpp
+++ b/src/btop_draw.hpp
@@ -45,6 +45,7 @@ namespace Draw {
string line_color = "", title = "", title2 = "";
bool fill = true;
uint num=0;
+ uint w_percent=0, h_percent=0;
};
//* Create a box using values from a BoxConf struct and return as a string
diff --git a/src/btop_linux.cpp b/src/btop_linux.cpp
index 7d84e28..12e6c31 100644
--- a/src/btop_linux.cpp
+++ b/src/btop_linux.cpp
@@ -92,35 +92,29 @@ namespace Proc {
};
//* Generate process tree list
- void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<proc_info>& out_procs, int cur_depth=0, bool collapsed=false){
+ void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<proc_info>& out_procs, int cur_depth, bool collapsed, string& prefix){
auto cur_pos = out_procs.size();
if (!collapsed)
out_procs.push_back(cur_proc);
+
int children = 0;
- for (auto& p : in_procs) {
- if (p.ppid == cur_proc.pid) {
- children++;
- if (collapsed) {
- out_procs.back().cpu_p += p.cpu_p;
- out_procs.back().mem += p.mem;
- out_procs.back().threads += p.threads;
- _tree_gen(p, in_procs, out_procs, cur_depth + 1, collapsed);
- }
- else _tree_gen(p, in_procs, out_procs, cur_depth + 1, cache.at(cur_proc.pid).collapsed);
+ for (auto& p : rng::equal_range(in_procs, cur_proc.pid, rng::less{}, &proc_info::ppid)) {
+ children++;
+ if (collapsed) {
+ out_procs.back().cpu_p += p.cpu_p;
+ out_procs.back().mem += p.mem;
+ out_procs.back().threads += p.threads;
}
+ _tree_gen(p, in_procs, out_procs, cur_depth + 1, (collapsed ? true : cache.at(cur_proc.pid).collapsed), prefix);
}
if (collapsed) return;
if (out_procs.size() > cur_pos + 1 && !out_procs.back().prefix.ends_with("] ")) {
- std::string_view n_prefix = out_procs.back().prefix;
- n_prefix.remove_suffix(8);
- out_procs.back().prefix = (string)n_prefix + " └─ ";
+ out_procs.back().prefix.resize(out_procs.back().prefix.size() - 8);
+ out_procs.back().prefix += " └─ ";
}
- string prefix = " ├─ ";
- if (children > 0) prefix = (cache.at(cur_proc.pid).collapsed) ? "[+] " : "[-] ";
-
- out_procs.at(cur_pos).prefix = " │ "s * cur_depth + prefix;
+ out_procs.at(cur_pos).prefix = " │ "s * cur_depth + (children > 0 ? (cache.at(cur_proc.pid).collapsed ? "[+] " : "[-] ") : prefix);
}
vector<proc_info> current_procs;
@@ -323,13 +317,13 @@ namespace Proc {
new_proc.mem *= page_size;
}
- //* Push process to vector
+ //? Push process to vector
procs.push_back(new_proc);
}
}
//* Sort processes
- auto cmp = [&reverse](auto &a, auto &b) { return (reverse ? a < b : a > b); };
+ auto cmp = [&reverse](const auto &a, const auto &b) { return (reverse ? a < b : a > b); };
switch (v_index(sort_vector, sorting)) {
case 0: { rng::sort(procs, cmp, &proc_info::pid); break; }
case 1: { rng::sort(procs, cmp, &proc_info::name); break; }
@@ -359,9 +353,13 @@ namespace Proc {
//* Generate tree view if enabled
if (tree) {
vector<proc_info> tree_procs;
- auto min_pid = rng::min(procs, rng::less{}, &proc_info::ppid).ppid;
- for (auto& p : procs) {
- if (p.ppid == min_pid) _tree_gen(p, procs, tree_procs);
+
+ //? Stable sort to retain selected sorting among processes with the same parent
+ rng::stable_sort(procs, rng::less{}, &proc_info::ppid);
+
+ string prefix = " ├─ ";
+ for (auto& p : rng::equal_range(procs, procs.at(0).ppid, rng::less{}, &proc_info::ppid)) {
+ _tree_gen(p, procs, tree_procs, 0, cache.at(p.pid).collapsed, prefix);
}
procs.swap(tree_procs);
}
@@ -372,11 +370,10 @@ namespace Proc {
counter = 0;
unordered_flat_map<uint, p_cache> r_cache;
r_cache.reserve(pid_list.size());
- for (auto& p : pid_list) {
- if (cache.contains(p)) r_cache[p] = cache.at(p);
- }
+ rng::for_each(pid_list, [&r_cache](const auto &p){ if (cache.contains(p)) r_cache[p] = cache.at(p); });
cache.swap(r_cache);
}
+
old_cputimes = cputimes;
current_procs.swap(procs);
numpids = npids;
diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp
index 3419b81..b39bc38 100644
--- a/src/btop_shared.hpp
+++ b/src/btop_shared.hpp
@@ -26,8 +26,9 @@ tab-size = 4
using std::string, std::vector;
namespace Global {
- extern string Version;
+ extern const string Version;
extern int coreCount;
+ extern string banner;
}
namespace Tools {
diff --git a/src/btop_theme.cpp b/src/btop_theme.cpp
index 59ff663..5fe8b1c 100644
--- a/src/btop_theme.cpp
+++ b/src/btop_theme.cpp
@@ -37,6 +37,7 @@ namespace Theme {
fs::path theme_dir;
fs::path user_theme_dir;
+ vector<string> themes;
const unordered_flat_map<string, string> Default_theme = {
{ "main_bg", "#00" },
@@ -83,6 +84,51 @@ namespace Theme {
{ "process_end", "#d45454" }
};
+ const unordered_flat_map<string, string> TTY_theme = {
+ { "main_bg", "\x1b[40m" },
+ { "main_fg", "\x1b[37m" },
+ { "title", "\x1b[97m" },
+ { "hi_fg", "\x1b[31m" },
+ { "selected_bg", "\x1b[41m" },
+ { "selected_fg", "\x1b[97m" },
+ { "inactive_fg", "\x1b[90m" },
+ { "graph_text", "\x1b[37m" },
+ { "meter_bg", "\x1b[90m" },
+ { "proc_misc", "\x1b[92m" },
+ { "cpu_box", "\x1b[32m" },
+ { "mem_box", "\x1b[33m" },
+ { "net_box", "\x1b[35m" },
+ { "proc_box", "\x1b[31m" },
+ { "div_line", "\x1b[90m" },
+ { "temp_start", "\x1b[94m" },
+ { "temp_mid", "\x1b[96m" },
+ { "temp_end", "\x1b[95m" },
+ { "cpu_start", "\x1b[92m" },
+ { "cpu_mid", "\x1b[93m" },
+ { "cpu_end", "\x1b[91m" },
+ { "free_start", "\x1b[32m" },
+ { "free_mid", "" },
+ { "free_end", "\x1b[92m" },
+ { "cached_start", "\x1b[36m" },
+ { "cached_mid", "" },
+ { "cached_end", "\x1b[96m" },
+ { "available_start", "\x1b[33m" },
+ { "available_mid", "" },
+ { "available_end", "\x1b[93m" },
+ { "used_start", "\x1b[31m" },
+ { "used_mid", "" },
+ { "used_end", "\x1b[91m" },
+ { "download_start", "\x1b[34m" },
+ { "download_mid", "" },
+ { "download_end", "\x1b[94m" },
+ { "upload_start", "\x1b[35m" },
+ { "upload_mid", "" },
+ { "upload_end", "\x1b[95m" },
+ { "process_start", "\x1b[32m" },
+ { "process_mid", "\x1b[33m" },
+ { "process_end", "\x1b[31m" }
+ };
+
namespace {
//* Convert 24-bit colors to 256 colors using 6x6x6 color cube
int truecolor_to_256(int r, int g, int b){
@@ -182,7 +228,7 @@ namespace Theme {
}
//* Generate colors and rgb decimal vectors for the theme
- void generateColors(unordered_flat_map<string, string>& source){
+ void generateColors(unordered_flat_map<string, string> source){
vector<string> t_rgb;
string depth;
bool t_to_256 = !Config::getB("truecolor");
@@ -251,13 +297,55 @@ namespace Theme {
gradients[wname].swap(c_gradient);
}
}
+
+ void generateTTYColors(){
+
+ rgbs.clear();
+ colors = TTY_theme;
+
+ gradients.clear();
+
+ for (auto& c : colors) {
+ if (!c.first.ends_with("_start")) continue;
+ string base_name = rtrim(c.first, "_start");
+ string section = "_start";
+ int split = colors.at(base_name + "_mid").empty() ? 50 : 33;
+ for (int i : iota(0, 101)) {
+ gradients[base_name][i] = colors.at(base_name + section);
+ if (i == split) {
+ if (split == 50 || split == 66)
+ section = "_end";
+ else {
+ section = "_mid";
+ split *= 2;
+ }
+ }
+ }
+
+ }
+
+ }
+
+ auto loadFile(string filename){
+ unordered_flat_map<string, string> out;
+
+ return out;
+ }
+ }
+
+ void updateThemes(){
+
}
//* Set current theme using <source> map
- void set(unordered_flat_map<string, string> source){
- generateColors(source);
- generateGradients();
+ void set(string theme){
+ if (theme == "TTY" || Config::getB("tty_mode"))
+ generateTTYColors();
+ else {
+ generateColors((theme == "Default" ? Default_theme : loadFile(theme)));
+ generateGradients();
+ }
Term::fg = colors.at("main_fg");
Term::bg = colors.at("main_bg");
Fx::reset = Fx::reset_base + Term::fg + Term::bg;
diff --git a/src/btop_theme.hpp b/src/btop_theme.hpp
index 699d416..45f48a1 100644
--- a/src/btop_theme.hpp
+++ b/src/btop_theme.hpp
@@ -28,7 +28,7 @@ namespace Theme {
extern std::filesystem::path theme_dir;
extern std::filesystem::path user_theme_dir;
- extern const robin_hood::unordered_flat_map<string, string> Default_theme;
+ extern vector<string> themes;
//* Generate escape sequence for 24-bit or 256 color and return as a string
//* Args hexa: ["#000000"-"#ffffff"] for color, ["#00"-"#ff"] for greyscale
@@ -45,8 +45,11 @@ namespace Theme {
//* Return an array of red, green and blue, 0-255 values for a 24-bit color escape string
std::array<int, 3> esc_to_rgb(string c_string);
+ //* Update list of available themes
+ void updateThemes();
+
//* Set current theme using <source> map
- void set(robin_hood::unordered_flat_map<string, string> source);
+ void set(string theme);
//* Return escape code for color <name>
const string& c(string name);
diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp
index 6ab63a5..b7d1cc0 100644
--- a/src/btop_tools.hpp
+++ b/src/btop_tools.hpp
@@ -151,7 +151,7 @@ namespace Tools {
//* Check if vector <vec> contains value <find_val>
template <typename T>
- bool v_contains(vector<T>& vec, T find_val) {
+ bool v_contains(const vector<T>& vec, const T find_val) {
return std::ranges::find(vec, find_val) != vec.end();
}
diff --git a/themes/adapta.theme b/themes/adapta.theme
new file mode 100644
index 0000000..e3e2128
--- /dev/null
+++ b/themes/adapta.theme
@@ -0,0 +1,89 @@
+#Bashtop Adapta theme
+#by olokelo
+
+# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255"
+# example for white: "#ffffff", "#ff" or "255 255 255".
+
+# 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]=""
+
+# Main text color
+theme[main_fg]="#cfd8dc"
+
+# Title color for boxes
+theme[title]="#ff"
+
+# Higlight color for keyboard shortcuts
+theme[hi_fg]="#90"
+
+# Background color of selected item in processes box
+theme[selected_bg]="#bb0040"
+
+# Foreground color of selected item in processes box
+theme[selected_fg]="#ff"
+
+# Color of inactive/disabled text
+theme[inactive_fg]="#40"
+
+# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
+theme[proc_misc]="#55bcea"
+
+# Cpu box outline color
+theme[cpu_box]="#00bcd4"
+
+# Memory/disks box outline color
+theme[mem_box]="#00bcd4"
+
+# Net up/down box outline color
+theme[net_box]="#00bcd4"
+
+# Processes box outline color
+theme[proc_box]="#00bcd4"
+
+# Box divider line and small boxes line color
+theme[div_line]="#50"
+
+# Temperature graph colors
+theme[temp_start]="#00bcd4"
+theme[temp_mid]="#d4d400"
+theme[temp_end]="#ff0040"
+
+# CPU graph colors
+theme[cpu_start]="#00bcd4"
+theme[cpu_mid]="#d4d400"
+theme[cpu_end]="#ff0040"
+
+# Mem/Disk free meter
+theme[free_start]="#00bcd4"
+theme[free_mid]="#1090a0"
+theme[free_end]="#206f79"
+
+# Mem/Disk cached meter
+theme[cached_start]="#991199"
+theme[cached_mid]="#770a55"
+theme[cached_end]="#550055"
+
+# Mem/Disk available meter
+theme[available_start]="#00b0ff"
+theme[available_mid]="#1099cc"
+theme[available_end]="#2070aa"
+
+# Mem/Disk used meter
+theme[used_start]="#ff0040"
+theme[used_mid]="#ff2060"
+theme[used_end]="#ff4080"
+
+# Download graph colors
+theme[download_start]="#00bcd4"
+theme[download_mid]="#991199"
+theme[download_end]="#ff0040"
+
+# Upload graph colors
+theme[upload_start]="#00bcd4"
+theme[upload_mid]="#991199"
+theme[upload_end]="#ff0040"
diff --git a/themes/default.theme-sample b/themes/default.theme-sample
new file mode 100644
index 0000000..ff47168
--- /dev/null
+++ b/themes/default.theme-sample
@@ -0,0 +1,100 @@
+#Bashtop theme with default colors and black background
+#by aristocratos
+
+# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255"
+# example for white: "#FFFFFF", "#ff" or "255 255 255".
+
+# 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]="#00"
+
+# Main text color
+theme[main_fg]="#cc"
+
+# Title color for boxes
+theme[title]="#ee"
+
+# Highlight co