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:
parent
a8dc1a6e5a
commit
6aedeac667
73
top/top.c
73
top/top.c
@ -3919,9 +3919,9 @@ static void win_names (WIN_t *q, const char *name) {
|
|||||||
static void win_reset (WIN_t *q) {
|
static void win_reset (WIN_t *q) {
|
||||||
SETw(q, Show_IDLEPS | Show_TASKON);
|
SETw(q, Show_IDLEPS | Show_TASKON);
|
||||||
#ifndef SCROLLVAR_NO
|
#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
|
#else
|
||||||
q->rc.maxtasks = q->usrseltyp = q->begpflg = q->begtask = 0;
|
q->rc.maxtasks = q->usrseltyp = q->begpflg = q->begtask = q->begnext = 0;
|
||||||
#endif
|
#endif
|
||||||
Monpidsidx = 0;
|
Monpidsidx = 0;
|
||||||
osel_clear(q);
|
osel_clear(q);
|
||||||
@ -4408,7 +4408,7 @@ static void find_string (int ch) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (Curwin->findstr[0]) {
|
if (Curwin->findstr[0]) {
|
||||||
SETw(Curwin, INFINDS_xxx);
|
SETw(Curwin, NOPRINT_xxx);
|
||||||
for (i = Curwin->begtask; i < PIDSmaxt; i++) {
|
for (i = Curwin->begtask; i < PIDSmaxt; i++) {
|
||||||
const char *row = task_show(Curwin, Curwin->ppt[i]);
|
const char *row = task_show(Curwin, Curwin->ppt[i]);
|
||||||
if (*row && -1 < find_ofs(Curwin, row)) {
|
if (*row && -1 < find_ofs(Curwin, row)) {
|
||||||
@ -4990,10 +4990,10 @@ static void keys_window (int ch) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kbd_UP:
|
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;
|
break;
|
||||||
case kbd_DOWN:
|
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;
|
break;
|
||||||
#ifdef USE_X_COLHDR // ------------------------------------
|
#ifdef USE_X_COLHDR // ------------------------------------
|
||||||
case kbd_LEFT:
|
case kbd_LEFT:
|
||||||
@ -5063,17 +5063,14 @@ static void keys_window (int ch) {
|
|||||||
case kbd_PGUP:
|
case kbd_PGUP:
|
||||||
if (VIZCHKw(w)) {
|
if (VIZCHKw(w)) {
|
||||||
if (CHKw(w, Show_IDLEPS) && 0 < w->begtask) {
|
if (CHKw(w, Show_IDLEPS) && 0 < w->begtask) {
|
||||||
w->begtask -= (w->winlines - 1);
|
w->begnext = -(w->winlines - 1);
|
||||||
if (0 > w->begtask) w->begtask = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kbd_PGDN:
|
case kbd_PGDN:
|
||||||
if (VIZCHKw(w)) {
|
if (VIZCHKw(w)) {
|
||||||
if (CHKw(w, Show_IDLEPS) && w->begtask < PIDSmaxt - 1) {
|
if (CHKw(w, Show_IDLEPS) && w->begtask < PIDSmaxt - 1) {
|
||||||
w->begtask += (w->winlines - 1);
|
w->begnext = +(w->winlines - 1);
|
||||||
if (w->begtask > PIDSmaxt - 1) w->begtask = PIDSmaxt - 1;
|
|
||||||
if (0 > w->begtask) w->begtask = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -5087,8 +5084,7 @@ static void keys_window (int ch) {
|
|||||||
case kbd_END:
|
case kbd_END:
|
||||||
if (VIZCHKw(w)) {
|
if (VIZCHKw(w)) {
|
||||||
if (CHKw(w, Show_IDLEPS)) {
|
if (CHKw(w, Show_IDLEPS)) {
|
||||||
w->begtask = (PIDSmaxt - w->winlines) + 1;
|
w->begnext = (PIDSmaxt - w->winlines) + 1;
|
||||||
if (0 > w->begtask) w->begtask = 0;
|
|
||||||
w->begpflg = w->endpflg;
|
w->begpflg = w->endpflg;
|
||||||
#ifndef SCROLLVAR_NO
|
#ifndef SCROLLVAR_NO
|
||||||
w->varcolbeg = 0;
|
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_XOF:
|
||||||
case EU_XON:
|
case EU_XON:
|
||||||
cp = NULL;
|
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
|
/* treat running tasks specially - entire row may get highlighted
|
||||||
so we needn't turn it on and we MUST NOT turn it off */
|
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)))
|
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
|
#undef Jn
|
||||||
} // end: for 'maxpflgs'
|
} // 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)))
|
const char *cap = ((CHKw(q, Show_HIROWS) && 'R' == rSv(EU_STA, s_ch)))
|
||||||
? q->capclr_rowhigh : q->capclr_rownorm;
|
? q->capclr_rowhigh : q->capclr_rownorm;
|
||||||
char *row = rbuf;
|
char *row = rbuf;
|
||||||
@ -5693,6 +5689,51 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) {
|
|||||||
} // end: task_show
|
} // 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) {
|
static int window_show (WIN_t *q, int wmax) {
|
||||||
#define sORDER CHKw(q, Qsrt_NORMAL) ? PIDS_SORT_DESCEND : PIDS_SORT_ASCEND
|
#define sORDER CHKw(q, Qsrt_NORMAL) ? PIDS_SORT_DESCEND : PIDS_SORT_ASCEND
|
||||||
/* the isBUSY macro determines if a task is 'active' --
|
/* 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)));
|
error_exit(fmtmk(N_fmt(LIB_errorpid_fmt),__LINE__, strerror(errno)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (q->begnext) window_hlp();
|
||||||
|
else OFFw(q, NOPRINT_xxx);
|
||||||
|
|
||||||
i = q->begtask;
|
i = q->begtask;
|
||||||
lwin = 1; // 1 for the column header
|
lwin = 1; // 1 for the column header
|
||||||
wmax = winMIN(wmax, q->winlines + 1); // ditto for winlines, too
|
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;
|
Tree_idx = Pseudo_row = Msg_row = scrlins = 0;
|
||||||
summary_show();
|
summary_show();
|
||||||
Max_lines = (Screen_rows - Msg_row) - 1;
|
Max_lines = (Screen_rows - Msg_row) - 1;
|
||||||
OFFw(w, INFINDS_xxx);
|
|
||||||
|
|
||||||
// we're now on Msg_row so clear out any residual messages ...
|
// we're now on Msg_row so clear out any residual messages ...
|
||||||
putp(Cap_clr_eol);
|
putp(Cap_clr_eol);
|
||||||
|
@ -245,7 +245,7 @@ typedef long long SIC_t;
|
|||||||
#define Show_JRSTRS 0x040000 // 'j' - right justify "string" data cols
|
#define Show_JRSTRS 0x040000 // 'j' - right justify "string" data cols
|
||||||
#define Show_JRNUMS 0x020000 // 'J' - right justify "numeric" data cols
|
#define Show_JRNUMS 0x020000 // 'J' - right justify "numeric" data cols
|
||||||
// these flag(s) have no command as such - they're for internal use
|
// these flag(s) have no command as such - they're for internal use
|
||||||
#define INFINDS_xxx 0x010000 // build rows for find_string, not display
|
#define NOPRINT_xxx 0x010000 // build task rows only (not for display)
|
||||||
#define EQUWINS_xxx 0x000001 // rebalance all wins & tasks (off i,n,u/U)
|
#define EQUWINS_xxx 0x000001 // rebalance all wins & tasks (off i,n,u/U)
|
||||||
#ifndef USE_X_COLHDR
|
#ifndef USE_X_COLHDR
|
||||||
#define NOHISEL_xxx 0x200000 // restrict Show_HICOLS for osel temporarily
|
#define NOHISEL_xxx 0x200000 // restrict Show_HICOLS for osel temporarily
|
||||||
@ -325,6 +325,7 @@ typedef struct WIN_t {
|
|||||||
begpflg, // scrolled beginning pos into pflgsall array
|
begpflg, // scrolled beginning pos into pflgsall array
|
||||||
endpflg, // scrolled ending pos into pflgsall array
|
endpflg, // scrolled ending pos into pflgsall array
|
||||||
begtask, // scrolled beginning pos into total tasks
|
begtask, // scrolled beginning pos into total tasks
|
||||||
|
begnext, // new scrolled delta for next frame's begtask
|
||||||
#ifndef SCROLLVAR_NO
|
#ifndef SCROLLVAR_NO
|
||||||
varcolbeg, // scrolled position within variable width col
|
varcolbeg, // scrolled position within variable width col
|
||||||
#endif
|
#endif
|
||||||
@ -665,6 +666,7 @@ typedef struct WIN_t {
|
|||||||
//atic void summary_hlp (struct stat_stack *this, const char *pfx);
|
//atic void summary_hlp (struct stat_stack *this, const char *pfx);
|
||||||
//atic void summary_show (void);
|
//atic void summary_show (void);
|
||||||
//atic const char *task_show (const WIN_t *q, struct pids_stack *p);
|
//atic const char *task_show (const WIN_t *q, struct pids_stack *p);
|
||||||
|
//atic void window_hlp (void);
|
||||||
//atic int window_show (WIN_t *q, int wmax);
|
//atic int window_show (WIN_t *q, int wmax);
|
||||||
/*------ Entry point plus two ------------------------------------------*/
|
/*------ Entry point plus two ------------------------------------------*/
|
||||||
//atic void frame_hlp (int wix, int max);
|
//atic void frame_hlp (int wix, int max);
|
||||||
|
Loading…
Reference in New Issue
Block a user