From 48f6425e6c7f58126dff95eb12ca2900719b47d1 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Sun, 26 Nov 2023 17:54:28 +1100 Subject: [PATCH] refactor: use a custom command, set in config as `copy_command`, to copy to clipboard instead, to support all windowing systems --- src/btop_config.cpp | 5 +++++ src/btop_draw.cpp | 3 +++ src/btop_input.cpp | 16 ++++++++++++++++ src/btop_shared.hpp | 2 +- src/linux/btop_collect.cpp | 9 ++++++--- src/osx/btop_collect.cpp | 6 +++--- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/btop_config.cpp b/src/btop_config.cpp index 6ddfd43..3233aad 100644 --- a/src/btop_config.cpp +++ b/src/btop_config.cpp @@ -65,6 +65,8 @@ namespace Config { {"vim_keys", "#* Set to True to enable \"h,j,k,l,g,G\" keys for directional control in lists.\n" "#* Conflicting keys for h:\"help\" and k:\"kill\" is accessible while holding shift."}, + {"copy_command", "#* Command to copy to the system clipboard. Clipboard contents are piped into stdin."}, + {"rounded_corners", "#* Rounded corners on boxes, is ignored if TTY mode is ON."}, {"graph_symbol", "#* Default symbols to use for graph creation, \"braille\", \"block\" or \"tty\".\n" @@ -221,6 +223,7 @@ namespace Config { {"shown_boxes", "cpu mem net proc"}, {"graph_symbol", "braille"}, {"presets", "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"}, + {"copy_command", ""}, {"graph_symbol_cpu", "default"}, {"graph_symbol_gpu", "default"}, {"graph_symbol_mem", "default"}, @@ -242,6 +245,7 @@ namespace Config { {"proc_filter", ""}, {"proc_command", ""}, {"selected_name", ""}, + {"selected_cmd", ""}, #ifdef GPU_SUPPORT {"custom_gpu_name0", ""}, {"custom_gpu_name1", ""}, @@ -525,6 +529,7 @@ namespace Config { if (Proc::shown) { ints.at("selected_pid") = Proc::selected_pid; strings.at("selected_name") = Proc::selected_name; + strings.at("selected_cmd") = Proc::selected_cmd; ints.at("proc_start") = Proc::start; ints.at("proc_selected") = Proc::selected; ints.at("selected_depth") = Proc::selected_depth; diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 97195f1..865a264 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -1462,6 +1462,7 @@ namespace Proc { bool shown = true, redraw = true; int selected_pid = 0, selected_depth = 0; string selected_name; + string selected_cmd; std::unordered_map p_graphs; std::unordered_map p_wide_cmd; std::unordered_map p_counters; @@ -1712,6 +1713,7 @@ namespace Proc { mouse_x += 6; } out += title_left_down + Fx::b + hi_color + 's' + t_color + "ignals" + Fx::ub + title_right_down; + out += title_left_down + Fx::b + t_color + "copy cmd" + Fx::b + hi_color + " y" + t_color + Fx::ub + title_right_down; if (selected > 0) Input::mouse_mappings["s"] = {y + height - 1, mouse_x, 1, 7}; //? Labels for fields in list @@ -1788,6 +1790,7 @@ namespace Proc { if (is_selected) { selected_pid = (int)p.pid; selected_name = p.name; + selected_cmd = p.cmd; selected_depth = p.depth; } diff --git a/src/btop_input.cpp b/src/btop_input.cpp index fb9e46d..82cc246 100644 --- a/src/btop_input.cpp +++ b/src/btop_input.cpp @@ -463,6 +463,22 @@ namespace Input { else if (old_selected != new_selected and (old_selected == 0 or new_selected == 0)) redraw = true; } + else if (key == "y") { + atomic_wait(Runner::active); + + auto copy_command = Config::getS("copy_command"); + if (copy_command.empty()) { + vector cont_vec; + cont_vec.emplace_back("`copy_command` is empty"); + Menu::msgBox messageBox = Menu::msgBox{45, 0, cont_vec, "error"}; + Global::overlay = messageBox(); + } else { + FILE *p_copy_stdin = popen(copy_command.c_str(), "w"); + auto selected_cmd = Config::getS("selected_cmd"); + fwrite(selected_cmd.c_str(), sizeof(char), selected_cmd.length(), p_copy_stdin); + pclose(p_copy_stdin); + } + } else keep_going = true; if (not keep_going) { diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index ebd1073..a08921c 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -306,7 +306,7 @@ namespace Proc { extern int select_max; extern atomic detailed_pid; extern int selected_pid, start, selected, collapse, expand, filter_found, selected_depth; - extern string selected_name; + extern string selected_name, selected_cmd; //? Contains the valid sorting options for processes const vector sort_vector = { diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index 677c3fe..0601be0 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -210,7 +210,7 @@ namespace Mem { namespace Shared { fs::path procPath, passwd_path; - long pageSize, clkTck, coreCount; + long pageSize, clkTck, coreCount, arg_max; void init() { @@ -244,6 +244,9 @@ namespace Shared { Logger::warning("Could not get system clock ticks per second. Defaulting to 100, processes cpu usage might be incorrect."); } + //* Get maximum length of process arguments + arg_max = sysconf(_SC_ARG_MAX); + //? Init for namespace Cpu if (not fs::exists(Cpu::freq_path) or access(Cpu::freq_path.c_str(), R_OK) == -1) Cpu::freq_path.clear(); Cpu::current_cpu.core_percent.insert(Cpu::current_cpu.core_percent.begin(), Shared::coreCount, {}); @@ -2529,8 +2532,8 @@ namespace Proc { long_string.clear(); while(getline(pread, long_string, '\0')) { new_proc.cmd += long_string + ' '; - if (new_proc.cmd.size() > 1000) { - new_proc.cmd.resize(1000); + if (new_proc.cmd.size() > static_cast(Shared::arg_max)) { + new_proc.cmd.resize(Shared::arg_max); break; } } diff --git a/src/osx/btop_collect.cpp b/src/osx/btop_collect.cpp index 76b63c0..6bdedfd 100644 --- a/src/osx/btop_collect.cpp +++ b/src/osx/btop_collect.cpp @@ -1227,7 +1227,7 @@ namespace Proc { std::string_view proc_args(proc_chars.get(), argmax); if (size_t null_pos = proc_args.find('\0', sizeof(argc)); null_pos != string::npos) { if (size_t start_pos = proc_args.find_first_not_of('\0', null_pos); start_pos != string::npos) { - while (argc-- > 0 and null_pos != string::npos and cmp_less(new_proc.cmd.size(), 1000)) { + while (argc-- > 0 and null_pos != string::npos and cmp_less(new_proc.cmd.size(), argmax)) { null_pos = proc_args.find('\0', start_pos); new_proc.cmd += (string)proc_args.substr(start_pos, null_pos - start_pos) + ' '; start_pos = null_pos + 1; @@ -1238,8 +1238,8 @@ namespace Proc { } } if (new_proc.cmd.empty()) new_proc.cmd = f_name; - if (new_proc.cmd.size() > 1000) { - new_proc.cmd.resize(1000); + if (new_proc.cmd.size() > static_cast(Shared::arg_max)) { + new_proc.cmd.resize(Shared::arg_max); new_proc.cmd.shrink_to_fit(); } new_proc.ppid = kproc.kp_eproc.e_ppid;