From c6e68e2fedc21b2537066433d1b50a60e06774eb Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sat, 23 Jun 2018 12:00:00 -0500 Subject: [PATCH] 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 --- top/top.c | 40 +++++++++++++++++++++++++++++----------- top/top.h | 4 ++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/top/top.c b/top/top.c index 7e17b1e3..294ff496 100644 --- a/top/top.c +++ b/top/top.c @@ -4424,7 +4424,9 @@ static WIN_t *win_select (int ch) { default: // keep gcc happy break; } - return Curwin = w; + Curwin = w; + mkVIZrow1(Curwin); + return Curwin; } // end: win_select @@ -4662,6 +4664,9 @@ static void wins_stage_2 (void) { ; // avoid -Wunused-result #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 sigemptyset(&Sigwinch_set); #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; #ifndef TREE_VWINALL - if (q == Curwin) + if (q == Curwin) // note: the following is NOT indented #endif if (p->pad_2 == 'x') { 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; - // 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++) if (Hide_pid[i] > 0) break; if (i == Hide_tot) Hide_tot = 0; @@ -5517,8 +5522,10 @@ static void keys_window (int ch) { case kbd_HOME: #ifndef SCROLLVAR_NO if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begtask = w->begpflg = w->varcolbeg = 0; + mkVIZrow1(w); #else if (VIZCHKw(w)) if (CHKw(w, Show_IDLEPS)) w->begtask = w->begpflg = 0; + mkVIZrow1(w); #endif break; 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_3: where level number is stored (0 - 100) */ #ifndef TREE_VWINALL - if (q == Curwin) + if (q == Curwin) // note: the following is NOT indented #endif if (CHKw(q, Show_FOREST) && p->pad_2 == 'z') 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' * 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 */ + * 1) exclusively for the 'current' window + * 2) immediately after interacting with the user + * 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) { WIN_t *w = Curwin; // avoid gcc bloat with a local copy - int i; + int i, reversed; SETw(w, NOPRINT_xxx); w->begtask += w->begnext; - if (w->begtask < 0) w->begtask = 0; - if (w->begtask >= Frame_maxtask) w->begtask = Frame_maxtask - 1; + // next 'if' will force a forward scan ... + 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 ... if (w->begnext > 0) { +fwd_redux: for (i = w->begtask; i < Frame_maxtask; i++) { if (user_matched(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]))) 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: w->begnext = 0; diff --git a/top/top.h b/top/top.h index 758470df..afbf6c22 100644 --- a/top/top.h +++ b/top/top.h @@ -474,6 +474,10 @@ typedef struct WIN_t { #define SCROLLAMT 8 #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 ------------------------------------------ */ /* /////////////////////////////////////////////////////////////// */