This fixes#443 and a downstream issue in nixpkgs:
https://github.com/NixOS/nixpkgs/issues/460344
Short description of the latter issue: I nixpkgs, different versions
of btop are installed under different paths. If a user selects a
theme and it is saved to the config by its absolute path, that path
will be broken after an update.
To solve this, we allow writing the theme name only into the config,
and we save the theme by name if possible.
When selecting a theme, we check if it is the first (with respect to
the load oder priority: custom > user > system) match for this
filename in the list of available themes. If it is, we save it by
filename instead of using the full path. If there is another theme
with the same name and higher priority, we save using the full path.
This should also be compatible with the previous behavior of being
able to load themes by name from $XDG_CONFIG_PATH/btop/themes.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
When proc_tree is active and left/right changes the sort column,
no_update was left as true. _tree_gen is called with no_update=true,
which skips the p.filtered=true assignment for children of collapsed
nodes while the unconditional else-if on line 211 of btop_shared.cpp
clears their stale filtered flag from the previous cycle. This leaves
collapsed children in an inconsistent state for one frame, causing a
brief visual glitch before the next full update corrects it.
Setting no_update=false only in tree mode keeps the fast path for
flat list mode unchanged.
Root processes (those whose parent is not in the tracked process list,
e.g. launchd on macOS or a top-level colima) are now left untouched by
the E hotkey. Only their descendants are collapsed or expanded.
The toggle direction is also determined solely from non-root parents,
so a tree full of root-only visible rows correctly expands on the
next E press.
Pressing E in tree mode collapses all processes if any parent is
currently expanded, or expands all if everything is already collapsed.
This gives a quick per-application resource summary without having
to manually toggle each node.
Implemented across all platforms (Linux, macOS, FreeBSD, OpenBSD, NetBSD).
When many GPUs are present and the terminal is small, the GPU graph
width calculations in Cpu::draw init_graphs and draw_graphs can
produce negative values. This causes std::out_of_range from the
Draw::Graph constructor, surfacing as "Exception in runner thread ->
Cpu:: -> deque".
The root cause is the remainder-distribution formula for the last GPU
graph: graph_width + graph_default_width%graph_width - gpus.size() + 1
which underflows when gpus.size() exceeds the available remainder plus
graph_width. The per-GPU graph_width itself can also go below 1 when
graph_default_width is small relative to gpu_draw_count.
Clamp both graph_width and the last-GPU width to a minimum of 1, and
clamp the cursor movement arguments in draw_graphs to prevent negative
Mv::l and Mv::r values.