Fixes and Improvements for Pause and Follow modes

Reselection Issues with Pause and Follow

- I found an edge case I had missed before for the very end of the process
  list (not view). For the process list pausing feature, if the process
  selected was the very last item in the whole list then the selection was
  moved up one. And vice versa when the list is paused and the very last
  item is selected, unpausing would also move it up one item in the list.
  For the process following feature the same thing would happen when
  unfollowing (if not using the detailed view follow) but for the last few
  items (upto halfway up the view)

  - This was fixed by adding 1 to either `selected` or `start` when
    required.

- When process following with detailed view. unfollowing by clicking the
  process and then clicking again to close detail view threw the view
  off because following was disengaged.

  - Fixed with the modification to the code block that handles
    following. It now also restores the selection and view when exiting
    detailed view also. (I had a different fix for this but the fix for
    the next issue made it irrelevant and was removed)

- If following a process with detailed view and it is one of the first
  or last few items in the whole list (not view) then if you change the
  reverse sort mode and then unfollow the process, instead of the
  selection returning to the process that was being followed it returns
  to where the process would have been if the sorting wasn't reversed.

  - I struggled to figure out a fix for this but landed on reusing the
    code block that locates the followed process to restore the
    selection when detailed view closes.
  - I actually quite like this fix since it also centers the selection
    if possiple when closing the detailed view.

- The change that removed selection for detailed view following caused
  an issue where if the list was paused holding up would cause the
  selection to loop from the list position where the followed process
  was after reaching the top of the list.

  - This was fixed by adding some additional conditions before changing
    the selection back to the followed process when selected is 0
  - This gets rid of this issue so that when paused scrolling to the
    top of the list doesn't loop back to the followed process location

- When following a process and the view was at the end of the list, if
  the process died and following disengaged, a blank line would be left
  at the bottom of the list until the next collection cycle.

  - fixed this by making select_max not a const and adding 1 to it when
    the following mode disengaged.

- When the followed process is the first process in the list, pressing
  up doesn't redraw the screen and get rid of the following banner
  until the next collection cycle.

  - I fixed this by moving `bool changed = false` to the top of the
    selection function and setting `changed` to true when reselecting
    the followed process before moving back up and `selected` is 0
    again.

- When following a process clicking on the banner with the mouse would
  exit following mode and select the last line. I am not sure if this is
  desirable or not.

  - I have fixed this with an extra condition in the mouse input logic
  - This can be reverted if you feel it is good for clicking the banner
    to exit following in that way.

Improvements to follow mode list centering

- The followed process was centered using select_max / 2. this works
  but would leave it off center by 2 if select_max was odd.

  - it has been updated to use select_max / 2 if select_max is even
    which has the followed process off center as close as it can be
    but slightly closer to the top of list. if select_max is odd then
    it uses select_max / 2 + 1 which places the process dead center.

- If follow-detailed is disabled and a process is being followed while
  paused, opening or closing the detailed view doesn't recenter the
  followed process.

  - fixed this by relocating a line that sets update_following

Issue with tree expand/collapse when following

- When I made the change that set `selected = 0` when following the
  detailed process. I did not realize that this would prevent the user
  from being able to expand or collapse the tree of the process being
  followed without first unfollowing it.

  - I fixed this by slightly reworking the input code for
    expand/collapse with some extra conditions

Misc improvement to follow mode

- Added a line in the F input handling code that sets the selection to
  the followed process before exiting follow mode. This means that if
  if you press F after opening a detailed view and following that it
  will exit follow mode and move selected to the followed process
  location instead of leaving selected as 0. This is equivalent to
  pressing down after opening a detailed view when not following the
  process.

- Since when following the detailed view process the selection can be
  moved up or down from the followed process, the up arrow for the
  select button should not be greyed out if following the detailed view
  process and `should_selection_return_to_followed` is false.

- Added a comment in the selection function to explain what the
  following mode code block does there.

Small optimization for Pause mode

- I moved `Config::getB("keep_dead_proc_usage")` outside of the for loop
  that goes through all the current procs while paused.
This commit is contained in:
Barry Van Deerlin
2026-01-13 17:53:21 -08:00
parent 64476b5d08
commit dca53f87e4
8 changed files with 79 additions and 33 deletions

View File

@@ -355,6 +355,10 @@ namespace Input {
}
else if (Config::getB("follow_process")) {
Config::flip("follow_process");
if (Config::getB("should_selection_return_to_followed"))
Config::set("proc_selected", Config::getI("proc_followed"));
else if (Config::getB("show_detailed") and Config::getI("followed_pid") == Config::getI("detailed_pid"))
Config::set("restore_detailed_pid", Config::getI("detailed_pid"));
Config::set("followed_pid", 0);
Config::set("proc_followed", 0);
}
@@ -395,6 +399,8 @@ namespace Input {
process("enter");
return;
}
else if (Config::getB("proc_banner_shown") and line == y + height - 2)
return;
else if (current_selection == 0 or line - y - 1 == 0)
redraw = true;
@@ -449,31 +455,35 @@ namespace Input {
if (Config::getB("proc_follow_detailed")) {
Config::set("follow_process", true);
Config::set("followed_pid", Config::getI("selected_pid"));
Config::set("update_following", true);
}
Config::set("show_detailed", true);
}
else if (Config::getB("show_detailed")) {
const int proc_start_offset = Config::getB("proc_follow_detailed") ? Config::getI("proc_followed") - Config::getI("proc_last_selected") : 0;
if (Config::getI("proc_last_selected") > 0) Config::set("proc_selected", Config::getI("proc_last_selected"));
Config::set("proc_start", std::max(0, Config::getI("proc_start") + proc_start_offset));
if (Config::getB("proc_follow_detailed")) {
Config::set("restore_detailed_pid", Config::getI("detailed_pid"));
if (Config::getB("follow_process") and Config::getI("followed_pid") == Config::getI("detailed_pid")) {
Config::flip("follow_process");
Config::set("followed_pid", 0);
Config::set("proc_followed", 0);
}
}
else if (Config::getI("proc_last_selected") > 0) Config::set("proc_selected", Config::getI("proc_last_selected"));
Config::set("proc_last_selected", 0);
Config::set("detailed_pid", 0);
Config::set("show_detailed", false);
if (Config::getB("follow_process") and Config::getB("proc_follow_detailed")) {
Config::flip("follow_process");
Config::set("followed_pid", 0);
Config::set("proc_followed", 0);
}
}
Config::set("update_following", true);
}
else if (is_in(key, "+", "-", "space", "C") and Config::getB("proc_tree") and Config::getI("proc_selected") > 0) {
atomic_wait(Runner::active);
auto& pid = Config::getI("selected_pid");
if (key == "+" or key == "space") Proc::expand = pid;
if (key == "-" or key == "space") Proc::collapse = pid;
if (key == "C") Proc::toggle_children = pid;
no_update = false;
else if (is_in(key, "+", "-", "space", "C") and Config::getB("proc_tree")) {
const bool is_following_detailed = Config::getB("follow_process") and Config::getI("followed_pid") == Config::getI("detailed_pid");
if (Config::getI("proc_selected") > 0 or is_following_detailed) {
atomic_wait(Runner::active);
auto& pid = is_following_detailed and Config::getI("proc_selected") == 0 ? Config::getI("followed_pid") : Config::getI("selected_pid");
if (key == "+" or key == "space") Proc::expand = pid;
if (key == "-" or key == "space") Proc::collapse = pid;
if (key == "C") Proc::toggle_children = pid;
no_update = false;
}
}
else if (is_in(key, "t", kill_key) and (Config::getB("show_detailed") or Config::getI("selected_pid") > 0)) {
atomic_wait(Runner::active);