From 266ab52b3a741a58fb17c48b0f7939d7c5d266de Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 11 Apr 2016 13:00:19 +0200 Subject: Imported Upstream version 0.6 --- htop.c | 546 ++++++++++++++++++++++++----------------------------------------- 1 file changed, 201 insertions(+), 345 deletions(-) (limited to 'htop.c') diff --git a/htop.c b/htop.c index b851a70..a1bd7ee 100644 --- a/htop.c +++ b/htop.c @@ -5,6 +5,13 @@ Released under the GNU GPL, see the COPYING file in the source distribution for its full text. */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + #include "ProcessList.h" #include "CRT.h" #include "ListBox.h" @@ -17,18 +24,11 @@ in the source distribution for its full text. #include "ListItem.h" #include "CategoriesListBox.h" #include "SignalsListBox.h" +#include "TraceScreen.h" #include "config.h" #include "debug.h" -#include -#include -#include -#include -#include - -int usleep(int usec); - //#link m #define INCSEARCH_MAX 40 @@ -47,20 +47,19 @@ void printHelpFlag() { clear(); printf("htop " VERSION " - (C) 2004,2005 Hisham Muhammad.\n"); printf("Released under the GNU GPL.\n\n"); - printf("-d DELAY Delay between updates, in tenths of seconds\n\n"); + printf("-d DELAY Delay between updates, in tenths of seconds\n\n"); + printf("-u USERNAME Show only processes of a given user\n\n"); printf("Press F1 inside htop for online help.\n"); - printf("See the man page for full info.\n\n"); + printf("See the man page for full information.\n\n"); exit(0); } void showHelp() { clear(); attrset(CRT_colors[HELP_BOLD]); - for (int i = 0; i < LINES; i++) { - move(i, 0); hline(' ', COLS); - } mvaddstr(0, 0, "htop " VERSION " - (C) 2004 Hisham Muhammad."); - mvaddstr(1, 0, "Released under the GNU GPL. See man page for more info."); + mvaddstr(1, 0, "Released under the GNU GPL. See 'man' page for more info."); + attrset(CRT_colors[DEFAULT_COLOR]); mvaddstr(3, 0, "CPU usage bar: "); #define addattrstr(a,s) attrset(a);addstr(s) @@ -85,293 +84,119 @@ void showHelp() { addattrstr(CRT_colors[BAR_SHADOW], " used/total"); addattrstr(CRT_colors[BAR_BORDER], "]"); attrset(CRT_colors[DEFAULT_COLOR]); + mvaddstr(6,0, "Type and layout of header meters is configurable in the setup screen."); + + mvaddstr( 8, 0, " Arrows: scroll process list F5 t: tree view"); + mvaddstr( 9, 0, " Digits: incremental PID search u: show processes of a single user"); + mvaddstr(10, 0, " F3 /: incremental name search H: hide/show user threads"); + mvaddstr(11, 0, " K: hide/show kernel threads"); + mvaddstr(12, 0, " Space: tag processes F: cursor follows process"); + mvaddstr(13, 0, " U: untag all processes"); + mvaddstr(14, 0, " F9 k: kill process/tagged processes P: sort by CPU%"); + mvaddstr(15, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%"); + mvaddstr(16, 0, " - ] F8: higher priority (root only) T: sort by TIME"); + mvaddstr(17, 0, " F4 I: invert sort order"); + mvaddstr(18, 0, " F2 S: setup F6 >: select sort column"); + mvaddstr(19, 0, " F1 h: show this help screen"); + mvaddstr(20, 0, " F10 q: quit s: trace syscalls with strace"); attrset(CRT_colors[HELP_BOLD]); - mvaddstr(7, 0, "Keyboard shortcuts"); + mvaddstr( 8, 0, " Arrows"); mvaddstr( 8,40, " F5 t"); + mvaddstr( 9, 0, " Digits"); mvaddstr( 9,40, " u"); + mvaddstr(10, 0, " F3 /"); mvaddstr(10,40, " H"); + mvaddstr(11,40, " K"); + mvaddstr(12, 0, " Space"); mvaddstr(12,40, " F"); + mvaddstr(13, 0, " U"); + mvaddstr(14, 0, " F9 k"); mvaddstr(14,40, " P"); + mvaddstr(15, 0, " + [ F7"); mvaddstr(15,40, " M"); + mvaddstr(16, 0, " - ] F8"); mvaddstr(16,40, " T"); + mvaddstr(17,40, " F4 I"); + mvaddstr(18, 0, " F2 S"); mvaddstr(18,40, " F6 >"); + mvaddstr(19, 0, " F1 h"); + mvaddstr(20, 0, " F10 q"); mvaddstr(20,40, " s"); attrset(CRT_colors[DEFAULT_COLOR]); - mvaddstr(8, 0, " Arrows - scroll process list Digits - incremental PID search"); - mvaddstr(9, 0, " Space - tag process / - incremental name search"); - mvaddstr(10, 0, " k - kill process/tagged processes U - shadow other users"); - mvaddstr(11, 0, " I - invert sort order t - tree view"); - mvaddstr(12, 0, " P - sort by CPU% K - hide kernel threads"); - mvaddstr(13, 0, " M - sort by MEM% F - cursor follows process"); - mvaddstr(14, 0, " T - sort by TIME Ctrl-L - refresh"); - mvaddstr(15, 0, " [ - decrease priority ] - increase priority (superuser)"); - mvaddstr(16, 0, " C - configure columns S - setup"); - mvaddstr(17, 0, " h - shows this help screen q - quit"); + attrset(CRT_colors[HELP_BOLD]); - mvaddstr(19,0, "Press any key to return."); + mvaddstr(23,0, "Press any key to return."); attrset(CRT_colors[DEFAULT_COLOR]); refresh(); CRT_readKey(); clear(); } -void showColumnConfig(ProcessList* pl) { - - int i; - int startSelected = 0; - int startAvailable = 0; - int currRow = 0; - int currCol = 0; - bool configure = true; - bool save = false; - - ProcessField avail[LAST_PROCESSFIELD + 1] = { 0 }; - ProcessField select[LAST_PROCESSFIELD + 1] = { 0 }; - ProcessField original[LAST_PROCESSFIELD + 1] = { 0 }; - int countAvail = 0; - int countSelect = 0; - int countOriginal = 0; - - for(i = 0; i < LAST_PROCESSFIELD && pl->fields[i] != LAST_PROCESSFIELD; i++) { - select[i] = pl->fields[i]; - original[i] = pl->fields[i]; - countSelect++; - } - countOriginal = countSelect; - select[countSelect] = LAST_PROCESSFIELD; - original[i] = pl->fields[i]; - for(i = 0; i < LAST_PROCESSFIELD; i++) { - bool found = false; - for(int j = 0; j < LAST_PROCESSFIELD && pl->fields[j] != LAST_PROCESSFIELD; j++) - if(i == pl->fields[j]) found = true; - if(!found) { - avail[countAvail] = i; - countAvail++; - } - } - avail[countAvail] = LAST_PROCESSFIELD; - - clear(); - mvaddstr(0, 0, "Column configuration"); - attron(CRT_colors[HELP_BOLD]); - mvaddstr(4, 1, "Selected Columns"); - attroff(CRT_colors[HELP_BOLD]); - attron(CRT_colors[HELP_BOLD]); - mvaddstr(4, (COLS / 2) + 1, "Available Columns"); - attroff(CRT_colors[HELP_BOLD]); - char* functions[5] = { "Move Up", "Move Down", "Move <->", "Apply ", "Cancel" }; - char* keys[5] = { "- ", "+ ", "Enter", "w ", "Esc" }; - int events[5] = { '-', '+', 13, 'w', 27 }; - FunctionBar* fuBar = FunctionBar_new(5, functions, keys, events); - FunctionBar_draw(fuBar, NULL); - - while(configure) { - - for(i = 0; i < LAST_PROCESSFIELD; i++) - pl->fields[i] = select[i]; - - for(i = 0; i < LAST_PROCESSFIELD; i++) { - int field = select[i + startSelected]; - if(field == LAST_PROCESSFIELD) break; - if(i == (LINES - 8)) break; - mvhline(5 + i, 1, ' ', COLS / 2); - mvaddstr(5 + i, 1, Process_fieldNames[field]); - } - for (; i < LINES - 8; i++) - mvhline(5 + i, 1, ' ', COLS / 2); - - RichString str = ProcessList_printHeader(pl); - if (str.len > 0) { - int attr = CRT_colors[PANEL_HEADER_FOCUS]; - attron(attr); - RichString_applyAttr(&str, attr); - move(2, 0); - hline(' ', 512); - mvaddchstr(2, 0, str.chstr); - attroff(attr); - } - - for(i = 0; i < LAST_PROCESSFIELD; i++) { - int field = avail[i + startAvailable]; - if(field == LAST_PROCESSFIELD) break; - if(i == (LINES - 8)) break; - mvhline(5 + i, (COLS / 2) + 1, ' ', COLS / 2); - mvaddstr(5 + i, (COLS / 2) + 1, Process_fieldNames[field]); - } - for (; i < LINES - 8; i++) - mvhline(5 + i, (COLS / 2) + 1, ' ', COLS / 2); - mvchgat(5 + currRow, (currCol) ? (COLS / 2) + 1 : 1, (COLS / 2) - 2, - A_REVERSE, CRT_colors[PANEL_HIGHLIGHT_FOCUS], NULL); - - refresh(); - - int *numEntries = (currCol) ? &countAvail : &countSelect; - int *notEntries = (currCol) ? &countSelect : &countAvail; - int *start = (currCol) ? &startAvailable : &startSelected; - int pos = currRow + *start; - - int c = getch(); - - mvchgat(5 + currRow, (currCol) ? (COLS / 2) + 1 : 1, (COLS / 2) - 2, - A_NORMAL, 0, NULL); - - switch(c) { - case KEY_DOWN: - if(currRow + *start == *numEntries - 1) break; - if(currRow < LINES - 9) currRow++; - else { - if((*numEntries - *start) > (LINES - 8)) - (*start)++; - } - break; - - case KEY_NPAGE: - // TODO: quick and dirty hack. Better improve. - for (int i = 0; i < LINES - 9; i++) { - if(currRow + *start == *numEntries - 1) break; - if(currRow < LINES - 9) currRow++; - else { - if((*numEntries - *start) > (LINES - 8)) - (*start)++; - } - } - break; - - case KEY_PPAGE: - // TODO: quick and dirty hack. Better improve. - for (int i = 0; i < LINES - 9; i++) { - if(currRow > 0) currRow--; - else { - if(*start > 0) - (*start)--; - } - } - break; - - case KEY_UP: - if(currRow > 0) currRow--; - else { - if(*start > 0) - (*start)--; - } - break; - - case KEY_LEFT: - currCol = 0; - if(currRow > *notEntries - 1) currRow = *notEntries - 1; - break; - - case KEY_RIGHT: - if(countAvail == 0) break; - currCol = 1; - if(currRow > *notEntries - 1) currRow = *notEntries - 1; - break; - - case '}': - case ']': - case '+': - case '.': - case '=': { - if(currRow + *start == *numEntries - 1) break; - ProcessField *array = (currCol) ? avail : select; - ProcessField inv = array[pos]; - array[pos] = array[pos + 1]; - array[pos + 1] = inv; - if(currRow < LINES - 9) currRow++; //From Key Down - else { - if((*numEntries - *start) > (LINES - 8)) - (*start)++; - } - break; - } - - case '{': - case '[': - case '_': - case ',': - case '-': { - if(currRow + *start == 0) break; - ProcessField *array = (currCol) ? avail : select; - ProcessField inv = array[pos]; - array[pos] = array[pos - 1]; - array[pos - 1] = inv; - if(currRow > 0) currRow--; //From Key up - else { - if(*start > 0) - (*start)--; - } - break; - } - - case 0x0a: - case 0x0d: - case KEY_ENTER: - if(*numEntries == 0) break; - if(!currCol && *numEntries == 1) break; - ProcessField *array = (currCol) ? avail : select; - ProcessField *notarray = (currCol) ? select : avail; - for(i = *notEntries + 2; i >=1; i--) { - notarray[i] = notarray[i-1]; - } - notarray[0] = array[pos]; - (*notEntries)++; - - for(i = pos; pos < LAST_PROCESSFIELD; i++) { - if(array[i] == LAST_PROCESSFIELD) break; - array[i] = array[i + 1]; - } - (*numEntries)--; - array[*numEntries] = LAST_PROCESSFIELD; - if(*start > 0) (*start)--; - else - if(pos > *numEntries - 1) currRow--; - - currCol = currCol == 0 ? 1 : 0; - currRow = 0; - - if(*numEntries == 0) { - currCol = 0; - currRow = 0; - } - break; - - case 27: - case 'q': - configure = false; - break; - - case 'w': - save = true; - configure = false; - break; +static void Setup_run(Settings* settings, int headerHeight) { + ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); + CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr); + ScreenManager_add(scr, (ListBox*) lbCategories, NULL, 16); + CategoriesListBox_makeMetersPage(lbCategories); + ListBox* lbFocus; + int ch; + ScreenManager_run(scr, &lbFocus, &ch); + ScreenManager_delete(scr); +} - default: - break; +static bool changePriority(ListBox* lb, int delta) { + bool anyTagged = false; + for (int i = 0; i < ListBox_getSize(lb); i++) { + Process* p = (Process*) ListBox_get(lb, i); + if (p->tag) { + Process_setPriority(p, p->nice + delta); + anyTagged = true; } } - - if(save) { - for(i = 0; i < LAST_PROCESSFIELD && select[i] != LAST_PROCESSFIELD; i++) - pl->fields[i] = select[i]; - pl->fields[countSelect] = LAST_PROCESSFIELD; + if (!anyTagged) { + Process* p = (Process*) ListBox_getSelected(lb); + Process_setPriority(p, p->nice + delta); } - else { - for(i = 0; i < LAST_PROCESSFIELD && original[i] != LAST_PROCESSFIELD; i++) - pl->fields[i] = original[i]; - pl->fields[countOriginal] = LAST_PROCESSFIELD; - } - FunctionBar_delete(fuBar); - - clear(); + return anyTagged; +} +static HandlerResult pickWithEnter(ListBox* lb, int ch) { + if (ch == 13) + return BREAK_LOOP; + return IGNORED; } -void Setup_run(Settings* settings, int headerHeight) { - ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); - CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr); - ScreenManager_add(scr, (ListBox*) lbCategories, 16); - CategoriesListBox_makeMetersPage(lbCategories); +static Object* pickFromList(ListBox* lb, ListBox* list, int x, int y, char** keyLabels, FunctionBar* prevBar) { + char* fuKeys[2] = {"Enter", "Esc"}; + int fuEvents[2] = {13, 27}; + if (!lb->eventHandler) + ListBox_setEventHandler(list, pickWithEnter); + ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false); + ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1); + ScreenManager_add(scr, lb, NULL, -1); ListBox* lbFocus; int ch; ScreenManager_run(scr, &lbFocus, &ch); ScreenManager_delete(scr); + ListBox_move(lb, 0, y); + ListBox_resize(lb, COLS, LINES-y-1); + FunctionBar_draw(prevBar, NULL); + if (lbFocus == list && ch == 13) { + return ListBox_getSelected(list); + } + return NULL; +} + +void addUserToList(int key, void* userCast, void* lbCast) { + char* user = (char*) userCast; + ListBox* lb = (ListBox*) lbCast; + ListBox_add(lb, (Object*) ListItem_new(user, key)); +} + +void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) { + struct passwd* user = getpwnam(userName); + if (user) { + *userOnly = true; + *userId = user->pw_uid; + } } int main(int argc, char** argv) { int delay = -1; + bool userOnly = false; + uid_t userId = 0; if (argc > 0) { if (String_eq(argv[1], "--help")) { @@ -383,6 +208,9 @@ int main(int argc, char** argv) { sscanf(argv[2], "%d", &delay); if (delay < 1) delay = 1; if (delay > 100) delay = 100; + } else if (String_eq(argv[1], "-u")) { + if (argc < 2) printHelpFlag(); + setUserOnly(argv[2], &userOnly, &userId); } } @@ -416,7 +244,7 @@ int main(int argc, char** argv) { CRT_init(settings->delay, settings->colorScheme); lb = ListBox_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); char* searchFunctions[3] = {"Next ", "Exit ", " Search: "}; char* searchKeys[3] = {"F3", "Esc", " "}; @@ -436,16 +264,17 @@ int main(int argc, char** argv) { bool follow = false; struct timeval tv; - double time = 0.0; + double newTime = 0.0; double oldTime = 0.0; bool recalculate; + while (!quit) { gettimeofday(&tv, NULL); - time = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); - recalculate = (time - oldTime > CRT_delay); + newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); + recalculate = (newTime - oldTime > CRT_delay); if (recalculate) - oldTime = time; + oldTime = newTime; if (doRefresh) { incSearchIndex = 0; incSearchBuffer[0] = 0; @@ -462,12 +291,16 @@ int main(int argc, char** argv) { } ListBox_prune(lb); int size = ProcessList_size(pl); + int lbi = 0; for (int i = 0; i < size; i++) { Process* p = ProcessList_get(pl, i); - ListBox_set(lb, i, (Object*)p); - if ((!follow && i == currPos) || (follow && p->pid == currPid)) { - ListBox_setSelected(lb, i); - lb->scrollV = currScrollV; + if (!userOnly || (p->st_uid == userId)) { + ListBox_set(lb, lbi, (Object*)p); + if ((!follow && lbi == currPos) || (follow && p->pid == currPid)) { + ListBox_setSelected(lb, lbi); + lb->scrollV = currScrollV; + } + lbi++; } } } @@ -575,7 +408,8 @@ int main(int argc, char** argv) { refreshTimeout = 0; pl->sortKey = PERCENT_MEM; pl->treeView = false; - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + settings->changed = true; + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); break; } case 'T': @@ -583,7 +417,17 @@ int main(int argc, char** argv) { refreshTimeout = 0; pl->sortKey = TIME; pl->treeView = false; - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + settings->changed = true; + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); + break; + } + case 'U': + { + for (int i = 0; i < ListBox_getSize(lb); i++) { + Process* p = (Process*) ListBox_get(lb, i); + p->tag = false; + } + doRefresh = true; break; } case 'P': @@ -591,7 +435,8 @@ int main(int argc, char** argv) { refreshTimeout = 0; pl->sortKey = PERCENT_CPU; pl->treeView = false; - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + settings->changed = true; + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); break; } case KEY_F(1): @@ -602,7 +447,6 @@ int main(int argc, char** argv) { refreshTimeout = 0; break; } - case '\012': // Enter case '\014': // Ctrl+L { clear(); @@ -617,12 +461,24 @@ int main(int argc, char** argv) { ListBox_onKey(lb, KEY_DOWN); break; } + case 's': + { + TraceScreen* ts = TraceScreen_new((Process*) ListBox_getSelected(lb)); + TraceScreen_run(ts); + TraceScreen_delete(ts); + clear(); + FunctionBar_draw(defaultBar, NULL); + refreshTimeout = 0; + CRT_enableDelay(); + break; + } case 'S': + case 'C': case KEY_F(2): { Setup_run(settings, headerHeight); // TODO: shouldn't need this, colors should be dynamic - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); headerHeight = Header_calculateHeight(header); ListBox_move(lb, 0, headerHeight); ListBox_resize(lb, COLS, LINES-headerHeight-1); @@ -635,33 +491,39 @@ int main(int argc, char** argv) { follow = true; continue; } + case 'u': + { + ListBox* lbu = ListBox_new(0, 0, 0, 0, LISTITEM_CLASS, true); + ListBox_setHeader(lbu, "Show processes of:"); + UsersTable_foreach(ut, addUserToList, lbu); + TypedVector_sort(lbu->items); + ListItem* allUsers = ListItem_new("All users", -1); + ListBox_insert(lbu, 0, (Object*) allUsers); + char* fuFunctions[2] = {"Show ", "Cancel "}; + ListItem* picked = (ListItem*) pickFromList(lb, lbu, 20, headerHeight, fuFunctions, defaultBar); + if (picked) { + if (picked == allUsers) { + userOnly = false; + break; + } else { + setUserOnly(ListItem_getRef(picked), &userOnly, &userId); + } + } + break; + } case KEY_F(9): case 'k': { - const int lbkWidth = 15; if (!lbk) { - lbk = (ListBox*) SignalsListBox_new(0, headerHeight, lbkWidth-1, LINES - headerHeight - 2); + lbk = (ListBox*) SignalsListBox_new(0, 0, 0, 0); } SignalsListBox_reset((SignalsListBox*) lbk); - char* fuFunctions[2] = {"Send ", "Cancel "}; - char* fuKeys[2] = {"Enter", "Esc"}; - int fuEvents[2] = {13, 27}; - FunctionBar* fuBar = FunctionBar_new(2, fuFunctions, fuKeys, fuEvents); - - ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, false); - ScreenManager_add(scr, lbk, lbkWidth - 1); - ScreenManager_add(scr, lb, -1); - ScreenManager_setFunctionBar(scr, fuBar); - ListBox* lbFocus; - int ch; - ScreenManager_run(scr, &lbFocus, &ch); - - if (lbFocus == lbk && ch == 13) { - Signal* signal = (Signal*) ListBox_getSelected(lbk); + Signal* signal = (Signal*) pickFromList(lb, lbk, 15, headerHeight, fuFunctions, defaultBar); + if (signal) { if (signal->number != 0) { - ListBox_setHeader(lbk, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Sending...")); - ListBox_draw(lbk, true); + ListBox_setHeader(lb, "Sending..."); + ListBox_draw(lb, true); refresh(); bool anyTagged = false; for (int i = 0; i < ListBox_getSize(lb); i++) { @@ -679,14 +541,8 @@ int main(int argc, char** argv) { napms(500); } } - - FunctionBar_delete(fuBar); - ScreenManager_delete(scr); - - ListBox_move(lb, 0, headerHeight); - ListBox_resize(lb, COLS, LINES-headerHeight-1); - FunctionBar_draw(defaultBar, NULL); - + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); + refreshTimeout = 0; break; } case KEY_F(10): @@ -696,27 +552,37 @@ int main(int argc, char** argv) { case '<': case ',': case KEY_F(18): - { - refreshTimeout = 0; - pl->treeView = false; - ProcessList_sortKey(pl, -1); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); - break; - } case '>': case '.': case KEY_F(6): { + ListBox* lbf = ListBox_new(0,0,0,0,LISTITEM_CLASS,true); + ListBox_setHeader(lbf, "Sort by"); + char* fuFunctions[2] = {"Sort ", "Cancel "}; + ProcessField* fields = pl->fields; + for (int i = 0; fields[i]; i++) { + char* name = String_trim(Process_printField(fields[i])); + ListBox_add(lbf, (Object*) ListItem_new(name, fields[i])); + if (fields[i] == pl->sortKey) + ListBox_setSelected(lbf, i); + free(name); + } + ListItem* field = (ListItem*) pickFromList(lb, lbf, 15, headerHeight, fuFunctions, defaultBar); + if (field) { + pl->treeView = false; + settings->changed = true; + pl->sortKey = field->key; + } + ((Object*)lbf)->delete((Object*)lbf); + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); refreshTimeout = 0; - pl->treeView = false; - ProcessList_sortKey(pl, 1); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); break; } case 'I': case KEY_F(4): { refreshTimeout = 0; + settings->changed = true; ProcessList_invertSortOrder(pl); break; } @@ -725,18 +591,14 @@ int main(int argc, char** argv) { case '=': case '+': { - Process* p = (Process*) ListBox_getSelected(lb);; - Process_setPriority(p, p->nice + 1); - doRefresh = false; + doRefresh = changePriority(lb, 1); break; } case KEY_F(7): case ']': case '-': { - Process* p = (Process*) ListBox_getSelected(lb);; - Process_setPriority(p, p->nice - 1); - doRefresh = false; + doRefresh = changePriority(lb, -1); break; } case KEY_F(3): @@ -744,28 +606,21 @@ int main(int argc, char** argv) { FunctionBar_draw(searchBar, incSearchBuffer); incSearchMode = true; break; - case 'C': - showColumnConfig(pl); - FunctionBar_draw(defaultBar, NULL); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); - refreshTimeout = 0; - break; case 't': case KEY_F(5): refreshTimeout = 0; pl->treeView = !pl->treeView; + settings->changed = true; break; case 'H': refreshTimeout = 0; pl->hideThreads = !pl->hideThreads; - break; - case 'U': - refreshTimeout = 0; - pl->shadowOtherUsers = !pl->shadowOtherUsers; + settings->changed = true; break; case 'K': refreshTimeout = 0; pl->hideKernelThreads = !pl->hideKernelThreads; + settings->changed = true; break; default: doRefresh = false; @@ -781,11 +636,12 @@ int main(int argc, char** argv) { refresh(); CRT_done(); - Settings_write(settings); + if (settings->changed) + Settings_write(settings); Header_delete(header); ProcessList_delete(pl); - FunctionBar_delete(searchBar); - FunctionBar_delete(defaultBar); + FunctionBar_delete((Object*)searchBar); + FunctionBar_delete((Object*)defaultBar); ((Object*)lb)->delete((Object*)lb); if (lbk) ((Object*)lbk)->delete((Object*)lbk); -- cgit v1.2.3