redbear-power: v1.36 mouse click to position Process cursor

Extends the existing mouse handler (which already supports
Per-CPU wheel/left/right/middle clicks) to also work on the
Process tab.

- Wheel up/down on the Process tab: cursor moves 1 row
  (process_cursor is set via the existing move_selection
  dispatcher, which is already tab-aware)
- Left click on a row: process_cursor jumps to that row.
  The Process tab has 2 lines of header (title + blank) and
  1 line of column header, so rows start at body.y + 2.
  Click in the body's empty space (below the rows) is a no-op
  (saturating_sub clamps to 0).
- Right click on a row: positions the cursor AND opens the
  PID detail popup (right-click is the natural 'inspect' gesture).
- The body rect for the Process tab is the same as 'table'
  in the existing handler since the Process tab uses the
  full body area (not split into header + table like Per-CPU).

Test count 127 (unchanged; mouse handling is TUI-time and
hard to unit-test without a full terminal harness).

Redox stripped binary: 4,250,472 bytes (+12 KiB from v1.35;
the new branches are inline in the existing handler).
Compile warnings: 56 (unchanged).
This commit is contained in:
2026-06-21 07:37:08 +03:00
parent a5237091fc
commit 7b973f932b
@@ -130,11 +130,15 @@ fn handle_mouse(me: MouseEvent, header: &Rect, table: &Rect, controls: &Rect, ap
MouseEvent::Press(MouseButton::WheelUp, _x, y) => {
if hit_test(*table, _x, y) {
app.move_selection(-1);
} else if app.current_tab == TabId::Process {
app.move_selection(-1);
}
}
MouseEvent::Press(MouseButton::WheelDown, _x, y) => {
if hit_test(*table, _x, y) {
app.move_selection(1);
} else if app.current_tab == TabId::Process {
app.move_selection(1);
}
}
MouseEvent::Press(MouseButton::Left, x, y) => {
@@ -159,6 +163,17 @@ fn handle_mouse(me: MouseEvent, header: &Rect, table: &Rect, controls: &Rect, ap
// action; this preserves a consistent "primary action
// on left, modifier on right" mapping.
app.cycle_governor();
} else if app.current_tab == TabId::Process {
// Process tab uses the full body_area as its panel.
// Click in the body maps to visible_index. The
// Process tab header is at body.y; rows start at
// body.y + 2 (line 0 is the title; line 1 is blank;
// line 2 is the column header; rows start at line 3).
let body = Rect::new(table.x, table.y, table.width, table.height);
if hit_test(body, x, y) {
let row = y.saturating_sub(table.y + 2) as usize;
app.process_cursor = row;
}
}
}
MouseEvent::Press(MouseButton::Right, x, y) => {
@@ -166,6 +181,16 @@ fn handle_mouse(me: MouseEvent, header: &Rect, table: &Rect, controls: &Rect, ap
app.toggle_expand();
} else if hit_test(*header, x, y) {
app.toggle_throttle_mode();
} else if app.current_tab == TabId::Process {
// Right-click on a process row opens the PID detail.
let body = Rect::new(table.x, table.y, table.width, table.height);
if hit_test(body, x, y) {
let row = y.saturating_sub(table.y + 2) as usize;
app.process_cursor = row;
if let Some(pid) = app.selected_pid() {
app.pid_detail = Some(crate::pid_detail::PidDetail::read(pid));
}
}
}
}
MouseEvent::Press(MouseButton::Middle, x, y) => {