mirror of
https://github.com/xzeldon/htop.git
synced 2024-12-23 22:55:46 +00:00
Introduce screen tabs
This is a forward port (by nathans) of Hisham's original code.
This commit is contained in:
parent
ff4f44b22a
commit
72ba20fa5f
70
Action.c
70
Action.c
@ -58,7 +58,7 @@ Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess)
|
||||
header->pl->following = pid;
|
||||
unfollow = true;
|
||||
}
|
||||
ScreenManager_run(scr, &panelFocus, &ch);
|
||||
ScreenManager_run(scr, &panelFocus, &ch, NULL);
|
||||
if (unfollow) {
|
||||
header->pl->following = -1;
|
||||
}
|
||||
@ -85,7 +85,7 @@ Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess)
|
||||
static void Action_runSetup(State* st) {
|
||||
ScreenManager* scr = ScreenManager_new(st->header, st->settings, st, true);
|
||||
CategoriesPanel_new(scr, st->settings, st->header, st->pl);
|
||||
ScreenManager_run(scr, NULL, NULL);
|
||||
ScreenManager_run(scr, NULL, NULL, "Setup");
|
||||
ScreenManager_delete(scr);
|
||||
if (st->settings->changed) {
|
||||
Header_writeBackToSettings(st->header);
|
||||
@ -154,7 +154,7 @@ static bool collapseIntoParent(Panel* panel) {
|
||||
}
|
||||
|
||||
Htop_Reaction Action_setSortKey(Settings* settings, ProcessField sortKey) {
|
||||
Settings_setSortKey(settings, sortKey);
|
||||
ScreenSettings_setSortKey(settings->ss, sortKey);
|
||||
return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_UPDATE_PANELHDR | HTOP_KEEP_FOLLOWING;
|
||||
}
|
||||
|
||||
@ -164,8 +164,9 @@ static Htop_Reaction actionSetSortColumn(State* st) {
|
||||
Htop_Reaction reaction = HTOP_OK;
|
||||
Panel* sortPanel = Panel_new(0, 0, 0, 0, Class(ListItem), true, FunctionBar_newEnterEsc("Sort ", "Cancel "));
|
||||
Panel_setHeader(sortPanel, "Sort by");
|
||||
const ProcessField* fields = st->settings->fields;
|
||||
Hashtable* dynamicColumns = st->settings->dynamicColumns;
|
||||
const Settings* settings = st->settings;
|
||||
const ProcessField* fields = settings->ss->fields;
|
||||
Hashtable* dynamicColumns = settings->dynamicColumns;
|
||||
for (int i = 0; fields[i]; i++) {
|
||||
char* name = NULL;
|
||||
if (fields[i] >= LAST_PROCESSFIELD) {
|
||||
@ -177,7 +178,7 @@ static Htop_Reaction actionSetSortColumn(State* st) {
|
||||
name = String_trim(Process_fields[fields[i]].name);
|
||||
}
|
||||
Panel_add(sortPanel, (Object*) ListItem_new(name, fields[i]));
|
||||
if (fields[i] == Settings_getActiveSortKey(st->settings))
|
||||
if (fields[i] == ScreenSettings_getActiveSortKey(settings->ss))
|
||||
Panel_setSelected(sortPanel, i);
|
||||
|
||||
free(name);
|
||||
@ -231,16 +232,18 @@ static Htop_Reaction actionToggleMergedCommand(State* st) {
|
||||
}
|
||||
|
||||
static Htop_Reaction actionToggleTreeView(State* st) {
|
||||
st->settings->treeView = !st->settings->treeView;
|
||||
ScreenSettings* ss = st->settings->ss;
|
||||
ss->treeView = !ss->treeView;
|
||||
|
||||
if (!st->settings->allBranchesCollapsed)
|
||||
if (!ss->allBranchesCollapsed)
|
||||
ProcessList_expandTree(st->pl);
|
||||
return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
||||
}
|
||||
|
||||
static Htop_Reaction actionExpandOrCollapseAllBranches(State* st) {
|
||||
st->settings->allBranchesCollapsed = !st->settings->allBranchesCollapsed;
|
||||
if (st->settings->allBranchesCollapsed)
|
||||
ScreenSettings* ss = st->settings->ss;
|
||||
ss->allBranchesCollapsed = !ss->allBranchesCollapsed;
|
||||
if (ss->allBranchesCollapsed)
|
||||
ProcessList_collapseAllBranches(st->pl);
|
||||
else
|
||||
ProcessList_expandTree(st->pl);
|
||||
@ -277,7 +280,7 @@ static Htop_Reaction actionLowerPriority(State* st) {
|
||||
}
|
||||
|
||||
static Htop_Reaction actionInvertSortOrder(State* st) {
|
||||
Settings_invertSortOrder(st->settings);
|
||||
ScreenSettings_invertSortOrder(st->settings->ss);
|
||||
if (st->pauseProcessUpdate)
|
||||
ProcessList_sort(st->pl);
|
||||
return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING;
|
||||
@ -289,7 +292,7 @@ static Htop_Reaction actionExpandOrCollapse(State* st) {
|
||||
}
|
||||
|
||||
static Htop_Reaction actionCollapseIntoParent(State* st) {
|
||||
if (!st->settings->treeView) {
|
||||
if (!st->settings->ss->treeView) {
|
||||
return HTOP_OK;
|
||||
}
|
||||
bool changed = collapseIntoParent((Panel*)st->mainPanel);
|
||||
@ -297,7 +300,46 @@ static Htop_Reaction actionCollapseIntoParent(State* st) {
|
||||
}
|
||||
|
||||
static Htop_Reaction actionExpandCollapseOrSortColumn(State* st) {
|
||||
return st->settings->treeView ? actionExpandOrCollapse(st) : actionSetSortColumn(st);
|
||||
return st->settings->ss->treeView ? actionExpandOrCollapse(st) : actionSetSortColumn(st);
|
||||
}
|
||||
|
||||
static Htop_Reaction actionNextScreen(State* st) {
|
||||
Settings* settings = st->settings;
|
||||
settings->ssIndex++;
|
||||
if (settings->ssIndex == settings->nScreens) {
|
||||
settings->ssIndex = 0;
|
||||
}
|
||||
settings->ss = settings->screens[settings->ssIndex];
|
||||
return HTOP_REFRESH;
|
||||
}
|
||||
|
||||
static Htop_Reaction actionPrevScreen(State* st) {
|
||||
Settings* settings = st->settings;
|
||||
if (settings->ssIndex == 0) {
|
||||
settings->ssIndex = settings->nScreens - 1;
|
||||
} else {
|
||||
settings->ssIndex--;
|
||||
}
|
||||
settings->ss = settings->screens[settings->ssIndex];
|
||||
return HTOP_REFRESH;
|
||||
}
|
||||
|
||||
Htop_Reaction Action_setScreenTab(Settings* settings, int x) {
|
||||
int s = 2;
|
||||
for (unsigned int i = 0; i < settings->nScreens; i++) {
|
||||
if (x < s) {
|
||||
return 0;
|
||||
}
|
||||
const char* name = settings->screens[i]->name;
|
||||
int len = strlen(name);
|
||||
if (x <= s + len + 1) {
|
||||
settings->ssIndex = i;
|
||||
settings->ss = settings->screens[i];
|
||||
return HTOP_REFRESH;
|
||||
}
|
||||
s += len + 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Htop_Reaction actionQuit(ATTR_UNUSED State* st) {
|
||||
@ -714,4 +756,6 @@ void Action_setBindings(Htop_Action* keys) {
|
||||
keys[KEY_F(10)] = actionQuit;
|
||||
keys[KEY_F(18)] = actionExpandCollapseOrSortColumn;
|
||||
keys[KEY_RECLICK] = actionExpandOrCollapse;
|
||||
keys[KEY_SHIFT_TAB] = actionPrevScreen;
|
||||
keys['\t'] = actionNextScreen;
|
||||
}
|
||||
|
2
Action.h
2
Action.h
@ -57,6 +57,8 @@ bool Action_setUserOnly(const char* userName, uid_t* userId);
|
||||
|
||||
Htop_Reaction Action_setSortKey(Settings* settings, ProcessField sortKey);
|
||||
|
||||
Htop_Reaction Action_setScreenTab(Settings* settings, int x);
|
||||
|
||||
Htop_Reaction Action_follow(State* st);
|
||||
|
||||
void Action_setBindings(Htop_Action* keys);
|
||||
|
36
CRT.c
36
CRT.c
@ -193,6 +193,11 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[CPU_SOFTIRQ] = ColorPair(Magenta, Black),
|
||||
[CPU_STEAL] = ColorPair(Cyan, Black),
|
||||
[CPU_GUEST] = ColorPair(Cyan, Black),
|
||||
[PANEL_EDIT] = ColorPair(White, Blue),
|
||||
[SCREENS_OTH_BORDER] = ColorPair(Blue, Blue),
|
||||
[SCREENS_OTH_TEXT] = ColorPair(Black, Blue),
|
||||
[SCREENS_CUR_BORDER] = ColorPair(Green, Green),
|
||||
[SCREENS_CUR_TEXT] = ColorPair(Black, Green),
|
||||
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Cyan, Black),
|
||||
[PRESSURE_STALL_SIXTY] = A_BOLD | ColorPair(Cyan, Black),
|
||||
[PRESSURE_STALL_TEN] = A_BOLD | ColorPair(White, Black),
|
||||
@ -295,6 +300,11 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[CPU_SOFTIRQ] = A_BOLD,
|
||||
[CPU_STEAL] = A_DIM,
|
||||
[CPU_GUEST] = A_DIM,
|
||||
[PANEL_EDIT] = A_BOLD,
|
||||
[SCREENS_OTH_BORDER] = A_DIM,
|
||||
[SCREENS_OTH_TEXT] = A_DIM,
|
||||
[SCREENS_CUR_BORDER] = A_REVERSE,
|
||||
[SCREENS_CUR_TEXT] = A_REVERSE,
|
||||
[PRESSURE_STALL_THREEHUNDRED] = A_DIM,
|
||||
[PRESSURE_STALL_SIXTY] = A_NORMAL,
|
||||
[PRESSURE_STALL_TEN] = A_BOLD,
|
||||
@ -397,6 +407,11 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[CPU_SOFTIRQ] = ColorPair(Blue, White),
|
||||
[CPU_STEAL] = ColorPair(Cyan, White),
|
||||
[CPU_GUEST] = ColorPair(Cyan, White),
|
||||
[PANEL_EDIT] = ColorPair(White,Blue),
|
||||
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Black,White),
|
||||
[SCREENS_OTH_TEXT] = A_BOLD | ColorPair(Black,White),
|
||||
[SCREENS_CUR_BORDER] = ColorPair(Green,Green),
|
||||
[SCREENS_CUR_TEXT] = ColorPair(Black,Green),
|
||||
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Black, White),
|
||||
[PRESSURE_STALL_SIXTY] = ColorPair(Black, White),
|
||||
[PRESSURE_STALL_TEN] = ColorPair(Black, White),
|
||||
@ -499,6 +514,11 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[CPU_SOFTIRQ] = ColorPair(Blue, Black),
|
||||
[CPU_STEAL] = ColorPair(Black, Black),
|
||||
[CPU_GUEST] = ColorPair(Black, Black),
|
||||
[PANEL_EDIT] = ColorPair(White,Blue),
|
||||
[SCREENS_OTH_BORDER] = ColorPair(Blue,Black),
|
||||
[SCREENS_OTH_TEXT] = ColorPair(Blue,Black),
|
||||
[SCREENS_CUR_BORDER] = ColorPair(Green,Green),
|
||||
[SCREENS_CUR_TEXT] = ColorPair(Black,Green),
|
||||
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Black, Black),
|
||||
[PRESSURE_STALL_SIXTY] = ColorPair(Black, Black),
|
||||
[PRESSURE_STALL_TEN] = ColorPair(Black, Black),
|
||||
@ -601,6 +621,11 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[CPU_SOFTIRQ] = ColorPair(Black, Blue),
|
||||
[CPU_STEAL] = ColorPair(White, Blue),
|
||||
[CPU_GUEST] = ColorPair(White, Blue),
|
||||
[PANEL_EDIT] = ColorPair(White,Blue),
|
||||
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Yellow,Blue),
|
||||
[SCREENS_OTH_TEXT] = ColorPair(Cyan,Blue),
|
||||
[SCREENS_CUR_BORDER] = ColorPair(Cyan,Cyan),
|
||||
[SCREENS_CUR_TEXT] = ColorPair(Black,Cyan),
|
||||
[PRESSURE_STALL_THREEHUNDRED] = A_BOLD | ColorPair(Black, Blue),
|
||||
[PRESSURE_STALL_SIXTY] = A_NORMAL | ColorPair(White, Blue),
|
||||
[PRESSURE_STALL_TEN] = A_BOLD | ColorPair(White, Blue),
|
||||
@ -701,6 +726,11 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[CPU_SOFTIRQ] = ColorPair(Blue, Black),
|
||||
[CPU_STEAL] = ColorPair(Cyan, Black),
|
||||
[CPU_GUEST] = ColorPair(Cyan, Black),
|
||||
[PANEL_EDIT] = ColorPair(White,Cyan),
|
||||
[SCREENS_OTH_BORDER] = ColorPair(White,Black),
|
||||
[SCREENS_OTH_TEXT] = ColorPair(Cyan,Black),
|
||||
[SCREENS_CUR_BORDER] = A_BOLD | ColorPair(White,Black),
|
||||
[SCREENS_CUR_TEXT] = A_BOLD | ColorPair(Green,Black),
|
||||
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Green, Black),
|
||||
[PRESSURE_STALL_SIXTY] = ColorPair(Green, Black),
|
||||
[PRESSURE_STALL_TEN] = A_BOLD | ColorPair(Green, Black),
|
||||
@ -725,8 +755,6 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||
[COLORSCHEME_BROKENGRAY] = { 0 } // dynamically generated.
|
||||
};
|
||||
|
||||
int CRT_cursorX = 0;
|
||||
|
||||
int CRT_scrollHAmount = 5;
|
||||
|
||||
int CRT_scrollWheelVAmount = 10;
|
||||
@ -915,6 +943,7 @@ IGNORE_WCASTQUAL_BEGIN
|
||||
define_key("\033[14~", KEY_F(4));
|
||||
define_key("\033[14;2~", KEY_F(15));
|
||||
define_key("\033[17;2~", KEY_F(18));
|
||||
define_key("\033[Z", KEY_SHIFT_TAB);
|
||||
char sequence[3] = "\033a";
|
||||
for (char c = 'a'; c <= 'z'; c++) {
|
||||
sequence[1] = c;
|
||||
@ -925,6 +954,9 @@ IGNORE_WCASTQUAL_END
|
||||
#undef define_key
|
||||
#endif
|
||||
}
|
||||
if (termType && (String_startsWith(termType, "rxvt"))) {
|
||||
define_key("\033[Z", KEY_SHIFT_TAB);
|
||||
}
|
||||
|
||||
CRT_installSignalHandlers();
|
||||
|
||||
|
6
CRT.h
6
CRT.h
@ -120,6 +120,11 @@ typedef enum ColorElements_ {
|
||||
CPU_SOFTIRQ,
|
||||
CPU_STEAL,
|
||||
CPU_GUEST,
|
||||
PANEL_EDIT,
|
||||
SCREENS_OTH_BORDER,
|
||||
SCREENS_OTH_TEXT,
|
||||
SCREENS_CUR_BORDER,
|
||||
SCREENS_CUR_TEXT,
|
||||
PRESSURE_STALL_TEN,
|
||||
PRESSURE_STALL_SIXTY,
|
||||
PRESSURE_STALL_THREEHUNDRED,
|
||||
@ -150,6 +155,7 @@ void CRT_handleSIGSEGV(int signal) ATTR_NORETURN;
|
||||
#define KEY_WHEELUP KEY_F(30)
|
||||
#define KEY_WHEELDOWN KEY_F(31)
|
||||
#define KEY_RECLICK KEY_F(32)
|
||||
#define KEY_SHIFT_TAB KEY_F(33)
|
||||
#define KEY_ALT(x) (KEY_F(64 - 26) + ((x) - 'A'))
|
||||
|
||||
extern const char* CRT_degreeSign;
|
||||
|
@ -14,7 +14,6 @@ in the source distribution for its full text.
|
||||
#include "AvailableColumnsPanel.h"
|
||||
#include "AvailableMetersPanel.h"
|
||||
#include "ColorsPanel.h"
|
||||
#include "ColumnsPanel.h"
|
||||
#include "DisplayOptionsPanel.h"
|
||||
#include "FunctionBar.h"
|
||||
#include "Header.h"
|
||||
@ -25,6 +24,7 @@ in the source distribution for its full text.
|
||||
#include "MetersPanel.h"
|
||||
#include "Object.h"
|
||||
#include "ProvideCurses.h"
|
||||
#include "ScreensPanel.h"
|
||||
#include "Vector.h"
|
||||
#include "XUtils.h"
|
||||
|
||||
@ -69,9 +69,11 @@ static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
|
||||
ScreenManager_add(this->scr, colors, -1);
|
||||
}
|
||||
|
||||
static void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) {
|
||||
Panel* columns = (Panel*) ColumnsPanel_new(this->settings);
|
||||
static void CategoriesPanel_makeScreensPage(CategoriesPanel* this) {
|
||||
Panel* screens = (Panel*) ScreensPanel_new(this->settings);
|
||||
Panel* columns = (Panel*) ((ScreensPanel*)screens)->columns;
|
||||
Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(columns, this->settings->dynamicColumns);
|
||||
ScreenManager_add(this->scr, screens, 20);
|
||||
ScreenManager_add(this->scr, columns, 20);
|
||||
ScreenManager_add(this->scr, availableColumns, -1);
|
||||
}
|
||||
@ -91,7 +93,7 @@ static const CategoriesPanelPage categoriesPanelPages[] = {
|
||||
{ .name = "Display options", .ctor = CategoriesPanel_makeDisplayOptionsPage },
|
||||
{ .name = "Header layout", .ctor = CategoriesPanel_makeHeaderOptionsPage },
|
||||
{ .name = "Meters", .ctor = CategoriesPanel_makeMetersPage },
|
||||
{ .name = "Columns", .ctor = CategoriesPanel_makeColumnsPage },
|
||||
{ .name = "Screens", .ctor = CategoriesPanel_makeScreensPage },
|
||||
{ .name = "Colors", .ctor = CategoriesPanel_makeColorsPage },
|
||||
};
|
||||
|
||||
@ -157,7 +159,7 @@ CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Hea
|
||||
this->settings = settings;
|
||||
this->header = header;
|
||||
this->pl = pl;
|
||||
Panel_setHeader(super, "Setup");
|
||||
Panel_setHeader(super, "Categories");
|
||||
for (size_t i = 0; i < ARRAYSIZE(categoriesPanelPages); i++)
|
||||
Panel_add(super, (Object*) ListItem_new(categoriesPanelPages[i].name, 0));
|
||||
|
||||
|
@ -138,20 +138,26 @@ static void ColumnsPanel_add(Panel* super, unsigned int key, Hashtable* columns)
|
||||
Panel_add(super, (Object*) ListItem_new(name, key));
|
||||
}
|
||||
|
||||
ColumnsPanel* ColumnsPanel_new(Settings* settings) {
|
||||
void ColumnsPanel_fill(ColumnsPanel* this, ScreenSettings* ss, Hashtable* columns) {
|
||||
Panel* super = (Panel*) this;
|
||||
Panel_prune(super);
|
||||
for (const ProcessField* fields = ss->fields; *fields; fields++)
|
||||
ColumnsPanel_add(super, *fields, columns);
|
||||
this->ss = ss;
|
||||
}
|
||||
|
||||
ColumnsPanel* ColumnsPanel_new(ScreenSettings* ss, Hashtable* columns, bool* changed) {
|
||||
ColumnsPanel* this = AllocThis(ColumnsPanel);
|
||||
Panel* super = (Panel*) this;
|
||||
FunctionBar* fuBar = FunctionBar_new(ColumnsFunctions, NULL, NULL);
|
||||
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true, fuBar);
|
||||
|
||||
this->settings = settings;
|
||||
this->ss = ss;
|
||||
this->changed = changed;
|
||||
this->moving = false;
|
||||
Panel_setHeader(super, "Active Columns");
|
||||
|
||||
Hashtable* dynamicColumns = settings->dynamicColumns;
|
||||
const ProcessField* fields = settings->fields;
|
||||
for (; *fields; fields++)
|
||||
ColumnsPanel_add(super, *fields, dynamicColumns);
|
||||
ColumnsPanel_fill(this, ss, columns);
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -159,14 +165,14 @@ ColumnsPanel* ColumnsPanel_new(Settings* settings) {
|
||||
void ColumnsPanel_update(Panel* super) {
|
||||
ColumnsPanel* this = (ColumnsPanel*) super;
|
||||
int size = Panel_size(super);
|
||||
this->settings->changed = true;
|
||||
this->settings->fields = xRealloc(this->settings->fields, sizeof(ProcessField) * (size + 1));
|
||||
this->settings->flags = 0;
|
||||
*(this->changed) = true;
|
||||
this->ss->fields = xRealloc(this->ss->fields, sizeof(ProcessField) * (size + 1));
|
||||
this->ss->flags = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
int key = ((ListItem*) Panel_get(super, i))->key;
|
||||
this->settings->fields[i] = key;
|
||||
this->ss->fields[i] = key;
|
||||
if (key < LAST_PROCESSFIELD)
|
||||
this->settings->flags |= Process_fields[key].flags;
|
||||
this->ss->flags |= Process_fields[key].flags;
|
||||
}
|
||||
this->settings->fields[size] = 0;
|
||||
this->ss->fields[size] = 0;
|
||||
}
|
||||
|
@ -15,14 +15,17 @@ in the source distribution for its full text.
|
||||
|
||||
typedef struct ColumnsPanel_ {
|
||||
Panel super;
|
||||
ScreenSettings* ss;
|
||||
bool* changed;
|
||||
|
||||
Settings* settings;
|
||||
bool moving;
|
||||
} ColumnsPanel;
|
||||
|
||||
extern const PanelClass ColumnsPanel_class;
|
||||
|
||||
ColumnsPanel* ColumnsPanel_new(Settings* settings);
|
||||
ColumnsPanel* ColumnsPanel_new(ScreenSettings* ss, Hashtable* columns, bool* changed);
|
||||
|
||||
void ColumnsPanel_fill(ColumnsPanel* this, ScreenSettings* ss, Hashtable* columns);
|
||||
|
||||
void ColumnsPanel_update(Panel* super);
|
||||
|
||||
|
@ -328,7 +328,7 @@ int CommandLine_run(const char* name, int argc, char** argv) {
|
||||
settings->enableMouse = false;
|
||||
#endif
|
||||
if (flags.treeView)
|
||||
settings->treeView = true;
|
||||
settings->ss->treeView = true;
|
||||
if (flags.highlightChanges)
|
||||
settings->highlightChanges = true;
|
||||
if (flags.highlightDelaySecs != -1)
|
||||
@ -337,9 +337,9 @@ int CommandLine_run(const char* name, int argc, char** argv) {
|
||||
// -t -s <key> means "tree sorted by key"
|
||||
// -s <key> means "list sorted by key" (previous existing behavior)
|
||||
if (!flags.treeView) {
|
||||
settings->treeView = false;
|
||||
settings->ss->treeView = false;
|
||||
}
|
||||
Settings_setSortKey(settings, flags.sortKey);
|
||||
ScreenSettings_setSortKey(settings->ss, flags.sortKey);
|
||||
}
|
||||
|
||||
CRT_init(settings, flags.allowUnicode);
|
||||
@ -347,7 +347,7 @@ int CommandLine_run(const char* name, int argc, char** argv) {
|
||||
MainPanel* panel = MainPanel_new();
|
||||
ProcessList_setPanel(pl, (Panel*) panel);
|
||||
|
||||
MainPanel_updateTreeFunctions(panel, settings->treeView);
|
||||
MainPanel_updateTreeFunctions(panel, settings->ss->treeView);
|
||||
|
||||
State state = {
|
||||
.settings = settings,
|
||||
@ -370,10 +370,10 @@ int CommandLine_run(const char* name, int argc, char** argv) {
|
||||
CommandLine_delay(pl, 75);
|
||||
ProcessList_scan(pl, false);
|
||||
|
||||
if (settings->allBranchesCollapsed)
|
||||
if (settings->ss->allBranchesCollapsed)
|
||||
ProcessList_collapseAllBranches(pl);
|
||||
|
||||
ScreenManager_run(scr, NULL, NULL);
|
||||
ScreenManager_run(scr, NULL, NULL, NULL);
|
||||
|
||||
Platform_done();
|
||||
|
||||
|
@ -97,9 +97,10 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
|
||||
this->scr = scr;
|
||||
|
||||
Panel_setHeader(super, "Display options");
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("Tree view", &(settings->treeView)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("- Tree view is always sorted by PID (htop 2 behavior)", &(settings->treeViewAlwaysByPID)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("- Tree view is collapsed by default", &(settings->allBranchesCollapsed)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("Tree view", &(settings->ss->treeView)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("- Tree view is always sorted by PID (htop 2 behavior)", &(settings->ss->treeViewAlwaysByPID)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("- Tree view is collapsed by default", &(settings->ss->allBranchesCollapsed)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("Show tabs for screens", &(settings->screenTabs)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("Shadow other users' processes", &(settings->shadowOtherUsers)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("Hide kernel threads", &(settings->hideKernelThreads)));
|
||||
Panel_add(super, (Object*) CheckItem_newByRef("Hide userland process threads", &(settings->hideUserlandThreads)));
|
||||
|
@ -88,11 +88,12 @@ void FunctionBar_setLabel(FunctionBar* this, int event, const char* text) {
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionBar_draw(const FunctionBar* this) {
|
||||
FunctionBar_drawExtra(this, NULL, -1, false);
|
||||
int FunctionBar_draw(const FunctionBar* this) {
|
||||
return FunctionBar_drawExtra(this, NULL, -1, false);
|
||||
}
|
||||
|
||||
void FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr, bool setCursor) {
|
||||
int FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr, bool setCursor) {
|
||||
int cursorX = 0;
|
||||
attrset(CRT_colors[FUNCTION_BAR]);
|
||||
mvhline(LINES - 1, 0, ' ', COLS);
|
||||
int x = 0;
|
||||
@ -113,18 +114,20 @@ void FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr
|
||||
}
|
||||
mvaddstr(LINES - 1, x, buffer);
|
||||
x += strlen(buffer);
|
||||
cursorX = x;
|
||||
}
|
||||
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
|
||||
if (setCursor) {
|
||||
CRT_cursorX = x;
|
||||
curs_set(1);
|
||||
} else {
|
||||
curs_set(0);
|
||||
}
|
||||
|
||||
currentLen = x;
|
||||
|
||||
return cursorX;
|
||||
}
|
||||
|
||||
void FunctionBar_append(const char* buffer, int attr) {
|
||||
|
@ -29,9 +29,9 @@ void FunctionBar_delete(FunctionBar* this);
|
||||
|
||||
void FunctionBar_setLabel(FunctionBar* this, int event, const char* text);
|
||||
|
||||
void FunctionBar_draw(const FunctionBar* this);
|
||||
int FunctionBar_draw(const FunctionBar* this);
|
||||
|
||||
void FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr, bool setCursor);
|
||||
int FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr, bool setCursor);
|
||||
|
||||
void FunctionBar_append(const char* buffer, int attr);
|
||||
|
||||
|
3
Header.c
3
Header.c
@ -283,6 +283,9 @@ int Header_calculateHeight(Header* this) {
|
||||
}
|
||||
maxHeight = MAXIMUM(maxHeight, height);
|
||||
}
|
||||
if (this->settings->screenTabs) {
|
||||
maxHeight++;
|
||||
}
|
||||
this->height = maxHeight;
|
||||
this->pad = pad;
|
||||
return maxHeight;
|
||||
|
37
IncSet.c
37
IncSet.c
@ -105,10 +105,10 @@ static void updateWeakPanel(const IncSet* this, Panel* panel, Vector* lines) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool search(const IncMode* mode, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
||||
static bool search(const IncSet* this, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
||||
int size = Panel_size(panel);
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
||||
if (String_contains_i(getPanelValue(panel, i), this->active->buffer)) {
|
||||
Panel_setSelected(panel, i);
|
||||
return true;
|
||||
}
|
||||
@ -117,6 +117,21 @@ static bool search(const IncMode* mode, Panel* panel, IncMode_GetPanelValue getP
|
||||
return false;
|
||||
}
|
||||
|
||||
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
|
||||
this->active = &(this->modes[type]);
|
||||
panel->currentBar = this->active->bar;
|
||||
panel->cursorOn = true;
|
||||
this->panel = panel;
|
||||
IncSet_drawBar(this, CRT_colors[FUNCTION_BAR]);
|
||||
}
|
||||
|
||||
static void IncSet_deactivate(IncSet* this, Panel* panel) {
|
||||
this->active = NULL;
|
||||
Panel_setDefaultBar(panel);
|
||||
panel->cursorOn = false;
|
||||
FunctionBar_draw(this->defaultBar);
|
||||
}
|
||||
|
||||
static bool IncMode_find(const IncMode* mode, Panel* panel, IncMode_GetPanelValue getPanelValue, int step) {
|
||||
int size = Panel_size(panel);
|
||||
int here = Panel_getSelectedIndex(panel);
|
||||
@ -194,12 +209,11 @@ bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue
|
||||
IncMode_reset(mode);
|
||||
}
|
||||
}
|
||||
this->active = NULL;
|
||||
Panel_setDefaultBar(panel);
|
||||
IncSet_deactivate(this, panel);
|
||||
doSearch = false;
|
||||
}
|
||||
if (doSearch) {
|
||||
this->found = search(mode, panel, getPanelValue);
|
||||
this->found = search(this, panel, getPanelValue);
|
||||
}
|
||||
if (filterChanged && lines) {
|
||||
updateWeakPanel(this, panel, lines);
|
||||
@ -212,14 +226,13 @@ const char* IncSet_getListItemValue(Panel* panel, int i) {
|
||||
return l ? l->value : "";
|
||||
}
|
||||
|
||||
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
|
||||
this->active = &(this->modes[type]);
|
||||
panel->currentBar = this->active->bar;
|
||||
}
|
||||
|
||||
void IncSet_drawBar(const IncSet* this) {
|
||||
void IncSet_drawBar(const IncSet* this, int attr) {
|
||||
if (this->active) {
|
||||
FunctionBar_drawExtra(this->active->bar, this->active->buffer, (this->active->isFilter || this->found) ? -1 : CRT_colors[FAILED_SEARCH], true);
|
||||
if (!this->active->isFilter && !this->found)
|
||||
attr = CRT_colors[FAILED_SEARCH];
|
||||
int cursorX = FunctionBar_drawExtra(this->active->bar, this->active->buffer, attr, true);
|
||||
this->panel->cursorY = LINES - 1;
|
||||
this->panel->cursorX = cursorX;
|
||||
} else {
|
||||
FunctionBar_draw(this->defaultBar);
|
||||
}
|
||||
|
3
IncSet.h
3
IncSet.h
@ -32,6 +32,7 @@ typedef struct IncMode_ {
|
||||
typedef struct IncSet_ {
|
||||
IncMode modes[2];
|
||||
IncMode* active;
|
||||
Panel* panel;
|
||||
FunctionBar* defaultBar;
|
||||
bool filtering;
|
||||
bool found;
|
||||
@ -57,7 +58,7 @@ const char* IncSet_getListItemValue(Panel* panel, int i);
|
||||
|
||||
void IncSet_activate(IncSet* this, IncType type, Panel* panel);
|
||||
|
||||
void IncSet_drawBar(const IncSet* this);
|
||||
void IncSet_drawBar(const IncSet* this, int attr);
|
||||
|
||||
int IncSet_synthesizeEvent(IncSet* this, int x);
|
||||
|
||||
|
12
InfoScreen.c
12
InfoScreen.c
@ -57,7 +57,7 @@ void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
|
||||
attrset(CRT_colors[DEFAULT_COLOR]);
|
||||
Panel_draw(this->display, true, true, true, false);
|
||||
|
||||
IncSet_drawBar(this->inc);
|
||||
IncSet_drawBar(this->inc, CRT_colors[FUNCTION_BAR]);
|
||||
}
|
||||
|
||||
void InfoScreen_addLine(InfoScreen* this, const char* line) {
|
||||
@ -89,15 +89,9 @@ void InfoScreen_run(InfoScreen* this) {
|
||||
while (looping) {
|
||||
|
||||
Panel_draw(panel, false, true, true, false);
|
||||
IncSet_drawBar(this->inc);
|
||||
IncSet_drawBar(this->inc, CRT_colors[FUNCTION_BAR]);
|
||||
|
||||
if (this->inc->active) {
|
||||
(void) move(LINES - 1, CRT_cursorX);
|
||||
}
|
||||
#ifdef HAVE_SET_ESCDELAY
|
||||
set_escdelay(25);
|
||||
#endif
|
||||
int ch = getch();
|
||||
int ch = Panel_getCh(panel);
|
||||
|
||||
if (ch == ERR) {
|
||||
if (As_InfoScreen(this)->onErr) {
|
||||
|
14
ListItem.c
14
ListItem.c
@ -18,13 +18,13 @@ in the source distribution for its full text.
|
||||
#include "XUtils.h"
|
||||
|
||||
|
||||
static void ListItem_delete(Object* cast) {
|
||||
void ListItem_delete(Object* cast) {
|
||||
ListItem* this = (ListItem*)cast;
|
||||
free(this->value);
|
||||
free(this);
|
||||
}
|
||||
|
||||
static void ListItem_display(const Object* cast, RichString* out) {
|
||||
void ListItem_display(const Object* cast, RichString* out) {
|
||||
const ListItem* const this = (const ListItem*)cast;
|
||||
assert (this != NULL);
|
||||
|
||||
@ -38,11 +38,15 @@ static void ListItem_display(const Object* cast, RichString* out) {
|
||||
RichString_appendWide(out, CRT_colors[DEFAULT_COLOR], this->value);
|
||||
}
|
||||
|
||||
ListItem* ListItem_new(const char* value, int key) {
|
||||
ListItem* this = AllocThis(ListItem);
|
||||
void ListItem_init(ListItem* this, const char* value, int key) {
|
||||
this->value = xStrdup(value);
|
||||
this->key = key;
|
||||
this->moving = false;
|
||||
}
|
||||
|
||||
ListItem* ListItem_new(const char* value, int key) {
|
||||
ListItem* this = AllocThis(ListItem);
|
||||
ListItem_init(this, value, key);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -55,7 +59,7 @@ void ListItem_append(ListItem* this, const char* text) {
|
||||
this->value[newLen] = '\0';
|
||||
}
|
||||
|
||||
static int ListItem_compare(const void* cast1, const void* cast2) {
|
||||
int ListItem_compare(const void* cast1, const void* cast2) {
|
||||
const ListItem* obj1 = (const ListItem*) cast1;
|
||||
const ListItem* obj2 = (const ListItem*) cast2;
|
||||
return strcmp(obj1->value, obj2->value);
|
||||
|
@ -21,10 +21,18 @@ typedef struct ListItem_ {
|
||||
|
||||
extern const ObjectClass ListItem_class;
|
||||
|
||||
void ListItem_delete(Object* cast);
|
||||
|
||||
void ListItem_display(const Object* cast, RichString* out);
|
||||
|
||||
void ListItem_init(ListItem* this, const char* value, int key);
|
||||
|
||||
ListItem* ListItem_new(const char* value, int key);
|
||||
|
||||
void ListItem_append(ListItem* this, const char* text);
|
||||
|
||||
int ListItem_compare(const void* cast1, const void* cast2);
|
||||
|
||||
static inline const char* ListItem_getRef(const ListItem* this) {
|
||||
return this->value;
|
||||
}
|
||||
|
22
MainPanel.c
22
MainPanel.c
@ -71,23 +71,29 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
|
||||
if (needReset)
|
||||
this->state->hideProcessSelection = false;
|
||||
|
||||
Settings* settings = this->state->settings;
|
||||
ScreenSettings* ss = settings->ss;
|
||||
|
||||
if (EVENT_IS_HEADER_CLICK(ch)) {
|
||||
int x = EVENT_HEADER_CLICK_GET_X(ch);
|
||||
const ProcessList* pl = this->state->pl;
|
||||
Settings* settings = this->state->settings;
|
||||
int hx = super->scrollH + x + 1;
|
||||
ProcessField field = ProcessList_keyAt(pl, hx);
|
||||
if (settings->treeView && settings->treeViewAlwaysByPID) {
|
||||
settings->treeView = false;
|
||||
settings->direction = 1;
|
||||
if (ss->treeView && ss->treeViewAlwaysByPID) {
|
||||
ss->treeView = false;
|
||||
ss->direction = 1;
|
||||
reaction |= Action_setSortKey(settings, field);
|
||||
} else if (field == Settings_getActiveSortKey(settings)) {
|
||||
Settings_invertSortOrder(settings);
|
||||
} else if (field == ScreenSettings_getActiveSortKey(ss)) {
|
||||
ScreenSettings_invertSortOrder(ss);
|
||||
} else {
|
||||
reaction |= Action_setSortKey(settings, field);
|
||||
}
|
||||
reaction |= HTOP_RECALCULATE | HTOP_REDRAW_BAR | HTOP_SAVE_SETTINGS;
|
||||
result = HANDLED;
|
||||
} else if (EVENT_IS_SCREEN_TAB_CLICK(ch)) {
|
||||
int x = EVENT_SCREEN_TAB_GET_X(ch);
|
||||
reaction |= Action_setScreenTab(settings, x);
|
||||
result = HANDLED;
|
||||
} else if (ch != ERR && this->inc->active) {
|
||||
bool filterChanged = IncSet_handleKey(this->inc, ch, super, MainPanel_getValue, NULL);
|
||||
if (filterChanged) {
|
||||
@ -116,7 +122,7 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
|
||||
}
|
||||
|
||||
if (reaction & HTOP_REDRAW_BAR) {
|
||||
MainPanel_updateTreeFunctions(this, this->state->settings->treeView);
|
||||
MainPanel_updateTreeFunctions(this, settings->ss->treeView);
|
||||
}
|
||||
if (reaction & HTOP_RESIZE) {
|
||||
result |= RESIZE;
|
||||
@ -182,7 +188,7 @@ static void MainPanel_drawFunctionBar(Panel* super, bool hideFunctionBar) {
|
||||
if (hideFunctionBar && !this->inc->active)
|
||||
return;
|
||||
|
||||
IncSet_drawBar(this->inc);
|
||||
IncSet_drawBar(this->inc, CRT_colors[FUNCTION_BAR]);
|
||||
if (this->state->pauseProcessUpdate) {
|
||||
FunctionBar_append("PAUSED", CRT_colors[PAUSED]);
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ myhtopsources = \
|
||||
ProcessLocksScreen.c \
|
||||
RichString.c \
|
||||
ScreenManager.c \
|
||||
ScreensPanel.c \
|
||||
Settings.c \
|
||||
SignalsPanel.c \
|
||||
SwapMeter.c \
|
||||
@ -135,6 +136,7 @@ myhtopheaders = \
|
||||
ProvideCurses.h \
|
||||
RichString.h \
|
||||
ScreenManager.h \
|
||||
ScreensPanel.h \
|
||||
Settings.h \
|
||||
SignalsPanel.h \
|
||||
SwapMeter.h \
|
||||
|
21
Panel.c
21
Panel.c
@ -49,6 +49,8 @@ void Panel_init(Panel* this, int x, int y, int w, int h, const ObjectClass* type
|
||||
this->y = y;
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
this->cursorX = 0;
|
||||
this->cursorY = 0;
|
||||
this->eventHandlerState = NULL;
|
||||
this->items = Vector_new(type, owner, DEFAULT_SIZE);
|
||||
this->scrollV = 0;
|
||||
@ -72,6 +74,11 @@ void Panel_done(Panel* this) {
|
||||
RichString_delete(&this->header);
|
||||
}
|
||||
|
||||
void Panel_setCursorToSelection(Panel* this) {
|
||||
this->cursorY = this->y + this->selected - this->scrollV + 1;
|
||||
this->cursorX = this->x + this->selectedLen - this->scrollH;
|
||||
}
|
||||
|
||||
void Panel_setSelectionColor(Panel* this, ColorElements colorId) {
|
||||
this->selectionColorId = colorId;
|
||||
}
|
||||
@ -330,7 +337,6 @@ void Panel_draw(Panel* this, bool force_redraw, bool focus, bool highlightSelect
|
||||
this->oldSelected = this->selected;
|
||||
this->wasFocus = focus;
|
||||
this->needsRedraw = false;
|
||||
move(0, 0);
|
||||
}
|
||||
|
||||
static int Panel_headerHeight(const Panel* this) {
|
||||
@ -485,3 +491,16 @@ HandlerResult Panel_selectByTyping(Panel* this, int ch) {
|
||||
|
||||
return IGNORED;
|
||||
}
|
||||
|
||||
int Panel_getCh(Panel* this) {
|
||||
if (this->cursorOn) {
|
||||
move(this->cursorY, this->cursorX);
|
||||
curs_set(1);
|
||||
} else {
|
||||
curs_set(0);
|
||||
}
|
||||
#ifdef HAVE_SET_ESCDELAY
|
||||
set_escdelay(25);
|
||||
#endif
|
||||
return getch();
|
||||
}
|
||||
|
10
Panel.h
10
Panel.h
@ -39,6 +39,10 @@ typedef enum HandlerResult_ {
|
||||
#define EVENT_IS_HEADER_CLICK(ev_) ((ev_) >= -10000 && (ev_) <= -9000)
|
||||
#define EVENT_HEADER_CLICK_GET_X(ev_) ((ev_) + 10000)
|
||||
|
||||
#define EVENT_SCREEN_TAB_CLICK(x_) (-20000 + (x_))
|
||||
#define EVENT_IS_SCREEN_TAB_CLICK(ev_) ((ev_) >= -20000 && (ev_) < -10000)
|
||||
#define EVENT_SCREEN_TAB_GET_X(ev_) ((ev_) + 20000)
|
||||
|
||||
typedef HandlerResult (*Panel_EventHandler)(Panel*, int);
|
||||
typedef void (*Panel_DrawFunctionBar)(Panel*, bool);
|
||||
typedef void (*Panel_PrintHeader)(Panel*);
|
||||
@ -61,6 +65,7 @@ typedef struct PanelClass_ {
|
||||
struct Panel_ {
|
||||
Object super;
|
||||
int x, y, w, h;
|
||||
int cursorX, cursorY;
|
||||
Vector* items;
|
||||
int selected;
|
||||
int oldSelected;
|
||||
@ -69,6 +74,7 @@ struct Panel_ {
|
||||
int scrollV;
|
||||
int scrollH;
|
||||
bool needsRedraw;
|
||||
bool cursorOn;
|
||||
bool wasFocus;
|
||||
FunctionBar* currentBar;
|
||||
FunctionBar* defaultBar;
|
||||
@ -90,6 +96,8 @@ void Panel_init(Panel* this, int x, int y, int w, int h, const ObjectClass* type
|
||||
|
||||
void Panel_done(Panel* this);
|
||||
|
||||
void Panel_setCursorToSelection(Panel* this);
|
||||
|
||||
void Panel_setSelectionColor(Panel* this, ColorElements colorId);
|
||||
|
||||
void Panel_setHeader(Panel* this, const char* header);
|
||||
@ -130,4 +138,6 @@ bool Panel_onKey(Panel* this, int key);
|
||||
|
||||
HandlerResult Panel_selectByTyping(Panel* this, int ch);
|
||||
|
||||
int Panel_getCh(Panel* this);
|
||||
|
||||
#endif
|
||||
|
10
Process.c
10
Process.c
@ -784,7 +784,8 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
|
||||
attr = CRT_colors[PROCESS_THREAD];
|
||||
baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
|
||||
}
|
||||
if (!this->settings->treeView || this->indent == 0) {
|
||||
const ScreenSettings* ss = this->settings->ss;
|
||||
if (!ss->treeView || this->indent == 0) {
|
||||
Process_writeCommand(this, attr, baseattr, str);
|
||||
return;
|
||||
}
|
||||
@ -974,7 +975,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
|
||||
|
||||
void Process_display(const Object* cast, RichString* out) {
|
||||
const Process* this = (const Process*) cast;
|
||||
const ProcessField* fields = this->settings->fields;
|
||||
const ProcessField* fields = this->settings->ss->fields;
|
||||
for (int i = 0; fields[i]; i++)
|
||||
As_Process(this)->writeField(this, out, fields[i]);
|
||||
|
||||
@ -1092,8 +1093,9 @@ int Process_compare(const void* v1, const void* v2) {
|
||||
const Process* p2 = (const Process*)v2;
|
||||
|
||||
const Settings* settings = p1->settings;
|
||||
const ScreenSettings* ss = settings->ss;
|
||||
|
||||
ProcessField key = Settings_getActiveSortKey(settings);
|
||||
ProcessField key = ScreenSettings_getActiveSortKey(ss);
|
||||
|
||||
int result = Process_compareByKey(p1, p2, key);
|
||||
|
||||
@ -1101,7 +1103,7 @@ int Process_compare(const void* v1, const void* v2) {
|
||||
if (!result)
|
||||
return SPACESHIP_NUMBER(p1->pid, p2->pid);
|
||||
|
||||
return (Settings_getActiveDirection(settings) == 1) ? result : -result;
|
||||
return (ScreenSettings_getActiveDirection(ss) == 1) ? result : -result;
|
||||
}
|
||||
|
||||
int Process_compareByKey_Base(const Process* p1, const Process* p2, ProcessField key) {
|
||||
|
@ -124,13 +124,14 @@ void ProcessList_printHeader(const ProcessList* this, RichString* header) {
|
||||
RichString_rewind(header, RichString_size(header));
|
||||
|
||||
const Settings* settings = this->settings;
|
||||
const ProcessField* fields = settings->fields;
|
||||
const ScreenSettings* ss = settings->ss;
|
||||
const ProcessField* fields = ss->fields;
|
||||
|
||||
ProcessField key = Settings_getActiveSortKey(settings);
|
||||
ProcessField key = ScreenSettings_getActiveSortKey(ss);
|
||||
|
||||
for (int i = 0; fields[i]; i++) {
|
||||
int color;
|
||||
if (settings->treeView && settings->treeViewAlwaysByPID) {
|
||||
if (ss->treeView && ss->treeViewAlwaysByPID) {
|
||||
color = CRT_colors[PANEL_HEADER_FOCUS];
|
||||
} else if (key == fields[i]) {
|
||||
color = CRT_colors[PANEL_SELECTION_FOCUS];
|
||||
@ -140,10 +141,11 @@ void ProcessList_printHeader(const ProcessList* this, RichString* header) {
|
||||
|
||||
RichString_appendWide(header, color, alignedProcessFieldTitle(this, fields[i]));
|
||||
if (key == fields[i] && RichString_getCharVal(*header, RichString_size(header) - 1) == ' ') {
|
||||
bool ascending = ScreenSettings_getActiveDirection(ss) == 1;
|
||||
RichString_rewind(header, 1); // rewind to override space
|
||||
RichString_appendnWide(header,
|
||||
CRT_colors[PANEL_SELECTION_FOCUS],
|
||||
CRT_treeStr[Settings_getActiveDirection(this->settings) == 1 ? TREE_STR_ASC : TREE_STR_DESC],
|
||||
CRT_treeStr[ascending ? TREE_STR_ASC : TREE_STR_DESC],
|
||||
1);
|
||||
}
|
||||
if (COMM == fields[i] && settings->showMergedCommand) {
|
||||
@ -402,7 +404,7 @@ static int ProcessList_treeProcessCompareByPID(const void* v1, const void* v2) {
|
||||
static void ProcessList_buildTree(ProcessList* this) {
|
||||
int node_counter = 1;
|
||||
int node_index = 0;
|
||||
int direction = Settings_getActiveDirection(this->settings);
|
||||
int direction = ScreenSettings_getActiveDirection(this->settings->ss);
|
||||
|
||||
// Sort by PID
|
||||
Vector_quickSortCustomCompare(this->processes, ProcessList_treeProcessCompareByPID);
|
||||
@ -488,7 +490,7 @@ static void ProcessList_buildTree(ProcessList* this) {
|
||||
}
|
||||
|
||||
void ProcessList_sort(ProcessList* this) {
|
||||
if (this->settings->treeView) {
|
||||
if (this->settings->ss->treeView) {
|
||||
ProcessList_updateTreeSet(this);
|
||||
Vector_quickSortCustomCompare(this->processes, ProcessList_treeProcessCompare);
|
||||
} else {
|
||||
@ -498,7 +500,7 @@ void ProcessList_sort(ProcessList* this) {
|
||||
|
||||
ProcessField ProcessList_keyAt(const ProcessList* this, int at) {
|
||||
int x = 0;
|
||||
const ProcessField* fields = this->settings->fields;
|
||||
const ProcessField* fields = this->settings->ss->fields;
|
||||
ProcessField field;
|
||||
for (int i = 0; (field = fields[i]); i++) {
|
||||
int len = strlen(alignedProcessFieldTitle(this, field));
|
||||
@ -661,7 +663,7 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
|
||||
// Set UID column width based on max UID.
|
||||
Process_setUidColumnWidth(maxUid);
|
||||
|
||||
if (this->settings->treeView) {
|
||||
if (this->settings->ss->treeView) {
|
||||
// Clear out the hashtable to avoid any left-over processes from previous build
|
||||
//
|
||||
// The sorting algorithm relies on the fact that
|
||||
|
@ -49,27 +49,43 @@ inline int ScreenManager_size(const ScreenManager* this) {
|
||||
}
|
||||
|
||||
void ScreenManager_add(ScreenManager* this, Panel* item, int size) {
|
||||
ScreenManager_insert(this, item, size, Vector_size(this->panels));
|
||||
}
|
||||
|
||||
void ScreenManager_insert(ScreenManager* this, Panel* item, int size, int idx) {
|
||||
int lastX = 0;
|
||||
if (this->panelCount > 0) {
|
||||
const Panel* last = (const Panel*) Vector_get(this->panels, this->panelCount - 1);
|
||||
if (idx > 0) {
|
||||
const Panel* last = (const Panel*) Vector_get(this->panels, idx - 1);
|
||||
lastX = last->x + last->w + 1;
|
||||
}
|
||||
int height = LINES - this->y1 - (this->header ? this->header->height : 0) + this->y2;
|
||||
if (size > 0) {
|
||||
Panel_resize(item, size, height);
|
||||
} else {
|
||||
Panel_resize(item, COLS - this->x1 + this->x2 - lastX, height);
|
||||
if (size <= 0) {
|
||||
size = COLS - this->x1 + this->x2 - lastX;
|
||||
}
|
||||
Panel_resize(item, size, height);
|
||||
Panel_move(item, lastX, this->y1 + (this->header ? this->header->height : 0));
|
||||
Vector_add(this->panels, item);
|
||||
if (idx < this->panelCount) {
|
||||
for (int i = idx + 1; i <= this->panelCount; i++) {
|
||||
Panel* p = (Panel*) Vector_get(this->panels, i);
|
||||
Panel_move(p, p->x + size, p->y);
|
||||
}
|
||||
}
|
||||
Vector_insert(this->panels, idx, item);
|
||||
item->needsRedraw = true;
|
||||
this->panelCount++;
|
||||
}
|
||||
|
||||
Panel* ScreenManager_remove(ScreenManager* this, int idx) {
|
||||
assert(this->panelCount > idx);
|
||||
int w = ((Panel*) Vector_get(this->panels, idx))->w;
|
||||
Panel* panel = (Panel*) Vector_remove(this->panels, idx);
|
||||
this->panelCount--;
|
||||
if (idx < this->panelCount) {
|
||||
for (int i = idx; i < this->panelCount; i++) {
|
||||
Panel* p = (Panel*) Vector_get(this->panels, i);
|
||||
Panel_move(p, p->x - w, p->y);
|
||||
}
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
@ -108,7 +124,7 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
|
||||
ProcessList_scan(pl, this->state->pauseProcessUpdate);
|
||||
// always update header, especially to avoid gaps in graph meters
|
||||
Header_updateData(this->header);
|
||||
if (!this->state->pauseProcessUpdate && (*sortTimeout == 0 || this->settings->treeView)) {
|
||||
if (!this->state->pauseProcessUpdate && (*sortTimeout == 0 || this->settings->ss->treeView)) {
|
||||
ProcessList_sort(pl);
|
||||
*sortTimeout = 1;
|
||||
}
|
||||
@ -125,7 +141,53 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
|
||||
*rescan = false;
|
||||
}
|
||||
|
||||
static inline bool drawTab(int* y, int* x, int l, const char* name, bool cur) {
|
||||
attrset(CRT_colors[cur ? SCREENS_CUR_BORDER : SCREENS_OTH_BORDER]);
|
||||
mvaddch(*y, *x, '[');
|
||||
(*x)++;
|
||||
if (*x >= l)
|
||||
return false;
|
||||
int nameLen = strlen(name);
|
||||
int n = MINIMUM(l - *x, nameLen);
|
||||
attrset(CRT_colors[cur ? SCREENS_CUR_TEXT : SCREENS_OTH_TEXT]);
|
||||
mvaddnstr(*y, *x, name, n);
|
||||
*x += n;
|
||||
if (*x >= l)
|
||||
return false;
|
||||
attrset(CRT_colors[cur ? SCREENS_CUR_BORDER : SCREENS_OTH_BORDER]);
|
||||
mvaddch(*y, *x, ']');
|
||||
*x += 2;
|
||||
if (*x >= l)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ScreenManager_drawScreenTabs(ScreenManager* this) {
|
||||
ScreenSettings** screens = this->settings->screens;
|
||||
int cur = this->settings->ssIndex;
|
||||
int l = COLS;
|
||||
Panel* panel = (Panel*) Vector_get(this->panels, 0);
|
||||
int y = panel->y - 1;
|
||||
int x = 2;
|
||||
|
||||
if (this->name) {
|
||||
drawTab(&y, &x, l, this->name, true);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int s = 0; screens[s]; s++) {
|
||||
bool ok = drawTab(&y, &x, l, screens[s]->name, s == cur);
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
}
|
||||
|
||||
static void ScreenManager_drawPanels(ScreenManager* this, int focus, bool force_redraw) {
|
||||
if (this->settings->screenTabs) {
|
||||
ScreenManager_drawScreenTabs(this);
|
||||
}
|
||||
const int nPanels = this->panelCount;
|
||||
for (int i = 0; i < nPanels; i++) {
|
||||
Panel* panel = (Panel*) Vector_get(this->panels, i);
|
||||
@ -138,7 +200,7 @@ static void ScreenManager_drawPanels(ScreenManager* this, int focus, bool force_
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, const char* name) {
|
||||
bool quit = false;
|
||||
int focus = 0;
|
||||
|
||||
@ -156,6 +218,8 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
int sortTimeout = 0;
|
||||
int resetSortTimeout = 5;
|
||||
|
||||
this->name = name;
|
||||
|
||||
while (!quit) {
|
||||
if (this->header) {
|
||||
checkRecalculation(this, &oldTime, &sortTimeout, &redraw, &rescan, &timedOut, &force_redraw);
|
||||
@ -167,10 +231,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
}
|
||||
|
||||
int prevCh = ch;
|
||||
#ifdef HAVE_SET_ESCDELAY
|
||||
set_escdelay(25);
|
||||
#endif
|
||||
ch = getch();
|
||||
ch = Panel_getCh(panelFocus);
|
||||
|
||||
HandlerResult result = IGNORED;
|
||||
#ifdef HAVE_GETMOUSE
|
||||
@ -189,6 +250,9 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
if (mevent.y == panel->y) {
|
||||
ch = EVENT_HEADER_CLICK(mevent.x - panel->x);
|
||||
break;
|
||||
} else if (this->settings->screenTabs && mevent.y == panel->y - 1) {
|
||||
ch = EVENT_SCREEN_TAB_CLICK(mevent.x);
|
||||
break;
|
||||
} else if (mevent.y > panel->y && mevent.y <= panel->y + panel->h) {
|
||||
ch = KEY_MOUSE;
|
||||
if (panel == panelFocus || this->allowFocusChange) {
|
||||
|
@ -22,6 +22,7 @@ typedef struct ScreenManager_ {
|
||||
int x2;
|
||||
int y2;
|
||||
Vector* panels;
|
||||
const char* name;
|
||||
int panelCount;
|
||||
Header* header;
|
||||
const Settings* settings;
|
||||
@ -37,10 +38,12 @@ int ScreenManager_size(const ScreenManager* this);
|
||||
|
||||
void ScreenManager_add(ScreenManager* this, Panel* item, int size);
|
||||
|
||||
void ScreenManager_insert(ScreenManager* this, Panel* item, int size, int idx);
|
||||
|
||||
Panel* ScreenManager_remove(ScreenManager* this, int idx);
|
||||
|
||||
void ScreenManager_resize(ScreenManager* this);
|
||||
|
||||
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey);
|
||||
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, const char* name);
|
||||
|
||||
#endif
|
||||
|
308
ScreensPanel.c
Normal file
308
ScreensPanel.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
htop - ScreensPanel.c
|
||||
(C) 2004-2011 Hisham H. Muhammad
|
||||
Released under the GNU GPL, see the COPYING file
|
||||
in the source distribution for its full text.
|
||||
*/
|
||||
|
||||
#include "ScreensPanel.h"
|
||||
#include "Platform.h"
|
||||
|
||||
#include "CRT.h"
|
||||
#include "XUtils.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
ObjectClass ScreenListItem_class = {
|
||||
.extends = Class(ListItem),
|
||||
.display = ListItem_display,
|
||||
.delete = ListItem_delete,
|
||||
.compare = ListItem_compare
|
||||
};
|
||||
|
||||
ScreenListItem* ScreenListItem_new(const char* value, ScreenSettings* ss) {
|
||||
ScreenListItem* this = AllocThis(ScreenListItem);
|
||||
ListItem_init((ListItem*)this, value, 0);
|
||||
this->ss = ss;
|
||||
return this;
|
||||
}
|
||||
|
||||
static const char* const ScreensFunctions[] = {" ", "Rename", " ", " ", "New ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL};
|
||||
|
||||
static void ScreensPanel_delete(Object* object) {
|
||||
Panel* super = (Panel*) object;
|
||||
ScreensPanel* this = (ScreensPanel*) object;
|
||||
Panel_done(super);
|
||||
free(this);
|
||||
}
|
||||
|
||||
static HandlerResult ScreensPanel_eventHandlerRenaming(Panel* super, int ch) {
|
||||
ScreensPanel* const this = (ScreensPanel*) super;
|
||||
|
||||
if (ch >= 32 && ch < 127 && ch != 61) {
|
||||
if (this->cursor < SCREEN_NAME_LEN - 1) {
|
||||
this->buffer[this->cursor] = ch;
|
||||
this->cursor++;
|
||||
super->selectedLen = strlen(this->buffer);
|
||||
Panel_setCursorToSelection(super);
|
||||
}
|
||||
} else {
|
||||
switch(ch) {
|
||||
case 127:
|
||||
case KEY_BACKSPACE:
|
||||
{
|
||||
if (this->cursor > 0) {
|
||||
this->cursor--;
|
||||
this->buffer[this->cursor] = '\0';
|
||||
super->selectedLen = strlen(this->buffer);
|
||||
Panel_setCursorToSelection(super);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x0a:
|
||||
case 0x0d:
|
||||
case KEY_ENTER:
|
||||
{
|
||||
ListItem* item = (ListItem*) Panel_getSelected(super);
|
||||
if (!item)
|
||||
break;
|
||||
free(this->saved);
|
||||
item->value = xStrdup(this->buffer);
|
||||
this->renaming = false;
|
||||
super->cursorOn = false;
|
||||
Panel_setSelectionColor(super, CRT_colors[PANEL_SELECTION_FOCUS]);
|
||||
ScreensPanel_update(super);
|
||||
break;
|
||||
}
|
||||
case 27: // Esc
|
||||
{
|
||||
ListItem* item = (ListItem*) Panel_getSelected(super);
|
||||
if (!item)
|
||||
break;
|
||||
item->value = this->saved;
|
||||
this->renaming = false;
|
||||
super->cursorOn = false;
|
||||
Panel_setSelectionColor(super, CRT_colors[PANEL_SELECTION_FOCUS]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HANDLED;
|
||||
}
|
||||
|
||||
static void startRenaming(Panel* super) {
|
||||
ScreensPanel* const this = (ScreensPanel*) super;
|
||||
|
||||
ListItem* item = (ListItem*) Panel_getSelected(super);
|
||||
if (item == NULL)
|
||||
return;
|
||||
this->renaming = true;
|
||||
super->cursorOn = true;
|
||||
char* name = item->value;
|
||||
this->saved = name;
|
||||
strncpy(this->buffer, name, SCREEN_NAME_LEN);
|
||||
this->buffer[SCREEN_NAME_LEN] = '\0';
|
||||
this->cursor = strlen(this->buffer);
|
||||
item->value = this->buffer;
|
||||
Panel_setSelectionColor(super, CRT_colors[PANEL_EDIT]);
|
||||
super->selectedLen = strlen(this->buffer);
|
||||
Panel_setCursorToSelection(super);
|
||||
}
|
||||
|
||||
static void rebuildSettingsArray(Panel* super) {
|
||||
ScreensPanel* const this = (ScreensPanel*) super;
|
||||
|
||||
int n = Panel_size(super);
|
||||
free(this->settings->screens);
|
||||
this->settings->screens = xMalloc(sizeof(ScreenSettings*) * (n + 1));
|
||||
this->settings->screens[n] = NULL;
|
||||
for (int i = 0; i < n; i++) {
|
||||
ScreenListItem* item = (ScreenListItem*) Panel_get(super, i);
|
||||
this->settings->screens[i] = item->ss;
|
||||
}
|
||||
this->settings->nScreens = n;
|
||||
}
|
||||
|
||||
static void addNewScreen(Panel* super) {
|
||||
ScreensPanel* const this = (ScreensPanel*) super;
|
||||
|
||||
const char* name = "New";
|
||||
ScreenSettings* ss = Settings_newScreen(this->settings, name, "PID Command");
|
||||
ScreenListItem* item = ScreenListItem_new(name, ss);
|
||||
int idx = Panel_getSelectedIndex(super);
|
||||
Panel_insert(super, idx + 1, (Object*) item);
|
||||
Panel_setSelected(super, idx + 1);
|
||||
}
|
||||
|
||||
static HandlerResult ScreensPanel_eventHandlerNormal(Panel* super, int ch) {
|
||||
ScreensPanel* const this = (ScreensPanel*) super;
|
||||
|
||||
int selected = Panel_getSelectedIndex(super);
|
||||
ScreenListItem* oldFocus = (ScreenListItem*) Panel_getSelected(super);
|
||||
bool shouldRebuildArray = false;
|
||||
HandlerResult result = IGNORED;
|
||||
switch(ch) {
|
||||
case 0x0a:
|
||||
case 0x0d:
|
||||
case KEY_ENTER:
|
||||
case KEY_MOUSE:
|
||||
case KEY_RECLICK:
|
||||
{
|
||||
this->moving = !(this->moving);
|
||||
Panel_setSelectionColor(super, this->moving ? CRT_colors[PANEL_SELECTION_FOLLOW] : CRT_colors[PANEL_SELECTION_FOCUS]);
|
||||
ListItem* item = (ListItem*) Panel_getSelected(super);
|
||||
if (item)
|
||||
item->moving = this->moving;
|
||||
result = HANDLED;
|
||||
break;
|
||||
}
|
||||
case EVENT_SET_SELECTED:
|
||||
result = HANDLED;
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
case KEY_PPAGE:
|
||||
case KEY_HOME:
|
||||
case KEY_END: {
|
||||
Panel_onKey(super, ch);
|
||||
break;
|
||||
}
|
||||
case KEY_F(2):
|
||||
case KEY_CTRL('R'):
|
||||
{
|
||||
startRenaming(super);
|
||||
result = HANDLED;
|
||||
break;
|
||||
}
|
||||
case KEY_F(5):
|
||||
case KEY_CTRL('N'):
|
||||
{
|
||||
addNewScreen(super);
|
||||
startRenaming(super);
|
||||
shouldRebuildArray = true;
|
||||
result = HANDLED;
|
||||
break;
|
||||
}
|
||||
case KEY_UP:
|
||||
{
|
||||
if (!this->moving) {
|
||||
Panel_onKey(super, ch);
|
||||
break;
|
||||
}
|
||||
/* else fallthrough */
|
||||
} /* FALLTHRU */
|
||||
case KEY_F(7):
|
||||
case '[':
|
||||
case '-':
|
||||
{
|
||||
Panel_moveSelectedUp(super);
|
||||
shouldRebuildArray = true;
|
||||
result = HANDLED;
|
||||
break;
|
||||
}
|
||||
case KEY_DOWN:
|
||||
{
|
||||
if (!this->moving) {
|
||||
Panel_onKey(super, ch);
|
||||
break;
|
||||
}
|
||||
/* else fallthrough */
|
||||
} /* FALLTHRU */
|
||||
case KEY_F(8):
|
||||
case ']':
|
||||
case '+':
|
||||
{
|
||||
Panel_moveSelectedDown(super);
|
||||
shouldRebuildArray = true;
|
||||
result = HANDLED;
|
||||
break;
|
||||
}
|
||||
case KEY_F(9):
|
||||
//case KEY_DC:
|
||||
{
|
||||
if (Panel_size(super) > 1) {
|
||||
Panel_remove(super, selected);
|
||||
}
|
||||
shouldRebuildArray = true;
|
||||
result = HANDLED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (ch < 255 && isalpha(ch))
|
||||
result = Panel_selectByTyping(super, ch);
|
||||
if (result == BREAK_LOOP)
|
||||
result = IGNORED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ScreenListItem* newFocus = (ScreenListItem*) Panel_getSelected(super);
|
||||
if (newFocus && oldFocus != newFocus) {
|
||||
ColumnsPanel_fill(this->columns, newFocus->ss, this->settings->dynamicColumns);
|
||||
result = HANDLED;
|
||||
}
|
||||
if (shouldRebuildArray)
|
||||
rebuildSettingsArray(super);
|
||||
if (result == HANDLED)
|
||||
ScreensPanel_update(super);
|
||||
return result;
|
||||
}
|
||||
|
||||
static HandlerResult ScreensPanel_eventHandler(Panel* super, int ch) {
|
||||
ScreensPanel* const this = (ScreensPanel*) super;
|
||||
|
||||
if (this->renaming) {
|
||||
return ScreensPanel_eventHandlerRenaming(super, ch);
|
||||
} else {
|
||||
return ScreensPanel_eventHandlerNormal(super, ch);
|
||||
}
|
||||
}
|
||||
|
||||
PanelClass ScreensPanel_class = {
|
||||
.super = {
|
||||
.extends = Class(Panel),
|
||||
.delete = ScreensPanel_delete
|
||||
},
|
||||
.eventHandler = ScreensPanel_eventHandler
|
||||
};
|
||||
|
||||
ScreensPanel* ScreensPanel_new(Settings* settings) {
|
||||
ScreensPanel* this = AllocThis(ScreensPanel);
|
||||
Panel* super = (Panel*) this;
|
||||
Hashtable* columns = settings->dynamicColumns;
|
||||
FunctionBar* fuBar = FunctionBar_new(ScreensFunctions, NULL, NULL);
|
||||
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true, fuBar);
|
||||
|
||||
this->settings = settings;
|
||||
this->columns = ColumnsPanel_new(settings->screens[0], columns, &(settings->changed));
|
||||
this->moving = false;
|
||||
this->renaming = false;
|
||||
super->cursorOn = false;
|
||||
this->cursor = 0;
|
||||
Panel_setHeader(super, "Screens");
|
||||
|
||||
for (unsigned int i = 0; i < settings->nScreens; i++) {
|
||||
ScreenSettings* ss = settings->screens[i];
|
||||
char* name = ss->name;
|
||||
Panel_add(super, (Object*) ScreenListItem_new(name, ss));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void ScreensPanel_update(Panel* super) {
|
||||
ScreensPanel* this = (ScreensPanel*) super;
|
||||
int size = Panel_size(super);
|
||||
this->settings->changed = true;
|
||||
this->settings->screens = xRealloc(this->settings->screens, sizeof(char*) * (size+1));
|
||||
for (int i = 0; i < size; i++) {
|
||||
ScreenListItem* item = (ScreenListItem*) Panel_get(super, i);
|
||||
ScreenSettings* ss = item->ss;
|
||||
free(ss->name);
|
||||
this->settings->screens[i] = ss;
|
||||
ss->name = xStrdup(((ListItem*) item)->value);
|
||||
}
|
||||
this->settings->screens[size] = NULL;
|
||||
}
|
49
ScreensPanel.h
Normal file
49
ScreensPanel.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef HEADER_ScreensPanel
|
||||
#define HEADER_ScreensPanel
|
||||
/*
|
||||
htop - ScreensPanel.h
|
||||
(C) 2004-2011 Hisham H. Muhammad
|
||||
Released under the GNU GPL, see the COPYING file
|
||||
in the source distribution for its full text.
|
||||
*/
|
||||
|
||||
#include "Panel.h"
|
||||
#include "ScreenManager.h"
|
||||
#include "ColumnsPanel.h"
|
||||
#include "Settings.h"
|
||||
#include "ListItem.h"
|
||||
|
||||
#ifndef SCREEN_NAME_LEN
|
||||
#define SCREEN_NAME_LEN 20
|
||||
#endif
|
||||
|
||||
typedef struct ScreensPanel_ {
|
||||
Panel super;
|
||||
|
||||
ScreenManager* scr;
|
||||
Settings* settings;
|
||||
ColumnsPanel* columns;
|
||||
char buffer[SCREEN_NAME_LEN + 1];
|
||||
char* saved;
|
||||
int cursor;
|
||||
bool moving;
|
||||
bool renaming;
|
||||
} ScreensPanel;
|
||||
|
||||
typedef struct ScreenListItem_ {
|
||||
ListItem super;
|
||||
ScreenSettings* ss;
|
||||
} ScreenListItem;
|
||||
|
||||
|
||||
extern ObjectClass ScreenListItem_class;
|
||||
|
||||
ScreenListItem* ScreenListItem_new(const char* value, ScreenSettings* ss);
|
||||
|
||||
extern PanelClass ScreensPanel_class;
|
||||
|
||||
ScreensPanel* ScreensPanel_new(Settings* settings);
|
||||
|
||||
void ScreensPanel_update(Panel* super);
|
||||
|
||||
#endif
|
293
Settings.c
293
Settings.c
@ -24,14 +24,62 @@ in the source distribution for its full text.
|
||||
#include "XUtils.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
static char** readQuotedList(char* line) {
|
||||
int n = 0;
|
||||
char** list = xCalloc(sizeof(char*), 1);
|
||||
int start = 0;
|
||||
for (;;) {
|
||||
while (line[start] && line[start] == ' ') {
|
||||
start++;
|
||||
}
|
||||
if (line[start] != '"') {
|
||||
break;
|
||||
}
|
||||
start++;
|
||||
int close = start;
|
||||
while (line[close] && line[close] != '"') {
|
||||
close++;
|
||||
}
|
||||
int len = close - start;
|
||||
char* item = xMalloc(len + 1);
|
||||
strncpy(item, line + start, len);
|
||||
item[len] = '\0';
|
||||
list[n] = item;
|
||||
n++;
|
||||
list = xRealloc(list, sizeof(char*) * (n + 1));
|
||||
start = close + 1;
|
||||
}
|
||||
list[n] = NULL;
|
||||
return list;
|
||||
}
|
||||
|
||||
static void writeQuotedList(FILE* fd, char** list) {
|
||||
const char* sep = "";
|
||||
for (int i = 0; list[i]; i++) {
|
||||
fprintf(fd, "%s\"%s\"", sep, list[i]);
|
||||
sep = " ";
|
||||
}
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void Settings_delete(Settings* this) {
|
||||
free(this->filename);
|
||||
free(this->fields);
|
||||
for (unsigned int i = 0; i < HeaderLayout_getColumns(this->hLayout); i++) {
|
||||
String_freeArray(this->hColumns[i].names);
|
||||
free(this->hColumns[i].modes);
|
||||
}
|
||||
free(this->hColumns);
|
||||
if (this->screens) {
|
||||
for (unsigned int i = 0; this->screens[i]; i++) {
|
||||
free(this->screens[i]->name);
|
||||
free(this->screens[i]->fields);
|
||||
}
|
||||
free(this->screens);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
@ -148,46 +196,98 @@ static void Settings_defaultMeters(Settings* this, unsigned int initialCpuCount)
|
||||
this->hColumns[1].modes[r++] = TEXT_METERMODE;
|
||||
}
|
||||
|
||||
static void Settings_readFields(Settings* settings, const char* line) {
|
||||
static const char* toFieldName(Hashtable* columns, int id) {
|
||||
if (id < 0)
|
||||
return NULL;
|
||||
if (id >= LAST_PROCESSFIELD) {
|
||||
const DynamicColumn* column = DynamicColumn_lookup(columns, id);
|
||||
return column->name;
|
||||
}
|
||||
return Process_fields[id].name;
|
||||
}
|
||||
|
||||
static int toFieldIndex(Hashtable* columns, const char* str) {
|
||||
if (isdigit(str[0])) {
|
||||
// This "+1" is for compatibility with the older enum format.
|
||||
int id = atoi(str) + 1;
|
||||
if (toFieldName(columns, id)) {
|
||||
return id;
|
||||
}
|
||||
} else {
|
||||
// Dynamically-defined columns are always stored by-name.
|
||||
char dynamic[32] = {0};
|
||||
if (sscanf(str, "Dynamic(%30s)", dynamic)) {
|
||||
char* end;
|
||||
if ((end = strrchr(dynamic, ')')) != NULL) {
|
||||
bool success;
|
||||
unsigned int key;
|
||||
*end = '\0';
|
||||
success = DynamicColumn_search(columns, dynamic, &key) != NULL;
|
||||
*end = ')';
|
||||
if (success)
|
||||
return key;
|
||||
}
|
||||
}
|
||||
// Fallback to iterative scan of table of fields by-name.
|
||||
for (int p = 1; p < LAST_PROCESSFIELD; p++) {
|
||||
const char* pName = toFieldName(columns, p);
|
||||
if (pName && strcmp(pName, str) == 0)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void ScreenSettings_readFields(ScreenSettings* ss, Hashtable* columns, const char* line) {
|
||||
char* trim = String_trim(line);
|
||||
char** ids = String_split(trim, ' ', NULL);
|
||||
free(trim);
|
||||
|
||||
settings->flags = 0;
|
||||
|
||||
unsigned int i, j;
|
||||
for (j = 0, i = 0; ids[i]; i++) {
|
||||
if (j >= UINT_MAX / sizeof(ProcessField))
|
||||
continue;
|
||||
if (j >= LAST_PROCESSFIELD) {
|
||||
settings->fields = xRealloc(settings->fields, j * sizeof(ProcessField));
|
||||
memset(&settings->fields[j], 0, sizeof(ProcessField));
|
||||
}
|
||||
|
||||
// Dynamically-defined columns are always stored by-name.
|
||||
char dynamic[32] = {0};
|
||||
if (sscanf(ids[i], "Dynamic(%30s)", dynamic)) {
|
||||
char* end;
|
||||
if ((end = strrchr(dynamic, ')')) == NULL)
|
||||
continue;
|
||||
*end = '\0';
|
||||
unsigned int key;
|
||||
if (!DynamicColumn_search(settings->dynamicColumns, dynamic, &key))
|
||||
continue;
|
||||
settings->fields[j++] = key;
|
||||
continue;
|
||||
}
|
||||
// This "+1" is for compatibility with the older enum format.
|
||||
int id = atoi(ids[i]) + 1;
|
||||
if (id > 0 && id < LAST_PROCESSFIELD && Process_fields[id].name) {
|
||||
settings->flags |= Process_fields[id].flags;
|
||||
settings->fields[j++] = id;
|
||||
ss->fields = xRealloc(ss->fields, (j+1) * sizeof(ProcessField));
|
||||
memset(&ss->fields[j], 0, sizeof(ProcessField));
|
||||
}
|
||||
int id = toFieldIndex(columns, ids[i]);
|
||||
if (id >= 0)
|
||||
ss->fields[j] = id;
|
||||
if (id > 0 && id < LAST_PROCESSFIELD)
|
||||
ss->flags |= Process_fields[id].flags;
|
||||
j++;
|
||||
}
|
||||
settings->fields[j] = NULL_PROCESSFIELD;
|
||||
String_freeArray(ids);
|
||||
}
|
||||
|
||||
ScreenSettings* Settings_newScreen(Settings* this, const char* name, const char* line) {
|
||||
ScreenSettings* ss = xCalloc(sizeof(ScreenSettings), 1);
|
||||
ss->name = xStrdup(name);
|
||||
ss->fields = xCalloc(LAST_PROCESSFIELD, sizeof(ProcessField));
|
||||
ss->flags = 0;
|
||||
ss->direction = 1;
|
||||
ss->treeDirection = 1;
|
||||
ss->treeSortKey = 1;
|
||||
ss->treeView = false;
|
||||
ss->treeViewAlwaysByPID = false;
|
||||
ss->allBranchesCollapsed = false;
|
||||
ScreenSettings_readFields(ss, this->dynamicColumns, line);
|
||||
this->screens[this->nScreens] = ss;
|
||||
this->nScreens++;
|
||||
this->screens = xRealloc(this->screens, sizeof(ScreenSettings*) * (this->nScreens + 1));
|
||||
this->screens[this->nScreens] = NULL;
|
||||
return ss;
|
||||
}
|
||||
|
||||
static void Settings_defaultScreens(Settings* this) {
|
||||
for (unsigned int i = 0; i < Platform_numberOfDefaultScreens; i++) {
|
||||
ScreenDefaults* defaults = &Platform_defaultScreens[i];
|
||||
Settings_newScreen(this, defaults->name, defaults->columns);
|
||||
this->screens[i]->sortKey = toFieldIndex(this->dynamicColumns, defaults->sortKey);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Settings_read(Settings* this, const char* fileName, unsigned int initialCpuCount) {
|
||||
FILE* fd = fopen(fileName, "r");
|
||||
if (!fd)
|
||||
@ -220,23 +320,33 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
||||
return false;
|
||||
}
|
||||
} else if (String_eq(option[0], "fields")) {
|
||||
Settings_readFields(this, option[1]);
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
if (!this->nScreens)
|
||||
Settings_defaultScreens(this);
|
||||
ScreenSettings_readFields(this->screens[0], this->dynamicColumns, option[1]);
|
||||
} else if (String_eq(option[0], "sort_key")) {
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
// This "+1" is for compatibility with the older enum format.
|
||||
this->sortKey = atoi(option[1]) + 1;
|
||||
this->screens[0]->sortKey = atoi(option[1]) + 1;
|
||||
} else if (String_eq(option[0], "tree_sort_key")) {
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
// This "+1" is for compatibility with the older enum format.
|
||||
this->treeSortKey = atoi(option[1]) + 1;
|
||||
this->screens[0]->treeSortKey = atoi(option[1]) + 1;
|
||||
} else if (String_eq(option[0], "sort_direction")) {
|
||||
this->direction = atoi(option[1]);
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
this->screens[0]->direction = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "tree_sort_direction")) {
|
||||
this->treeDirection = atoi(option[1]);
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
this->screens[0]->treeDirection = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "tree_view")) {
|
||||
this->treeView = atoi(option[1]);
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
this->screens[0]->treeView = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "tree_view_always_by_pid")) {
|
||||
this->treeViewAlwaysByPID = atoi(option[1]);
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
this->screens[0]->treeViewAlwaysByPID = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "all_branches_collapsed")) {
|
||||
this->allBranchesCollapsed = atoi(option[1]);
|
||||
// old (no screen) naming also supported for backwards compatibility
|
||||
this->screens[0]->allBranchesCollapsed = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "hide_kernel_threads")) {
|
||||
this->hideKernelThreads = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "hide_userland_threads")) {
|
||||
@ -267,6 +377,8 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
||||
this->showMergedCommand = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "header_margin")) {
|
||||
this->headerMargin = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "screen_tabs")) {
|
||||
this->screenTabs = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "expand_system_time")) {
|
||||
// Compatibility option.
|
||||
this->detailedCPUTime = atoi(option[1]);
|
||||
@ -332,23 +444,45 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
||||
} else if (String_eq(option[0], "topology_affinity")) {
|
||||
this->topologyAffinity = !!atoi(option[1]);
|
||||
#endif
|
||||
} else if (strncmp(option[0], "screen:", 7) == 0) {
|
||||
Settings_newScreen(this, option[0] + 7, option[1]);
|
||||
} else if (String_eq(option[0], ".sort_key")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->sortKey = toFieldIndex(this->dynamicColumns, option[1]);
|
||||
} else if (String_eq(option[0], ".tree_sort_key")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->treeSortKey = toFieldIndex(this->dynamicColumns, option[1]);
|
||||
} else if (String_eq(option[0], ".sort_direction")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->direction = atoi(option[1]);
|
||||
} else if (String_eq(option[0], ".tree_sort_direction")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->treeDirection = atoi(option[1]);
|
||||
} else if (String_eq(option[0], ".tree_view")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->treeView = atoi(option[1]);
|
||||
} else if (String_eq(option[0], ".tree_view_always_by_pid")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->treeViewAlwaysByPID = atoi(option[1]);
|
||||
} else if (String_eq(option[0], ".all_branches_collapsed")) {
|
||||
if (this->nScreens)
|
||||
this->screens[this->nScreens - 1]->allBranchesCollapsed = atoi(option[1]);
|
||||
}
|
||||
String_freeArray(option);
|
||||
}
|
||||
fclose(fd);
|
||||
if (!didReadMeters || !Settings_validateMeters(this)) {
|
||||
if (!didReadMeters || !Settings_validateMeters(this))
|
||||
Settings_defaultMeters(this, initialCpuCount);
|
||||
}
|
||||
if (!this->nScreens)
|
||||
Settings_defaultScreens(this);
|
||||
return didReadAny;
|
||||
}
|
||||
|
||||
static void writeFields(FILE* fd, const ProcessField* fields, Hashtable* columns, const char* name, char separator) {
|
||||
fprintf(fd, "%s=", name);
|
||||
static void writeFields(FILE* fd, const ProcessField* fields, Hashtable* columns, bool byName, char separator) {
|
||||
const char* sep = "";
|
||||
for (unsigned int i = 0; fields[i]; i++) {
|
||||
if (fields[i] >= LAST_PROCESSFIELD) {
|
||||
const DynamicColumn* column = DynamicColumn_lookup(columns, fields[i]);
|
||||
fprintf(fd, "%sDynamic(%s)", sep, column->name);
|
||||
if (fields[i] >= LAST_PROCESSFIELD || byName) {
|
||||
fprintf(fd, "%s%s", sep, toFieldName(columns, i));
|
||||
} else {
|
||||
// This "-1" is for compatibility with the older enum format.
|
||||
fprintf(fd, "%s%d", sep, (int) fields[i] - 1);
|
||||
@ -358,15 +492,19 @@ static void writeFields(FILE* fd, const ProcessField* fields, Hashtable* columns
|
||||
fputc(separator, fd);
|
||||
}
|
||||
|
||||
static void writeMeters(const Settings* this, FILE* fd, char separator, unsigned int column) {
|
||||
static void writeList(FILE* fd, char** list, int len, char separator) {
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i < this->hColumns[column].len; i++) {
|
||||
fprintf(fd, "%s%s", sep, this->hColumns[column].names[i]);
|
||||
for (int i = 0; i < len; i++) {
|
||||
fprintf(fd, "%s%s", sep, list[i]);
|
||||
sep = " ";
|
||||
}
|
||||
fputc(separator, fd);
|
||||
}
|
||||
|
||||
static void writeMeters(const Settings* this, FILE* fd, char separator, unsigned int column) {
|
||||
writeList(fd, this->hColumns[column].names, this->hColumns[column].len, separator);
|
||||
}
|
||||
|
||||
static void writeMeterModes(const Settings* this, FILE* fd, char separator, unsigned int column) {
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i < this->hColumns[column].len; i++) {
|
||||
@ -400,12 +538,7 @@ int Settings_write(const Settings* this, bool onCrash) {
|
||||
}
|
||||
printSettingString("htop_version", VERSION);
|
||||
printSettingInteger("config_reader_min_version", CONFIG_READER_MIN_VERSION);
|
||||
writeFields(fd, this->fields, this->dynamicColumns, "fields", separator);
|
||||
// This "-1" is for compatibility with the older enum format.
|
||||
printSettingInteger("sort_key", this->sortKey - 1);
|
||||
printSettingInteger("sort_direction", this->direction);
|
||||
printSettingInteger("tree_sort_key", this->treeSortKey - 1);
|
||||
printSettingInteger("tree_sort_direction", this->treeDirection);
|
||||
fprintf(fd, "fields="); writeFields(fd, this->screens[0]->fields, this->dynamicColumns, false, separator);
|
||||
printSettingInteger("hide_kernel_threads", this->hideKernelThreads);
|
||||
printSettingInteger("hide_userland_threads", this->hideUserlandThreads);
|
||||
printSettingInteger("shadow_other_users", this->shadowOtherUsers);
|
||||
@ -420,10 +553,8 @@ int Settings_write(const Settings* this, bool onCrash) {
|
||||
printSettingInteger("find_comm_in_cmdline", this->findCommInCmdline);
|
||||
printSettingInteger("strip_exe_from_cmdline", this->stripExeFromCmdline);
|
||||
printSettingInteger("show_merged_command", this->showMergedCommand);
|
||||
printSettingInteger("tree_view", this->treeView);
|
||||
printSettingInteger("tree_view_always_by_pid", this->treeViewAlwaysByPID);
|
||||
printSettingInteger("all_branches_collapsed", this->allBranchesCollapsed);
|
||||
printSettingInteger("header_margin", this->headerMargin);
|
||||
printSettingInteger("screen_tabs", this->screenTabs);
|
||||
printSettingInteger("detailed_cpu_time", this->detailedCPUTime);
|
||||
printSettingInteger("cpu_count_from_one", this->countCPUsFromOne);
|
||||
printSettingInteger("show_cpu_usage", this->showCPUUsage);
|
||||
@ -452,6 +583,31 @@ int Settings_write(const Settings* this, bool onCrash) {
|
||||
writeMeterModes(this, fd, separator, i);
|
||||
}
|
||||
|
||||
// Legacy compatibility with older versions of htop
|
||||
printSettingInteger("tree_view", this->screens[0]->treeView);
|
||||
// This "-1" is for compatibility with the older enum format.
|
||||
printSettingInteger("sort_key", this->screens[0]->sortKey - 1);
|
||||
printSettingInteger("tree_sort_key", this->screens[0]->treeSortKey - 1);
|
||||
printSettingInteger("sort_direction", this->screens[0]->direction);
|
||||
printSettingInteger("tree_sort_direction", this->screens[0]->treeDirection);
|
||||
printSettingInteger("tree_view_always_by_pid", this->screens[0]->treeViewAlwaysByPID);
|
||||
printSettingInteger("all_branches_collapsed", this->screens[0]->allBranchesCollapsed);
|
||||
|
||||
if (this->screens && this->screens[0]) {
|
||||
for (unsigned int i = 0; i < this->nScreens; i++) {
|
||||
ScreenSettings* ss = this->screens[i];
|
||||
fprintf(fd, "screen:%s=", ss->name);
|
||||
writeFields(fd, ss->fields, this->dynamicColumns, true, separator);
|
||||
printSettingString(".sort_key", toFieldName(this->dynamicColumns, ss->sortKey));
|
||||
printSettingString(".tree_sort_key", toFieldName(this->dynamicColumns, ss->treeSortKey));
|
||||
printSettingInteger(".tree_view", ss->treeView);
|
||||
printSettingInteger(".tree_view_always_by_pid", ss->treeViewAlwaysByPID);
|
||||
printSettingInteger(".sort_direction", ss->direction);
|
||||
printSettingInteger(".tree_sort_direction", ss->treeDirection);
|
||||
printSettingInteger(".all_branches_collapsed", ss->allBranchesCollapsed);
|
||||
}
|
||||
}
|
||||
|
||||
#undef printSettingString
|
||||
#undef printSettingInteger
|
||||
|
||||
@ -475,16 +631,11 @@ Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns)
|
||||
this->dynamicColumns = dynamicColumns;
|
||||
this->hLayout = HF_TWO_50_50;
|
||||
this->hColumns = xCalloc(HeaderLayout_getColumns(this->hLayout), sizeof(MeterColumnSetting));
|
||||
this->sortKey = PERCENT_CPU;
|
||||
this->treeSortKey = PID;
|
||||
this->direction = -1;
|
||||
this->treeDirection = 1;
|
||||
|
||||
this->shadowOtherUsers = false;
|
||||
this->showThreadNames = false;
|
||||
this->hideKernelThreads = true;
|
||||
this->hideUserlandThreads = false;
|
||||
this->treeView = false;
|
||||
this->allBranchesCollapsed = false;
|
||||
this->highlightBaseName = false;
|
||||
this->highlightDeletedExe = true;
|
||||
this->highlightMegabytes = true;
|
||||
@ -506,18 +657,13 @@ Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns)
|
||||
this->showMergedCommand = false;
|
||||
this->hideFunctionBar = 0;
|
||||
this->headerMargin = true;
|
||||
this->screenTabs = true;
|
||||
#ifdef HAVE_LIBHWLOC
|
||||
this->topologyAffinity = false;
|
||||
#endif
|
||||
this->fields = xCalloc(LAST_PROCESSFIELD + 1, sizeof(ProcessField));
|
||||
// TODO: turn 'fields' into a Vector,
|
||||
// (and ProcessFields into proper objects).
|
||||
this->flags = 0;
|
||||
const ProcessField* defaults = Platform_defaultFields;
|
||||
for (int i = 0; defaults[i]; i++) {
|
||||
this->fields[i] = defaults[i];
|
||||
this->flags |= Process_fields[defaults[i]].flags;
|
||||
}
|
||||
|
||||
this->screens = xCalloc(Platform_numberOfDefaultScreens * sizeof(ScreenSettings*), 1);
|
||||
this->nScreens = 0;
|
||||
|
||||
char* legacyDotfile = NULL;
|
||||
const char* rcfile = getenv("HTOPRC");
|
||||
@ -578,16 +724,21 @@ Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns)
|
||||
}
|
||||
if (!ok) {
|
||||
Settings_defaultMeters(this, initialCpuCount);
|
||||
Settings_defaultScreens(this);
|
||||
}
|
||||
|
||||
this->ssIndex = 0;
|
||||
this->ss = this->screens[this->ssIndex];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Settings_invertSortOrder(Settings* this) {
|
||||
void ScreenSettings_invertSortOrder(ScreenSettings* this) {
|
||||
int* attr = (this->treeView) ? &(this->treeDirection) : &(this->direction);
|
||||
*attr = (*attr == 1) ? -1 : 1;
|
||||
}
|
||||
|
||||
void Settings_setSortKey(Settings* this, ProcessField sortKey) {
|
||||
void ScreenSettings_setSortKey(ScreenSettings* this, ProcessField sortKey) {
|
||||
if (this->treeViewAlwaysByPID || !this->treeView) {
|
||||
this->sortKey = sortKey;
|
||||
this->direction = (Process_fields[sortKey].defaultSortDesc) ? -1 : 1;
|
||||
|
47
Settings.h
47
Settings.h
@ -19,7 +19,13 @@ in the source distribution for its full text.
|
||||
|
||||
#define DEFAULT_DELAY 15
|
||||
|
||||
#define CONFIG_READER_MIN_VERSION 2
|
||||
#define CONFIG_READER_MIN_VERSION 3
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const char* columns;
|
||||
const char* sortKey;
|
||||
} ScreenDefaults;
|
||||
|
||||
typedef struct {
|
||||
size_t len;
|
||||
@ -27,6 +33,19 @@ typedef struct {
|
||||
int* modes;
|
||||
} MeterColumnSetting;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
ProcessField* fields;
|
||||
uint32_t flags;
|
||||
int direction;
|
||||
int treeDirection;
|
||||
ProcessField sortKey;
|
||||
ProcessField treeSortKey;
|
||||
bool treeView;
|
||||
bool treeViewAlwaysByPID;
|
||||
bool allBranchesCollapsed;
|
||||
} ScreenSettings;
|
||||
|
||||
typedef struct Settings_ {
|
||||
char* filename;
|
||||
int config_version;
|
||||
@ -34,16 +53,14 @@ typedef struct Settings_ {
|
||||
MeterColumnSetting* hColumns;
|
||||
Hashtable* dynamicColumns;
|
||||
|
||||
ProcessField* fields;
|
||||
uint32_t flags;
|
||||
ScreenSettings** screens;
|
||||
unsigned int nScreens;
|
||||
unsigned int ssIndex;
|
||||
ScreenSettings* ss;
|
||||
|
||||
int colorScheme;
|
||||
int delay;
|
||||
|
||||
int direction;
|
||||
int treeDirection;
|
||||
ProcessField sortKey;
|
||||
ProcessField treeSortKey;
|
||||
|
||||
bool countCPUsFromOne;
|
||||
bool detailedCPUTime;
|
||||
bool showCPUUsage;
|
||||
@ -52,9 +69,6 @@ typedef struct Settings_ {
|
||||
bool showCPUTemperature;
|
||||
bool degreeFahrenheit;
|
||||
#endif
|
||||
bool treeView;
|
||||
bool treeViewAlwaysByPID;
|
||||
bool allBranchesCollapsed;
|
||||
bool showProgramPath;
|
||||
bool shadowOtherUsers;
|
||||
bool showThreadNames;
|
||||
@ -72,6 +86,7 @@ typedef struct Settings_ {
|
||||
bool updateProcessNames;
|
||||
bool accountGuestInCPUMeter;
|
||||
bool headerMargin;
|
||||
bool screenTabs;
|
||||
#ifdef HAVE_GETMOUSE
|
||||
bool enableMouse;
|
||||
#endif
|
||||
@ -85,13 +100,13 @@ typedef struct Settings_ {
|
||||
|
||||
#define Settings_cpuId(settings, cpu) ((settings)->countCPUsFromOne ? (cpu)+1 : (cpu))
|
||||
|
||||
static inline ProcessField Settings_getActiveSortKey(const Settings* this) {
|
||||
static inline ProcessField ScreenSettings_getActiveSortKey(const ScreenSettings* this) {
|
||||
return (this->treeView)
|
||||
? (this->treeViewAlwaysByPID ? PID : this->treeSortKey)
|
||||
: this->sortKey;
|
||||
}
|
||||
|
||||
static inline int Settings_getActiveDirection(const Settings* this) {
|
||||
static inline int ScreenSettings_getActiveDirection(const ScreenSettings* this) {
|
||||
return this->treeView ? this->treeDirection : this->direction;
|
||||
}
|
||||
|
||||
@ -101,9 +116,11 @@ int Settings_write(const Settings* this, bool onCrash);
|
||||
|
||||
Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns);
|
||||
|
||||
void Settings_invertSortOrder(Settings* this);
|
||||
ScreenSettings* Settings_newScreen(Settings* this, const char* name, const char* line);
|
||||
|
||||
void Settings_setSortKey(Settings* this, ProcessField sortKey);
|
||||
void ScreenSettings_invertSortOrder(ScreenSettings* this);
|
||||
|
||||
void ScreenSettings_setSortKey(ScreenSettings* this, ProcessField sortKey);
|
||||
|
||||
void Settings_enableReadonly(void);
|
||||
|
||||
|
@ -322,7 +322,7 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
|
||||
DarwinProcess_updateExe(ep->p_pid, proc);
|
||||
DarwinProcess_updateCmdLine(ps, proc);
|
||||
|
||||
if (proc->settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (proc->settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
DarwinProcess_updateCwd(ep->p_pid, proc);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,16 @@ in the source distribution for its full text.
|
||||
#endif
|
||||
|
||||
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
|
||||
const SignalItem Platform_signals[] = {
|
||||
|
@ -26,7 +26,9 @@ in the source distribution for its full text.
|
||||
#include "generic/uname.h"
|
||||
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
|
@ -481,7 +481,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||
DragonFlyBSDProcessList_updateExe(kproc, proc);
|
||||
DragonFlyBSDProcessList_updateProcessName(dfpl->kd, kproc, proc);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
DragonFlyBSDProcessList_updateCwd(kproc, proc);
|
||||
}
|
||||
|
||||
|
@ -32,8 +32,15 @@ in the source distribution for its full text.
|
||||
#include "dragonflybsd/DragonFlyBSDProcess.h"
|
||||
#include "dragonflybsd/DragonFlyBSDProcessList.h"
|
||||
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
const SignalItem Platform_signals[] = {
|
||||
{ .name = " 0 Cancel", .number = 0 },
|
||||
|
@ -29,7 +29,9 @@ in the source distribution for its full text.
|
||||
#include "generic/uname.h"
|
||||
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
|
@ -516,7 +516,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||
FreeBSDProcessList_updateExe(kproc, proc);
|
||||
FreeBSDProcessList_updateProcessName(fpl->kd, kproc, proc);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
FreeBSDProcessList_updateCwd(kproc, proc);
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,15 @@ in the source distribution for its full text.
|
||||
#include "zfs/ZfsArcMeter.h"
|
||||
#include "zfs/ZfsCompressedArcMeter.h"
|
||||
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
const SignalItem Platform_signals[] = {
|
||||
{ .name = " 0 Cancel", .number = 0 },
|
||||
|
@ -25,7 +25,9 @@ in the source distribution for its full text.
|
||||
#include "generic/uname.h"
|
||||
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
|
@ -1370,6 +1370,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
ProcessList* pl = (ProcessList*) this;
|
||||
const struct dirent* entry;
|
||||
const Settings* settings = pl->settings;
|
||||
const ScreenSettings* ss = settings->ss;
|
||||
|
||||
#ifdef HAVE_OPENAT
|
||||
int dirFd = openat(parentFd, dirname, O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||
@ -1463,7 +1464,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
continue;
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_IO)
|
||||
if (ss->flags & PROCESS_FLAG_IO)
|
||||
LinuxProcessList_readIoFile(lp, procFd, pl->realtimeMs);
|
||||
|
||||
if (!LinuxProcessList_readStatmFile(lp, procFd))
|
||||
@ -1472,7 +1473,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
{
|
||||
bool prev = proc->usesDeletedLib;
|
||||
|
||||
if ((settings->flags & PROCESS_FLAG_LINUX_LRS_FIX) ||
|
||||
if ((ss->flags & PROCESS_FLAG_LINUX_LRS_FIX) ||
|
||||
(settings->highlightDeletedExe && !proc->procExeDeleted && !proc->isKernelThread && !proc->isUserlandThread)) {
|
||||
// Check if we really should recalculate the M_LRS value for this process
|
||||
uint64_t passedTimeInMs = pl->realtimeMs - lp->last_mlrs_calctime;
|
||||
@ -1481,7 +1482,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
|
||||
if (passedTimeInMs > recheck) {
|
||||
lp->last_mlrs_calctime = pl->realtimeMs;
|
||||
LinuxProcessList_readMaps(lp, procFd, settings->flags & PROCESS_FLAG_LINUX_LRS_FIX, settings->highlightDeletedExe);
|
||||
LinuxProcessList_readMaps(lp, procFd, ss->flags & PROCESS_FLAG_LINUX_LRS_FIX, settings->highlightDeletedExe);
|
||||
}
|
||||
} else {
|
||||
/* Copy from process structure in threads and reset if setting got disabled */
|
||||
@ -1491,7 +1492,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
proc->mergedCommand.exeChanged |= prev ^ proc->usesDeletedLib;
|
||||
}
|
||||
|
||||
if ((settings->flags & PROCESS_FLAG_LINUX_SMAPS) && !Process_isKernelThread(proc)) {
|
||||
if ((ss->flags & PROCESS_FLAG_LINUX_SMAPS) && !Process_isKernelThread(proc)) {
|
||||
if (!parent) {
|
||||
// Read smaps file of each process only every second pass to improve performance
|
||||
static int smaps_flag = 0;
|
||||
@ -1521,7 +1522,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
proc->tty_name = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_IOPRIO) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_IOPRIO) {
|
||||
LinuxProcess_updateIOPriority(lp);
|
||||
}
|
||||
|
||||
@ -1536,13 +1537,13 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
if (!preExisting) {
|
||||
|
||||
#ifdef HAVE_OPENVZ
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_OPENVZ) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_OPENVZ) {
|
||||
LinuxProcessList_readOpenVZData(lp, procFd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VSERVER
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_VSERVER) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_VSERVER) {
|
||||
LinuxProcessList_readVServerData(lp, procFd);
|
||||
}
|
||||
#endif
|
||||
@ -1567,32 +1568,32 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
}
|
||||
|
||||
#ifdef HAVE_DELAYACCT
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_DELAYACCT) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_DELAYACCT) {
|
||||
LinuxProcessList_readDelayAcctData(this, lp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_CGROUP) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_CGROUP) {
|
||||
LinuxProcessList_readCGroupFile(lp, procFd);
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_OOM) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_OOM) {
|
||||
LinuxProcessList_readOomData(lp, procFd);
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_CTXT) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_CTXT) {
|
||||
LinuxProcessList_readCtxtData(lp, procFd);
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_SECATTR) {
|
||||
if (ss->flags & PROCESS_FLAG_LINUX_SECATTR) {
|
||||
LinuxProcessList_readSecattrData(lp, procFd);
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (ss->flags & PROCESS_FLAG_CWD) {
|
||||
LinuxProcessList_readCwd(lp, procFd);
|
||||
}
|
||||
|
||||
if ((settings->flags & PROCESS_FLAG_LINUX_AUTOGROUP) && this->haveAutogroup) {
|
||||
if ((ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP) && this->haveAutogroup) {
|
||||
LinuxProcessList_readAutogroup(lp, procFd);
|
||||
}
|
||||
|
||||
@ -2146,7 +2147,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_AUTOGROUP) {
|
||||
if (settings->ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP) {
|
||||
// Refer to sched(7) 'autogroup feature' section
|
||||
// The kernel feature can be enabled/disabled through procfs at
|
||||
// any time, so check for it at the start of each sample - only
|
||||
|
@ -79,7 +79,20 @@ enum CapMode {
|
||||
};
|
||||
#endif
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
{
|
||||
.name = "I/O",
|
||||
.columns = "PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY COMM",
|
||||
.sortKey = "IO_RATE",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
const SignalItem Platform_signals[] = {
|
||||
{ .name = " 0 Cancel", .number = 0 },
|
||||
|
@ -38,7 +38,9 @@ in the source distribution for its full text.
|
||||
#endif
|
||||
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
|
@ -307,7 +307,7 @@ static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) {
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
NetBSDProcessList_updateCwd(kproc, proc);
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,16 @@ in the source distribution for its full text.
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
/*
|
||||
* See /usr/include/sys/signal.h
|
||||
*/
|
||||
|
@ -36,6 +36,10 @@ in the source distribution for its full text.
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
/* see /usr/include/sys/signal.h */
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
|
@ -309,7 +309,7 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
|
||||
|
||||
OpenBSDProcessList_updateProcessName(this->kd, kproc, proc);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
OpenBSDProcessList_updateCwd(kproc, proc);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,15 @@ in the source distribution for its full text.
|
||||
#include "openbsd/OpenBSDProcessList.h"
|
||||
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
/*
|
||||
* See /usr/include/sys/signal.h
|
||||
|
@ -26,7 +26,9 @@ in the source distribution for its full text.
|
||||
#include "generic/uname.h"
|
||||
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
/* see /usr/include/sys/signal.h */
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
@ -384,12 +384,12 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_IO)
|
||||
if (settings->ss->flags & PROCESS_FLAG_IO)
|
||||
PCPProcessList_updateIO(pp, pid, offset, now);
|
||||
|
||||
PCPProcessList_updateMemory(pp, pid, offset);
|
||||
|
||||
if ((settings->flags & PROCESS_FLAG_LINUX_SMAPS) &&
|
||||
if ((settings->ss->flags & PROCESS_FLAG_LINUX_SMAPS) &&
|
||||
(Process_isKernelThread(proc) == false)) {
|
||||
if (PCPMetric_enabled(PCP_PROC_SMAPS_PSS))
|
||||
PCPProcessList_updateSmaps(pp, pid, offset);
|
||||
@ -419,22 +419,22 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period,
|
||||
PCPProcessList_updateCmdline(proc, pid, offset, command);
|
||||
}
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_CGROUP)
|
||||
if (settings->ss->flags & PROCESS_FLAG_LINUX_CGROUP)
|
||||
PCPProcessList_readCGroups(pp, pid, offset);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_OOM)
|
||||
if (settings->ss->flags & PROCESS_FLAG_LINUX_OOM)
|
||||
PCPProcessList_readOomData(pp, pid, offset);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_CTXT)
|
||||
if (settings->ss->flags & PROCESS_FLAG_LINUX_CTXT)
|
||||
PCPProcessList_readCtxtData(pp, pid, offset);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_SECATTR)
|
||||
if (settings->ss->flags & PROCESS_FLAG_LINUX_SECATTR)
|
||||
PCPProcessList_readSecattrData(pp, pid, offset);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_CWD)
|
||||
if (settings->ss->flags & PROCESS_FLAG_CWD)
|
||||
PCPProcessList_readCwd(pp, pid, offset);
|
||||
|
||||
if (settings->flags & PROCESS_FLAG_LINUX_AUTOGROUP)
|
||||
if (settings->ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP)
|
||||
PCPProcessList_readAutogroup(pp, pid, offset);
|
||||
|
||||
if (proc->state == ZOMBIE && !proc->cmdline && command[0]) {
|
||||
@ -676,16 +676,16 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||
for (int metric = PCP_PROC_PID; metric < PCP_METRIC_COUNT; metric++)
|
||||
PCPMetric_enable(metric, enabled);
|
||||
|
||||
flagged = settings->flags & PROCESS_FLAG_LINUX_CGROUP;
|
||||
flagged = settings->ss->flags & PROCESS_FLAG_LINUX_CGROUP;
|
||||
PCPMetric_enable(PCP_PROC_CGROUPS, flagged && enabled);
|
||||
flagged = settings->flags & PROCESS_FLAG_LINUX_OOM;
|
||||
flagged = settings->ss->flags & PROCESS_FLAG_LINUX_OOM;
|
||||
PCPMetric_enable(PCP_PROC_OOMSCORE, flagged && enabled);
|
||||
flagged = settings->flags & PROCESS_FLAG_LINUX_CTXT;
|
||||
flagged = settings->ss->flags & PROCESS_FLAG_LINUX_CTXT;
|
||||
PCPMetric_enable(PCP_PROC_VCTXSW, flagged && enabled);
|
||||
PCPMetric_enable(PCP_PROC_NVCTXSW, flagged && enabled);
|
||||
flagged = settings->flags & PROCESS_FLAG_LINUX_SECATTR;
|
||||
flagged = settings->ss->flags & PROCESS_FLAG_LINUX_SECATTR;
|
||||
PCPMetric_enable(PCP_PROC_LABELS, flagged && enabled);
|
||||
flagged = settings->flags & PROCESS_FLAG_LINUX_AUTOGROUP;
|
||||
flagged = settings->ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP;
|
||||
PCPMetric_enable(PCP_PROC_AUTOGROUP_ID, flagged && enabled);
|
||||
PCPMetric_enable(PCP_PROC_AUTOGROUP_NICE, flagged && enabled);
|
||||
|
||||
|
@ -54,6 +54,21 @@ in the source distribution for its full text.
|
||||
|
||||
Platform* pcp;
|
||||
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
{
|
||||
.name = "I/O",
|
||||
.columns = "PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY COMM",
|
||||
.sortKey = "IO_RATE",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
|
||||
int Platform_numberOfFields = LAST_PROCESSFIELD;
|
||||
|
@ -58,6 +58,10 @@ typedef struct Platform_ {
|
||||
unsigned int ncpu; /* maximum processor count configured */
|
||||
} Platform;
|
||||
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern ProcessField Platform_defaultFields[];
|
||||
|
||||
extern int Platform_numberOfFields;
|
||||
|
@ -40,6 +40,16 @@ in the source distribution for its full text.
|
||||
#include "SolarisProcessList.h"
|
||||
|
||||
|
||||
ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Default",
|
||||
.columns = "PID LWPID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
const SignalItem Platform_signals[] = {
|
||||
{ .name = " 0 Cancel", .number = 0 },
|
||||
{ .name = " 1 SIGHUP", .number = 1 },
|
||||
@ -87,8 +97,6 @@ const SignalItem Platform_signals[] = {
|
||||
|
||||
const unsigned int Platform_numberOfSignals = ARRAYSIZE(Platform_signals);
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, LWPID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
|
||||
const MeterClass* const Platform_meterTypes[] = {
|
||||
&CPUMeter_class,
|
||||
&ClockMeter_class,
|
||||
|
@ -52,12 +52,14 @@ typedef struct envAccum_ {
|
||||
char* env;
|
||||
} envAccum;
|
||||
|
||||
extern ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
extern const unsigned int Platform_numberOfSignals;
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
|
||||
extern const MeterClass* const Platform_meterTypes[];
|
||||
|
||||
bool Platform_init(void);
|
||||
|
@ -451,7 +451,7 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo,
|
||||
Process_updateComm(proc, _psinfo->pr_fname);
|
||||
Process_updateCmdline(proc, _psinfo->pr_psargs, 0, 0);
|
||||
|
||||
if (proc->settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (proc->settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
SolarisProcessList_updateCwd(_psinfo->pr_pid, proc);
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,22 @@ in the source distribution for its full text.
|
||||
#include "UptimeMeter.h"
|
||||
|
||||
|
||||
const ScreenDefaults Platform_defaultScreens[] = {
|
||||
{
|
||||
.name = "Main",
|
||||
.columns = "PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME COMM",
|
||||
.sortKey = "PERCENT_CPU",
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfDefaultScreens = ARRAYSIZE(Platform_defaultScreens);
|
||||
|
||||
const SignalItem Platform_signals[] = {
|
||||
{ .name = " 0 Cancel", .number = 0 },
|
||||
};
|
||||
|
||||
const unsigned int Platform_numberOfSignals = ARRAYSIZE(Platform_signals);
|
||||
|
||||
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
|
||||
const MeterClass* const Platform_meterTypes[] = {
|
||||
&CPUMeter_class,
|
||||
&ClockMeter_class,
|
||||
|
@ -20,12 +20,14 @@ in the source distribution for its full text.
|
||||
#include "unsupported/UnsupportedProcess.h"
|
||||
|
||||
|
||||
extern const ScreenDefaults Platform_defaultScreens[];
|
||||
|
||||
extern const unsigned int Platform_numberOfDefaultScreens;
|
||||
|
||||
extern const SignalItem Platform_signals[];
|
||||
|
||||
extern const unsigned int Platform_numberOfSignals;
|
||||
|
||||
extern const ProcessField Platform_defaultFields[];
|
||||
|
||||
extern const MeterClass* const Platform_meterTypes[];
|
||||
|
||||
bool Platform_init(void);
|
||||
|
@ -51,7 +51,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||
Process_updateCmdline(proc, "<unsupported architecture>", 0, 0);
|
||||
Process_updateExe(proc, "/path/to/executable");
|
||||
|
||||
if (proc->settings->flags & PROCESS_FLAG_CWD) {
|
||||
if (proc->settings->ss->flags & PROCESS_FLAG_CWD) {
|
||||
free_and_xStrdup(&proc->procCwd, "/current/working/directory");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user