top: a few tweaks for those scrolling (mostly) changes

This patch just addresses some edge cases with respect
to 'unseen' tasks. Given the ability to preserve other
filters in the rcfile, it's entirely possible the very
first task(s) may not be visible at top startup. Also,
when switching between windows ('a'/'w') we should try
to always position its row #1 on some visible process.

Lastly, a window might have *NO* visible tasks at all.
Therefore, protect 'window_hlp' from an infinite loop.

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2018-06-23 12:00:00 -05:00 committed by Craig Small
parent 2c2d86e6cc
commit c6e68e2fed
2 changed files with 33 additions and 11 deletions

View File

@ -4424,7 +4424,9 @@ static WIN_t *win_select (int ch) {
default: // keep gcc happy default: // keep gcc happy
break; break;
} }
return Curwin = w; Curwin = w;
mkVIZrow1(Curwin);
return Curwin;
} // end: win_select } // end: win_select
@ -4662,6 +4664,9 @@ static void wins_stage_2 (void) {
; // avoid -Wunused-result ; // avoid -Wunused-result
#endif #endif
// with preserved 'other filters', ensure a visible task on row #1
mkVIZrow1(Curwin);
// lastly, initialize a signal set used to throttle one troublesome signal // lastly, initialize a signal set used to throttle one troublesome signal
sigemptyset(&Sigwinch_set); sigemptyset(&Sigwinch_set);
#ifdef SIGNALS_LESS #ifdef SIGNALS_LESS
@ -4788,7 +4793,7 @@ static inline const char *forest_display (const WIN_t *q, const proc_t *p) {
if (!CHKw(q, Show_FOREST) || !p->pad_3) return which; if (!CHKw(q, Show_FOREST) || !p->pad_3) return which;
#ifndef TREE_VWINALL #ifndef TREE_VWINALL
if (q == Curwin) if (q == Curwin) // note: the following is NOT indented
#endif #endif
if (p->pad_2 == 'x') { if (p->pad_2 == 'x') {
snprintf(buf, sizeof(buf), "+%*s%s", ((4 * p->pad_3) - 1), "`- ", which); snprintf(buf, sizeof(buf), "+%*s%s", ((4 * p->pad_3) - 1), "`- ", which);
@ -5380,7 +5385,7 @@ static void keys_task (int ch) {
} }
} }
if (i == Hide_tot) Hide_pid[Hide_tot++] = pid; if (i == Hide_tot) Hide_pid[Hide_tot++] = pid;
// plenty of room, but if everything's expaned let's reset ... // plenty of room, but if everything's expanded let's reset ...
for (i = 0; i < Hide_tot; i++) for (i = 0; i < Hide_tot; i++)
if (Hide_pid[i] > 0) break; if (Hide_pid[i] > 0) break;
if (i == Hide_tot) Hide_tot = 0; if (i == Hide_tot) Hide_tot = 0;
@ -5517,8 +5522,10 @@ static void keys_window (int ch) {
case kbd_HOME: case kbd_HOME:
#ifndef SCROLLVAR_NO #ifndef SCROLLVAR_NO
if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begtask = w->begpflg = w->varcolbeg = 0; if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begtask = w->begpflg = w->varcolbeg = 0;
mkVIZrow1(w);
#else #else
if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begtask = w->begpflg = 0; if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begtask = w->begpflg = 0;
mkVIZrow1(w);
#endif #endif
break; break;
case kbd_END: case kbd_END:
@ -5931,7 +5938,7 @@ static const char *task_show (const WIN_t *q, const proc_t *p) {
pad_2: 'x' means a collapsed thread, 'z' means an unseen child pad_2: 'x' means a collapsed thread, 'z' means an unseen child
pad_3: where level number is stored (0 - 100) */ pad_3: where level number is stored (0 - 100) */
#ifndef TREE_VWINALL #ifndef TREE_VWINALL
if (q == Curwin) if (q == Curwin) // note: the following is NOT indented
#endif #endif
if (CHKw(q, Show_FOREST) && p->pad_2 == 'z') if (CHKw(q, Show_FOREST) && p->pad_2 == 'z')
return ""; return "";
@ -6191,20 +6198,24 @@ static const char *task_show (const WIN_t *q, const proc_t *p) {
* A window_show *Helper* function ensuring that Curwin's 'begtask' * A window_show *Helper* function ensuring that Curwin's 'begtask'
* represents a visible process (not any hidden/filtered-out task). * represents a visible process (not any hidden/filtered-out task).
* In reality, this function is called: * In reality, this function is called:
* 1) exclusively for the current window * 1) exclusively for the 'current' window
* 2) immediately after interacting with a user * 2) immediately after interacting with the user
* 3) with the only key stuck: up, down, pgup, pgdn or end */ * 3) who struck 1 of these: up, down, pgup, pgdn, home or end
* 4) or upon the user switching from one window to another window */
static void window_hlp (void) { static void window_hlp (void) {
WIN_t *w = Curwin; // avoid gcc bloat with a local copy WIN_t *w = Curwin; // avoid gcc bloat with a local copy
int i; int i, reversed;
SETw(w, NOPRINT_xxx); SETw(w, NOPRINT_xxx);
w->begtask += w->begnext; w->begtask += w->begnext;
if (w->begtask < 0) w->begtask = 0; // next 'if' will force a forward scan ...
if (w->begtask >= Frame_maxtask) w->begtask = Frame_maxtask - 1; if (w->begtask <= 0) { w->begtask = 0; w->begnext = +1; }
else if (w->begtask >= Frame_maxtask) w->begtask = Frame_maxtask - 1;
reversed = 0;
// potentially scroll forward ... // potentially scroll forward ...
if (w->begnext > 0) { if (w->begnext > 0) {
fwd_redux:
for (i = w->begtask; i < Frame_maxtask; i++) { for (i = w->begtask; i < Frame_maxtask; i++) {
if (user_matched(w, w->ppt[i]) if (user_matched(w, w->ppt[i])
&& (*task_show(w, w->ppt[i]))) && (*task_show(w, w->ppt[i])))
@ -6224,7 +6235,14 @@ static void window_hlp (void) {
&& (*task_show(w, w->ppt[i]))) && (*task_show(w, w->ppt[i])))
break; break;
} }
w->begtask = i; // reached the top, but maybe this guy ain't visible
if (!(w->begtask = i) && !reversed) {
if (!(user_matched(w, w->ppt[0]))
|| (!(*task_show(w, w->ppt[0])))) {
reversed = 1;
goto fwd_redux;
}
}
wrap_up: wrap_up:
w->begnext = 0; w->begnext = 0;

View File

@ -474,6 +474,10 @@ typedef struct WIN_t {
#define SCROLLAMT 8 #define SCROLLAMT 8
#endif #endif
// Support for a proper (visible) row #1 whenever Curwin changes
// ( or a certain vertical scrolling key has been struck )
#define mkVIZrow1(q) { q->begtask -= 1; q->begnext = +1; }
/* Special Section: end ------------------------------------------ */ /* Special Section: end ------------------------------------------ */
/* /////////////////////////////////////////////////////////////// */ /* /////////////////////////////////////////////////////////////// */