mirror of
https://github.com/xzeldon/htop.git
synced 2024-12-23 22:55:46 +00:00
expand/collapse tree
This commit is contained in:
parent
bc4f7147cc
commit
9eb912149e
@ -79,6 +79,7 @@ typedef struct Process_ {
|
||||
int indent;
|
||||
char state;
|
||||
bool tag;
|
||||
bool showChildren;
|
||||
pid_t ppid;
|
||||
unsigned int pgrp;
|
||||
unsigned int session;
|
||||
@ -331,9 +332,9 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
|
||||
n -= 4;
|
||||
}
|
||||
if (this->pl->direction == 1)
|
||||
snprintf(buf, n, " `- ");
|
||||
snprintf(buf, n, " `%s ", this->showChildren ? "-" : "+" );
|
||||
else
|
||||
snprintf(buf, n, " ,- ");
|
||||
snprintf(buf, n, " ,%s ", this->showChildren ? "-" : "+" );
|
||||
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
|
||||
Process_writeCommand(this, attr, baseattr, str);
|
||||
return;
|
||||
@ -460,6 +461,7 @@ Process* Process_new(struct ProcessList_ *pl) {
|
||||
this->pid = 0;
|
||||
this->pl = pl;
|
||||
this->tag = false;
|
||||
this->showChildren = true;
|
||||
this->updated = false;
|
||||
this->utime = 0;
|
||||
this->stime = 0;
|
||||
|
@ -81,6 +81,7 @@ typedef struct Process_ {
|
||||
int indent;
|
||||
char state;
|
||||
bool tag;
|
||||
bool showChildren;
|
||||
pid_t ppid;
|
||||
unsigned int pgrp;
|
||||
unsigned int session;
|
||||
|
@ -331,7 +331,7 @@ int ProcessList_size(ProcessList* this) {
|
||||
return (Vector_size(this->processes));
|
||||
}
|
||||
|
||||
static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction) {
|
||||
static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction, bool show) {
|
||||
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
|
||||
|
||||
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
||||
@ -344,17 +344,21 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
|
||||
int size = Vector_size(children);
|
||||
for (int i = 0; i < size; i++) {
|
||||
Process* process = (Process*) (Vector_get(children, i));
|
||||
int s = this->processes2->items;
|
||||
if (direction == 1)
|
||||
Vector_add(this->processes2, process);
|
||||
else
|
||||
Vector_insert(this->processes2, 0, process);
|
||||
assert(this->processes2->items == s+1); (void)s;
|
||||
int nextIndent = indent;
|
||||
if (i < size - 1)
|
||||
nextIndent = indent | (1 << level);
|
||||
ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction);
|
||||
process->indent = indent | (1 << level);
|
||||
if (show) {
|
||||
int s = this->processes2->items;
|
||||
if (direction == 1)
|
||||
Vector_add(this->processes2, process);
|
||||
else
|
||||
Vector_insert(this->processes2, 0, process);
|
||||
assert(this->processes2->items == s+1); (void)s;
|
||||
int nextIndent = indent;
|
||||
if (i < size - 1)
|
||||
nextIndent = indent | (1 << level);
|
||||
ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction, process->showChildren);
|
||||
process->indent = indent | (1 << level);
|
||||
} else {
|
||||
Hashtable_remove(this->processTable, process->pid);
|
||||
}
|
||||
}
|
||||
Vector_delete(children);
|
||||
}
|
||||
@ -382,13 +386,13 @@ void ProcessList_sort(ProcessList* this) {
|
||||
init->indent = 0;
|
||||
Vector_add(this->processes2, init);
|
||||
// Recursively empty list
|
||||
ProcessList_buildTree(this, init->pid, 0, 0, direction);
|
||||
ProcessList_buildTree(this, init->pid, 0, 0, direction, true);
|
||||
// Add leftovers
|
||||
while (Vector_size(this->processes)) {
|
||||
Process* p = (Process*) (Vector_take(this->processes, 0));
|
||||
p->indent = 0;
|
||||
Vector_add(this->processes2, p);
|
||||
ProcessList_buildTree(this, p->pid, 0, 0, direction);
|
||||
ProcessList_buildTree(this, p->pid, 0, 0, direction, p->showChildren);
|
||||
}
|
||||
assert(Vector_size(this->processes2) == vsize); (void)vsize;
|
||||
assert(Vector_size(this->processes) == 0);
|
||||
|
15
Vector.c
15
Vector.c
@ -20,8 +20,6 @@ in the source distribution for its full text.
|
||||
#define DEFAULT_SIZE -1
|
||||
#endif
|
||||
|
||||
typedef void(*Vector_procedure)(void*);
|
||||
|
||||
typedef struct Vector_ {
|
||||
Object **array;
|
||||
Object_Compare compare;
|
||||
@ -255,16 +253,3 @@ inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
static void Vector_foreach(Vector* this, Vector_procedure f) {
|
||||
int i;
|
||||
assert(Vector_isConsistent(this));
|
||||
|
||||
for (i = 0; i < this->items; i++)
|
||||
f(this->array[i]);
|
||||
assert(Vector_isConsistent(this));
|
||||
}
|
||||
|
||||
*/
|
||||
|
6
Vector.h
6
Vector.h
@ -22,8 +22,6 @@ in the source distribution for its full text.
|
||||
#define DEFAULT_SIZE -1
|
||||
#endif
|
||||
|
||||
typedef void(*Vector_procedure)(void*);
|
||||
|
||||
typedef struct Vector_ {
|
||||
Object **array;
|
||||
Object_Compare compare;
|
||||
@ -73,8 +71,4 @@ void Vector_add(Vector* this, void* data_);
|
||||
|
||||
extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
19
htop.c
19
htop.c
@ -117,10 +117,10 @@ static void showHelp(ProcessList* pl) {
|
||||
mvaddstr(11, 0, " F3 /: incremental name search H: hide/show user threads");
|
||||
mvaddstr(12, 0, " K: hide/show kernel threads");
|
||||
mvaddstr(13, 0, " Space: tag processes F: cursor follows process");
|
||||
mvaddstr(14, 0, " U: untag all processes");
|
||||
mvaddstr(14, 0, " U: untag all processes + -: expand/collapse tree");
|
||||
mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
|
||||
mvaddstr(16, 0, " - ] F7: higher priority (root only) M: sort by MEM%");
|
||||
mvaddstr(17, 0, " + [ F8: lower priority (+ nice) T: sort by TIME");
|
||||
mvaddstr(16, 0, " ] F7: higher priority (root only) M: sort by MEM%");
|
||||
mvaddstr(17, 0, " [ F8: lower priority (+ nice) T: sort by TIME");
|
||||
#ifdef HAVE_PLPA
|
||||
if (pl->processorCount > 1)
|
||||
mvaddstr(18, 0, " a: set CPU affinity F4 I: invert sort order");
|
||||
@ -639,6 +639,16 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '+':
|
||||
case '=':
|
||||
case '-':
|
||||
{
|
||||
Process* p = (Process*) Panel_getSelected(panel);
|
||||
p->showChildren = !p->showChildren;
|
||||
refreshTimeout = 0;
|
||||
doRecalculate = true;
|
||||
break;
|
||||
}
|
||||
case KEY_F(9):
|
||||
case 'k':
|
||||
{
|
||||
@ -751,15 +761,12 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
case KEY_F(8):
|
||||
case '[':
|
||||
case '=':
|
||||
case '+':
|
||||
{
|
||||
doRefresh = changePriority(panel, 1);
|
||||
break;
|
||||
}
|
||||
case KEY_F(7):
|
||||
case ']':
|
||||
case '-':
|
||||
{
|
||||
doRefresh = changePriority(panel, -1);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user