From dde71c6637905e1707bd1020c93e930f4b0a480b Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Fri, 30 Oct 2020 21:56:16 -0400 Subject: Highlight new and old processes (#74) --- CRT.c | 12 +++++++++ CRT.h | 2 ++ DisplayOptionsPanel.c | 1 + Panel.c | 12 +++++---- Process.c | 17 ++++++++++++ Process.h | 11 +++++++- ProcessList.c | 42 ++++++++++++++++++++++++++--- ProcessList.h | 2 ++ RichString.h | 1 + ScreenManager.c | 1 + Settings.c | 7 +++++ Settings.h | 2 ++ htop.1.in | 5 +++- htop.c | 75 ++++++++++++++++++++++++++++++++++----------------- 14 files changed, 155 insertions(+), 35 deletions(-) diff --git a/CRT.c b/CRT.c index 888444cc..28a2add7 100644 --- a/CRT.c +++ b/CRT.c @@ -111,6 +111,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PROCESS_D_STATE] = A_BOLD | ColorPair(Red,Black), [PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black), [PROCESS_LOW_PRIORITY] = ColorPair(Green,Black), + [PROCESS_NEW] = ColorPair(Black,Green), + [PROCESS_TOMB] = ColorPair(Black,Red), [PROCESS_THREAD] = ColorPair(Green,Black), [PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Black), [BAR_BORDER] = A_BOLD, @@ -188,6 +190,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PROCESS_D_STATE] = A_BOLD, [PROCESS_HIGH_PRIORITY] = A_BOLD, [PROCESS_LOW_PRIORITY] = A_DIM, + [PROCESS_NEW] = A_BOLD, + [PROCESS_TOMB] = A_DIM, [PROCESS_THREAD] = A_BOLD, [PROCESS_THREAD_BASENAME] = A_REVERSE, [BAR_BORDER] = A_BOLD, @@ -265,6 +269,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PROCESS_D_STATE] = A_BOLD | ColorPair(Red,White), [PROCESS_HIGH_PRIORITY] = ColorPair(Red,White), [PROCESS_LOW_PRIORITY] = ColorPair(Green,White), + [PROCESS_NEW] = ColorPair(White,Green), + [PROCESS_TOMB] = ColorPair(White,Red), [PROCESS_THREAD] = ColorPair(Blue,White), [PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,White), [BAR_BORDER] = ColorPair(Blue,White), @@ -342,6 +348,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PROCESS_D_STATE] = A_BOLD | ColorPair(Red,Black), [PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black), [PROCESS_LOW_PRIORITY] = ColorPair(Green,Black), + [PROCESS_NEW] = ColorPair(Black,Green), + [PROCESS_TOMB] = ColorPair(Black,Red), [PROCESS_THREAD] = ColorPair(Blue,Black), [PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black), [BAR_BORDER] = ColorPair(Blue,Black), @@ -419,6 +427,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PROCESS_D_STATE] = A_BOLD | ColorPair(Red,Blue), [PROCESS_HIGH_PRIORITY] = ColorPair(Red,Blue), [PROCESS_LOW_PRIORITY] = ColorPair(Green,Blue), + [PROCESS_NEW] = ColorPair(Blue,Green), + [PROCESS_TOMB] = ColorPair(Blue,Red), [PROCESS_THREAD] = ColorPair(Green,Blue), [PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Blue), [BAR_BORDER] = A_BOLD | ColorPair(Yellow,Blue), @@ -498,6 +508,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PROCESS_D_STATE] = A_BOLD | ColorPair(Red,Black), [PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black), [PROCESS_LOW_PRIORITY] = ColorPair(Green,Black), + [PROCESS_NEW] = ColorPair(Black,Green), + [PROCESS_TOMB] = ColorPair(Black,Red), [BAR_BORDER] = A_BOLD | ColorPair(Green,Black), [BAR_SHADOW] = ColorPair(Cyan,Black), [SWAP] = ColorPair(Red,Black), diff --git a/CRT.h b/CRT.h index 1cdc209c..818148ef 100644 --- a/CRT.h +++ b/CRT.h @@ -72,6 +72,8 @@ typedef enum ColorElements_ { PROCESS_BASENAME, PROCESS_HIGH_PRIORITY, PROCESS_LOW_PRIORITY, + PROCESS_NEW, + PROCESS_TOMB, PROCESS_THREAD, PROCESS_THREAD_BASENAME, BAR_BORDER, diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index 64fd303c..e539906c 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -93,6 +93,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU percentage numerically"), &(settings->showCPUUsage))); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU frequency"), &(settings->showCPUFrequency))); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable the mouse"), &(settings->enableMouse))); + Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Highlight new and old processes"), &(settings->highlightChanges))); #ifdef HAVE_LIBHWLOC Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show topology when selecting affinity by default"), &(settings->topologyAffinity))); #endif diff --git a/Panel.c b/Panel.c index 02440d85..f3a48bc9 100644 --- a/Panel.c +++ b/Panel.c @@ -266,16 +266,18 @@ void Panel_draw(Panel* this, bool focus) { Object_display(itemObj, &item); int itemLen = RichString_sizeVal(item); int amt = MINIMUM(itemLen - scrollH, this->w); - bool selected = (i == this->selected); - if (selected) { - attrset(selectionColor); - RichString_setAttr(&item, selectionColor); + if (i == this->selected) { + item.highlightAttr = selectionColor; + } + if (item.highlightAttr) { + attrset(item.highlightAttr); + RichString_setAttr(&item, item.highlightAttr); this->selectedLen = itemLen; } mvhline(y + line, x, ' ', this->w); if (amt > 0) RichString_printoffnVal(item, y + line, x, scrollH, amt); - if (selected) + if (item.highlightAttr) attrset(CRT_colors[RESET_COLOR]); RichString_end(item); line++; diff --git a/Process.c b/Process.c index 842232f7..f78720a5 100644 --- a/Process.c +++ b/Process.c @@ -6,6 +6,7 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ + #include "config.h" // IWYU pragma: keep #include "Process.h" @@ -381,6 +382,12 @@ void Process_display(const Object* cast, RichString* out) { RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]); if (this->tag == true) RichString_setAttr(out, CRT_colors[PROCESS_TAG]); + if (this->settings->highlightChanges) { + if (Process_isNew(this)) + out->highlightAttr = CRT_colors[PROCESS_NEW]; + if (Process_isTomb(this)) + out->highlightAttr = CRT_colors[PROCESS_TOMB]; + } assert(out->chlen > 0); } @@ -413,6 +420,16 @@ void Process_toggleTag(Process* this) { this->tag = this->tag == true ? false : true; } +bool Process_isNew(const Process* this) { + if (this->processList && this->processList->scanTs >= this->seenTs) + return (this->processList->scanTs - this->seenTs <= this->processList->settings->highlightDelaySecs); + return false; +} + +bool Process_isTomb(const Process* this) { + return (this->tombTs > 0); +} + bool Process_setPriority(Process* this, int priority) { CRT_dropPrivileges(); int old_prio = getpriority(PRIO_PROCESS, this->pid); diff --git a/Process.h b/Process.h index b2c82080..e3ff333f 100644 --- a/Process.h +++ b/Process.h @@ -10,17 +10,18 @@ in the source distribution for its full text. #include #include +#include #include "Object.h" #include "RichString.h" - #ifdef __ANDROID__ #define SYS_ioprio_get __NR_ioprio_get #define SYS_ioprio_set __NR_ioprio_set #endif #define PROCESS_FLAG_IO 0x0001 +#define DEFAULT_HIGHLIGHT_SECS 5 typedef enum ProcessFields { NULL_PROCESSFIELD = 0, @@ -59,6 +60,7 @@ struct Settings_; typedef struct Process_ { Object super; + const struct ProcessList_* processList; const struct Settings_* settings; unsigned long long int time; @@ -99,6 +101,9 @@ typedef struct Process_ { int exit_signal; + time_t seenTs; + time_t tombTs; + unsigned long int minflt; unsigned long int majflt; } Process; @@ -172,6 +177,10 @@ void Process_init(Process* this, const struct Settings_* settings); void Process_toggleTag(Process* this); +bool Process_isNew(const Process* this); + +bool Process_isTomb(const Process* this); + bool Process_setPriority(Process* this, int priority); bool Process_changePriorityBy(Process* this, Arg delta); diff --git a/ProcessList.c b/ProcessList.c index dac86cb8..1ae7b9cc 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -9,11 +9,11 @@ in the source distribution for its full text. #include #include +#include #include "CRT.h" #include "XUtils.h" - ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { this->processes = Vector_new(klass, true, DEFAULT_SIZE); this->processTable = Hashtable_new(140, false); @@ -27,6 +27,9 @@ ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, Users // set later by platform-specific code this->cpuCount = 0; + this->scanTs = 0; + this->firstScanTs = 0; + #ifdef HAVE_LIBHWLOC this->topologyOk = false; if (hwloc_topology_init(&this->topology) == 0) { @@ -81,6 +84,14 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) { void ProcessList_add(ProcessList* this, Process* p) { assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1); assert(Hashtable_get(this->processTable, p->pid) == NULL); + p->processList = this; + + if (this->scanTs == this->firstScanTs) { + // prevent highlighting processes found in first scan + p->seenTs = this->firstScanTs - this->settings->highlightDelaySecs - 1; + } else { + p->seenTs = this->scanTs; + } Vector_add(this->processes, p); Hashtable_put(this->processTable, p->pid, p); @@ -283,6 +294,7 @@ Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting, } void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) { + struct timespec now; // in pause mode only gather global data for meters (CPU/memory/...) if (pauseProcessUpdate) { @@ -302,13 +314,35 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) { this->kernelThreads = 0; this->runningTasks = 0; + + // set scanTs + if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) { + if (this->firstScanTs == 0) { + this->firstScanTs = now.tv_sec; + } + this->scanTs = now.tv_sec; + } + ProcessList_goThroughEntries(this, false); for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { Process* p = (Process*) Vector_get(this->processes, i); - if (p->updated == false) - ProcessList_remove(this, p); - else + if (p->tombTs > 0) { + // remove tombed process + if (this->scanTs >= p->tombTs) { + ProcessList_remove(this, p); + } + } else if (p->updated == false) { + // process no longer exists + if (this->settings->highlightChanges) { + // mark tombed + p->tombTs = this->scanTs + this->settings->highlightDelaySecs; + } else { + // immediately remove + ProcessList_remove(this, p); + } + } else { p->updated = false; + } } } diff --git a/ProcessList.h b/ProcessList.h index 6b075fa7..db0549a6 100644 --- a/ProcessList.h +++ b/ProcessList.h @@ -70,6 +70,8 @@ typedef struct ProcessList_ { int cpuCount; + time_t scanTs; + time_t firstScanTs; } ProcessList; ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); diff --git a/RichString.h b/RichString.h index 48c1e749..9ee3a2d0 100644 --- a/RichString.h +++ b/RichString.h @@ -39,6 +39,7 @@ typedef struct RichString_ { int chlen; CharType* chptr; CharType chstr[RICHSTRING_MAXLEN+1]; + int highlightAttr; } RichString; void RichString_setAttrn(RichString* this, int attrs, int start, int finish); diff --git a/ScreenManager.c b/ScreenManager.c index bc5f66ac..2d43babc 100644 --- a/ScreenManager.c +++ b/ScreenManager.c @@ -102,6 +102,7 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi struct timeval tv; gettimeofday(&tv, NULL); double newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); + *timedOut = (newTime - *oldTime > this->settings->delay); *rescan = *rescan || *timedOut; if (newTime < *oldTime) *rescan = true; // clock was adjusted? diff --git a/Settings.c b/Settings.c index 9ac27565..a0a05042 100644 --- a/Settings.c +++ b/Settings.c @@ -158,6 +158,10 @@ static bool Settings_read(Settings* this, const char* fileName, int initialCpuCo this->highlightMegabytes = atoi(option[1]); } else if (String_eq(option[0], "highlight_threads")) { this->highlightThreads = atoi(option[1]); + } else if (String_eq(option[0], "highlight_changes")) { + this->highlightChanges = atoi(option[1]); + } else if (String_eq(option[0], "highlight_changes_delay_secs")) { + this->highlightDelaySecs = atoi(option[1]); } else if (String_eq(option[0], "header_margin")) { this->headerMargin = atoi(option[1]); } else if (String_eq(option[0], "expand_system_time")) { @@ -265,6 +269,8 @@ bool Settings_write(Settings* this) { fprintf(fd, "highlight_base_name=%d\n", (int) this->highlightBaseName); fprintf(fd, "highlight_megabytes=%d\n", (int) this->highlightMegabytes); fprintf(fd, "highlight_threads=%d\n", (int) this->highlightThreads); + fprintf(fd, "highlight_changes=%d\n", (int) this->highlightChanges); + fprintf(fd, "highlight_changes_delay_secs=%d\n", (int) this->highlightDelaySecs); fprintf(fd, "tree_view=%d\n", (int) this->treeView); fprintf(fd, "header_margin=%d\n", (int) this->headerMargin); fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime); @@ -307,6 +313,7 @@ Settings* Settings_new(int initialCpuCount) { this->updateProcessNames = false; this->showProgramPath = true; this->highlightThreads = true; + this->highlightDelaySecs = DEFAULT_HIGHLIGHT_SECS; #ifdef HAVE_LIBHWLOC this->topologyAffinity = false; #endif diff --git a/Settings.h b/Settings.h index bbd40e16..b04a4308 100644 --- a/Settings.h +++ b/Settings.h @@ -48,6 +48,8 @@ typedef struct Settings_ { bool highlightBaseName; bool highlightMegabytes; bool highlightThreads; + bool highlightChanges; + int highlightDelaySecs; bool updateProcessNames; bool accountGuestInCPUMeter; bool headerMargin; diff --git a/htop.1.in b/htop.1.in index 3e95c201..b688d87d 100644 --- a/htop.1.in +++ b/htop.1.in @@ -4,7 +4,7 @@ htop \- interactive process viewer .SH "SYNOPSIS" .LP .B htop -.RB [ \-dCFhpustv ] +.RB [ \-dCFhpustvH ] .SH "DESCRIPTION" .LP .B htop @@ -62,6 +62,9 @@ Output version information and exit .TP \fB\-t \-\-tree Show processes in tree view +.TP +\fB\-H \-\-highlight-changes=DELAY\fR +Highlight new and old processes .SH "INTERACTIVE COMMANDS" .LP The following commands are supported while in diff --git a/htop.c b/htop.c index e4d437b9..351f5867 100644 --- a/htop.c +++ b/htop.c @@ -46,17 +46,18 @@ static void printHelpFlag(void) { fputs("htop " VERSION "\n" COPYRIGHT "\n" "Released under the GNU GPLv2.\n\n" - "-C --no-color Use a monochrome color scheme\n" - "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n" - "-F --filter=FILTER Show only the commands matching the given filter\n" - "-h --help Print this help screen\n" - "-M --no-mouse Disable the mouse\n" - "-p --pid=PID,[,PID,PID...] Show only the given PIDs\n" - "-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n" - "-t --tree Show the tree view by default\n" - "-u --user[=USERNAME] Show only processes for a given user (or $USER)\n" - "-U --no-unicode Do not use unicode but plain ASCII\n" - "-V --version Print version info\n" + "-C --no-color Use a monochrome color scheme\n" + "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n" + "-F --filter=FILTER Show only the commands matching the given filter\n" + "-h --help Print this help screen\n" + "-M --no-mouse Disable the mouse\n" + "-p --pid=PID,[,PID,PID...] Show only the given PIDs\n" + "-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n" + "-t --tree Show the tree view by default\n" + "-u --user[=USERNAME] Show only processes for a given user (or $USER)\n" + "-U --no-unicode Do not use unicode but plain ASCII\n" + "-V --version Print version info\n" + "-H --highlight-changes[=DELAY] Highlight new and old processes\n" "\n" "Long options may be passed with a single dash.\n\n" "Press F1 inside htop for online help.\n" @@ -76,6 +77,8 @@ typedef struct CommandLineSettings_ { bool enableMouse; bool treeView; bool allowUnicode; + bool highlightChanges; + int highlightDelaySecs; } CommandLineSettings; static CommandLineSettings parseArguments(int argc, char** argv) { @@ -90,28 +93,31 @@ static CommandLineSettings parseArguments(int argc, char** argv) { .enableMouse = true, .treeView = false, .allowUnicode = true, + .highlightChanges = false, + .highlightDelaySecs = -1, }; static struct option long_opts[] = { - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"delay", required_argument, 0, 'd'}, - {"sort-key", required_argument, 0, 's'}, - {"user", optional_argument, 0, 'u'}, - {"no-color", no_argument, 0, 'C'}, - {"no-colour", no_argument, 0, 'C'}, - {"no-mouse", no_argument, 0, 'M'}, - {"no-unicode", no_argument, 0, 'U'}, - {"tree", no_argument, 0, 't'}, - {"pid", required_argument, 0, 'p'}, - {"filter", required_argument, 0, 'F'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"delay", required_argument, 0, 'd'}, + {"sort-key", required_argument, 0, 's'}, + {"user", optional_argument, 0, 'u'}, + {"no-color", no_argument, 0, 'C'}, + {"no-colour", no_argument, 0, 'C'}, + {"no-mouse", no_argument, 0, 'M'}, + {"no-unicode", no_argument, 0, 'U'}, + {"tree", no_argument, 0, 't'}, + {"pid", required_argument, 0, 'p'}, + {"filter", required_argument, 0, 'F'}, + {"highlight-changes", optional_argument, 0, 'H'}, {0,0,0,0} }; int opt, opti=0; /* Parse arguments */ - while ((opt = getopt_long(argc, argv, "hVMCs:td:u::Up:F:", long_opts, &opti))) { + while ((opt = getopt_long(argc, argv, "hVMCs:td:u::Up:F:H::", long_opts, &opti))) { if (opt == EOF) break; switch (opt) { case 'h': @@ -198,6 +204,23 @@ static CommandLineSettings parseArguments(int argc, char** argv) { break; } + case 'H': { + const char *delay = optarg; + if (!delay && optind < argc && argv[optind] != NULL && + (argv[optind][0] != '\0' && argv[optind][0] != '-')) { + delay = argv[optind++]; + } + if (delay) { + if (sscanf(delay, "%16d", &(flags.highlightDelaySecs)) == 1) { + if (flags.highlightDelaySecs < 1) flags.highlightDelaySecs = 1; + } else { + fprintf(stderr, "Error: invalid highlight delay value \"%s\".\n", delay); + exit(1); + } + } + flags.highlightChanges = true; + break; + } default: exit(1); } @@ -271,6 +294,10 @@ int main(int argc, char** argv) { settings->enableMouse = false; if (flags.treeView) settings->treeView = true; + if (flags.highlightChanges) + settings->highlightChanges = true; + if (flags.highlightDelaySecs != -1) + settings->highlightDelaySecs = flags.highlightDelaySecs; CRT_init(settings->delay, settings->colorScheme, flags.allowUnicode); -- cgit v1.2.3 From a83f515f0fb75a079601be0d2e0e24b9402c9e15 Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Sat, 31 Oct 2020 20:36:53 -0400 Subject: Address items from review --- Process.c | 12 ++++++------ Process.h | 3 ++- ProcessList.c | 4 +++- Settings.c | 1 + htop.c | 7 ++++--- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Process.c b/Process.c index f78720a5..d3e6f4c6 100644 --- a/Process.c +++ b/Process.c @@ -6,7 +6,6 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ - #include "config.h" // IWYU pragma: keep #include "Process.h" @@ -383,10 +382,10 @@ void Process_display(const Object* cast, RichString* out) { if (this->tag == true) RichString_setAttr(out, CRT_colors[PROCESS_TAG]); if (this->settings->highlightChanges) { - if (Process_isNew(this)) - out->highlightAttr = CRT_colors[PROCESS_NEW]; if (Process_isTomb(this)) out->highlightAttr = CRT_colors[PROCESS_TOMB]; + else if (Process_isNew(this)) + out->highlightAttr = CRT_colors[PROCESS_NEW]; } assert(out->chlen > 0); } @@ -421,13 +420,14 @@ void Process_toggleTag(Process* this) { } bool Process_isNew(const Process* this) { - if (this->processList && this->processList->scanTs >= this->seenTs) - return (this->processList->scanTs - this->seenTs <= this->processList->settings->highlightDelaySecs); + assert(this->processList); + if (this->processList->scanTs >= this->seenTs) + return this->processList->scanTs - this->seenTs <= this->processList->settings->highlightDelaySecs; return false; } bool Process_isTomb(const Process* this) { - return (this->tombTs > 0); + return this->tombTs > 0; } bool Process_setPriority(Process* this, int priority) { diff --git a/Process.h b/Process.h index e3ff333f..c75ee501 100644 --- a/Process.h +++ b/Process.h @@ -9,8 +9,8 @@ in the source distribution for its full text. */ #include -#include #include +#include #include "Object.h" #include "RichString.h" @@ -78,6 +78,7 @@ typedef struct Process_ { bool tag; bool showChildren; bool show; + bool wasShown; unsigned int pgrp; unsigned int session; unsigned int tty_nr; diff --git a/ProcessList.c b/ProcessList.c index 1ae7b9cc..364de1e0 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -14,6 +14,7 @@ in the source distribution for its full text. #include "CRT.h" #include "XUtils.h" + ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { this->processes = Vector_new(klass, true, DEFAULT_SIZE); this->processTable = Hashtable_new(140, false); @@ -306,6 +307,7 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) { for (int i = 0; i < Vector_size(this->processes); i++) { Process* p = (Process*) Vector_get(this->processes, i); p->updated = false; + p->wasShown = p->show; p->show = true; } @@ -334,7 +336,7 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) { } } else if (p->updated == false) { // process no longer exists - if (this->settings->highlightChanges) { + if (this->settings->highlightChanges && p->wasShown) { // mark tombed p->tombTs = this->scanTs + this->settings->highlightDelaySecs; } else { diff --git a/Settings.c b/Settings.c index a0a05042..8310eecb 100644 --- a/Settings.c +++ b/Settings.c @@ -313,6 +313,7 @@ Settings* Settings_new(int initialCpuCount) { this->updateProcessNames = false; this->showProgramPath = true; this->highlightThreads = true; + this->highlightChanges = false; this->highlightDelaySecs = DEFAULT_HIGHLIGHT_SECS; #ifdef HAVE_LIBHWLOC this->topologyAffinity = false; diff --git a/htop.c b/htop.c index 351f5867..48c6f8d0 100644 --- a/htop.c +++ b/htop.c @@ -50,14 +50,14 @@ static void printHelpFlag(void) { "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n" "-F --filter=FILTER Show only the commands matching the given filter\n" "-h --help Print this help screen\n" + "-H --highlight-changes[=DELAY] Highlight new and old processes\n" "-M --no-mouse Disable the mouse\n" - "-p --pid=PID,[,PID,PID...] Show only the given PIDs\n" + "-p --pid=PID[,PID,PID...] Show only the given PIDs\n" "-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n" "-t --tree Show the tree view by default\n" "-u --user[=USERNAME] Show only processes for a given user (or $USER)\n" "-U --no-unicode Do not use unicode but plain ASCII\n" "-V --version Print version info\n" - "-H --highlight-changes[=DELAY] Highlight new and old processes\n" "\n" "Long options may be passed with a single dash.\n\n" "Press F1 inside htop for online help.\n" @@ -212,7 +212,8 @@ static CommandLineSettings parseArguments(int argc, char** argv) { } if (delay) { if (sscanf(delay, "%16d", &(flags.highlightDelaySecs)) == 1) { - if (flags.highlightDelaySecs < 1) flags.highlightDelaySecs = 1; + if (flags.highlightDelaySecs < 1) + flags.highlightDelaySecs = 1; } else { fprintf(stderr, "Error: invalid highlight delay value \"%s\".\n", delay); exit(1); -- cgit v1.2.3