top: normalize vertical scrolling for hidden processes

To my knowledge, nobody has ever complained about some
anomalies when scrolling vertically if tasks should be
hidden from view. This can happen with the user filter
('u/U') or other filter ('o/O') features. And although
some tasks are not shown, they still impact scrolling.

This is most apparent when that scroll coordinates msg
is on ('C') & up/down arrow keys used (vs. pgup/pgdn).

Now that we can collapse/expand forked children, there
is a potential for yet more of those hidden processes.

So this commit normalizes vertical scrolling providing
an expected behavior. In other words, the up/down keys
skip the unseen tasks to reposition on a visible task.

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner
2018-06-20 00:00:00 -05:00
committed by Craig Small
parent a8dc1a6e5a
commit 6aedeac667
2 changed files with 61 additions and 16 deletions

View File

@@ -3919,9 +3919,9 @@ static void win_names (WIN_t *q, const char *name) {
static void win_reset (WIN_t *q) {
SETw(q, Show_IDLEPS | Show_TASKON);
#ifndef SCROLLVAR_NO
q->rc.maxtasks = q->usrseltyp = q->begpflg = q->begtask = q->varcolbeg = 0;
q->rc.maxtasks = q->usrseltyp = q->begpflg = q->begtask = q->begnext = q->varcolbeg = 0;
#else
q->rc.maxtasks = q->usrseltyp = q->begpflg = q->begtask = 0;
q->rc.maxtasks = q->usrseltyp = q->begpflg = q->begtask = q->begnext = 0;
#endif
Monpidsidx = 0;
osel_clear(q);
@@ -4408,7 +4408,7 @@ static void find_string (int ch) {
#endif
}
if (Curwin->findstr[0]) {
SETw(Curwin, INFINDS_xxx);
SETw(Curwin, NOPRINT_xxx);
for (i = Curwin->begtask; i < PIDSmaxt; i++) {
const char *row = task_show(Curwin, Curwin->ppt[i]);
if (*row && -1 < find_ofs(Curwin, row)) {
@@ -4990,10 +4990,10 @@ static void keys_window (int ch) {
}
break;
case kbd_UP:
if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS) && 0 < w->begtask) w->begtask -= 1;
if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begnext = -1;
break;
case kbd_DOWN:
if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS) && (w->begtask < PIDSmaxt - 1)) w->begtask += 1;
if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begnext = +1;
break;
#ifdef USE_X_COLHDR // ------------------------------------
case kbd_LEFT:
@@ -5063,17 +5063,14 @@ static void keys_window (int ch) {
case kbd_PGUP:
if (VIZCHKw(w)) {
if (CHKw(w, Show_IDLEPS) && 0 < w->begtask) {
w->begtask -= (w->winlines - 1);
if (0 > w->begtask) w->begtask = 0;
w->begnext = -(w->winlines - 1);
}
}
break;
case kbd_PGDN:
if (VIZCHKw(w)) {
if (CHKw(w, Show_IDLEPS) && w->begtask < PIDSmaxt - 1) {
w->begtask += (w->winlines - 1);
if (w->begtask > PIDSmaxt - 1) w->begtask = PIDSmaxt - 1;
if (0 > w->begtask) w->begtask = 0;
w->begnext = +(w->winlines - 1);
}
}
break;
@@ -5087,8 +5084,7 @@ static void keys_window (int ch) {
case kbd_END:
if (VIZCHKw(w)) {
if (CHKw(w, Show_IDLEPS)) {
w->begtask = (PIDSmaxt - w->winlines) + 1;
if (0 > w->begtask) w->begtask = 0;
w->begnext = (PIDSmaxt - w->winlines) + 1;
w->begpflg = w->endpflg;
#ifndef SCROLLVAR_NO
w->varcolbeg = 0;
@@ -5507,7 +5503,7 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) {
case EU_XOF:
case EU_XON:
cp = NULL;
if (!CHKw(q, INFINDS_xxx | NOHIFND_xxx | NOHISEL_xxx)) {
if (!CHKw(q, NOPRINT_xxx | NOHIFND_xxx | NOHISEL_xxx)) {
/* treat running tasks specially - entire row may get highlighted
so we needn't turn it on and we MUST NOT turn it off */
if (!('R' == rSv(EU_STA, s_ch) && CHKw(q, Show_HIROWS)))
@@ -5662,7 +5658,7 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) {
#undef Jn
} // end: for 'maxpflgs'
if (!CHKw(q, INFINDS_xxx)) {
if (!CHKw(q, NOPRINT_xxx)) {
const char *cap = ((CHKw(q, Show_HIROWS) && 'R' == rSv(EU_STA, s_ch)))
? q->capclr_rowhigh : q->capclr_rownorm;
char *row = rbuf;
@@ -5693,6 +5689,51 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) {
} // end: task_show
/*
* A window_show *Helper* function ensuring that Curwin's 'begtask'
* represents a visible process (not any hidden/filtered-out task).
* In reality, this function is called:
* 1) exclusively for the current window
* 2) immediately after interacting with a user
* 3) with the only key stuck: up, down, pgup, pgdn or end */
static void window_hlp (void) {
WIN_t *w = Curwin; // avoid gcc bloat with a local copy
int i;
SETw(w, NOPRINT_xxx);
w->begtask += w->begnext;
if (w->begtask < 0) w->begtask = 0;
if (w->begtask >= PIDSmaxt) w->begtask = PIDSmaxt - 1;
// potentially scroll forward ...
if (w->begnext > 0) {
for (i = w->begtask; i < PIDSmaxt; i++) {
if (wins_usrselect(w, w->ppt[i])
&& (*task_show(w, w->ppt[i])))
break;
}
if (i < PIDSmaxt) {
w->begtask = i;
goto wrap_up;
}
// no luck forward, so let's try backward
w->begtask = PIDSmaxt - 1;
}
// potentially scroll backward ...
for (i = w->begtask; i > 0; i--) {
if (wins_usrselect(w, w->ppt[i])
&& (*task_show(w, w->ppt[i])))
break;
}
w->begtask = i;
wrap_up:
w->begnext = 0;
OFFw(w, NOPRINT_xxx);
} // end: window_hlp
static int window_show (WIN_t *q, int wmax) {
#define sORDER CHKw(q, Qsrt_NORMAL) ? PIDS_SORT_DESCEND : PIDS_SORT_ASCEND
/* the isBUSY macro determines if a task is 'active' --
@@ -5717,6 +5758,9 @@ static int window_show (WIN_t *q, int wmax) {
error_exit(fmtmk(N_fmt(LIB_errorpid_fmt),__LINE__, strerror(errno)));
}
if (q->begnext) window_hlp();
else OFFw(q, NOPRINT_xxx);
i = q->begtask;
lwin = 1; // 1 for the column header
wmax = winMIN(wmax, q->winlines + 1); // ditto for winlines, too
@@ -5807,7 +5851,6 @@ static void frame_make (void) {
Tree_idx = Pseudo_row = Msg_row = scrlins = 0;
summary_show();
Max_lines = (Screen_rows - Msg_row) - 1;
OFFw(w, INFINDS_xxx);
// we're now on Msg_row so clear out any residual messages ...
putp(Cap_clr_eol);