mirror of
https://github.com/xzeldon/htop.git
synced 2024-12-23 22:55:46 +00:00
Allow typing to select items in various panels (sort, user, signal).
Factored code from the SignalsPanel to apply to all selections from main screen. Closes feature request #3425304.
This commit is contained in:
parent
4c4cceee5d
commit
e204861de5
@ -23,7 +23,7 @@ ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c DebugMemory.c \
|
||||
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \
|
||||
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \
|
||||
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
|
||||
SignalItem.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
|
||||
SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
|
||||
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \
|
||||
HostnameMeter.c OpenFilesScreen.c Affinity.c
|
||||
|
||||
@ -32,7 +32,7 @@ CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \
|
||||
CPUMeter.h CRT.h DebugMemory.h DisplayOptionsPanel.h FunctionBar.h \
|
||||
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \
|
||||
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
|
||||
ScreenManager.h Settings.h SignalItem.h SignalsPanel.h String.h \
|
||||
ScreenManager.h Settings.h SignalsPanel.h String.h \
|
||||
SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h \
|
||||
Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h
|
||||
|
||||
|
1
Panel.c
1
Panel.c
@ -47,6 +47,7 @@ struct Panel_ {
|
||||
bool needsRedraw;
|
||||
RichString header;
|
||||
Panel_EventHandler eventHandler;
|
||||
char* eventHandlerBuffer;
|
||||
};
|
||||
|
||||
}*/
|
||||
|
1
Panel.h
1
Panel.h
@ -49,6 +49,7 @@ struct Panel_ {
|
||||
bool needsRedraw;
|
||||
RichString header;
|
||||
Panel_EventHandler eventHandler;
|
||||
char* eventHandlerBuffer;
|
||||
};
|
||||
|
||||
|
||||
|
101
SignalItem.c
101
SignalItem.c
@ -1,101 +0,0 @@
|
||||
/*
|
||||
htop - SignalItem.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 "SignalItem.h"
|
||||
#include "String.h"
|
||||
#include "Object.h"
|
||||
#include "RichString.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define SIGNAL_COUNT 34
|
||||
|
||||
/*{
|
||||
|
||||
typedef struct Signal_ {
|
||||
Object super;
|
||||
const char* name;
|
||||
int number;
|
||||
} Signal;
|
||||
|
||||
}*/
|
||||
|
||||
#ifdef DEBUG
|
||||
char* SIGNAL_CLASS = "Signal";
|
||||
#else
|
||||
#define SIGNAL_CLASS NULL
|
||||
#endif
|
||||
|
||||
static void Signal_delete(Object* cast) {
|
||||
Signal* this = (Signal*)cast;
|
||||
assert (this != NULL);
|
||||
// names are string constants, so we're not deleting them.
|
||||
free(this);
|
||||
}
|
||||
|
||||
static void Signal_display(Object* cast, RichString* out) {
|
||||
Signal* this = (Signal*)cast;
|
||||
assert (this != NULL);
|
||||
|
||||
char buffer[31];
|
||||
snprintf(buffer, 30, "%2d %s", this->number, this->name);
|
||||
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
|
||||
}
|
||||
|
||||
static Signal* Signal_new(const char* name, int number) {
|
||||
Signal* this = malloc(sizeof(Signal));
|
||||
Object_setClass(this, SIGNAL_CLASS);
|
||||
((Object*)this)->display = Signal_display;
|
||||
((Object*)this)->delete = Signal_delete;
|
||||
this->name = name;
|
||||
this->number = number;
|
||||
return this;
|
||||
}
|
||||
|
||||
int Signal_getSignalCount() {
|
||||
return SIGNAL_COUNT;
|
||||
}
|
||||
|
||||
Signal** Signal_getSignalTable() {
|
||||
Signal** signals = malloc(sizeof(Signal*) * SIGNAL_COUNT);
|
||||
signals[0] = Signal_new("Cancel", 0);
|
||||
signals[1] = Signal_new("SIGHUP", 1);
|
||||
signals[2] = Signal_new("SIGINT", 2);
|
||||
signals[3] = Signal_new("SIGQUIT", 3);
|
||||
signals[4] = Signal_new("SIGILL", 4);
|
||||
signals[5] = Signal_new("SIGTRAP", 5);
|
||||
signals[6] = Signal_new("SIGABRT", 6);
|
||||
signals[7] = Signal_new("SIGIOT", 6);
|
||||
signals[8] = Signal_new("SIGBUS", 7);
|
||||
signals[9] = Signal_new("SIGFPE", 8);
|
||||
signals[10] = Signal_new("SIGKILL", 9);
|
||||
signals[11] = Signal_new("SIGUSR1", 10);
|
||||
signals[12] = Signal_new("SIGSEGV", 11);
|
||||
signals[13] = Signal_new("SIGUSR2", 12);
|
||||
signals[14] = Signal_new("SIGPIPE", 13);
|
||||
signals[15] = Signal_new("SIGALRM", 14);
|
||||
signals[16] = Signal_new("SIGTERM", 15);
|
||||
signals[17] = Signal_new("SIGSTKFLT", 16);
|
||||
signals[18] = Signal_new("SIGCHLD", 17);
|
||||
signals[19] = Signal_new("SIGCONT", 18);
|
||||
signals[20] = Signal_new("SIGSTOP", 19);
|
||||
signals[21] = Signal_new("SIGTSTP", 20);
|
||||
signals[22] = Signal_new("SIGTTIN", 21);
|
||||
signals[23] = Signal_new("SIGTTOU", 22);
|
||||
signals[24] = Signal_new("SIGURG", 23);
|
||||
signals[25] = Signal_new("SIGXCPU", 24);
|
||||
signals[26] = Signal_new("SIGXFSZ", 25);
|
||||
signals[27] = Signal_new("SIGVTALRM", 26);
|
||||
signals[28] = Signal_new("SIGPROF", 27);
|
||||
signals[29] = Signal_new("SIGWINCH", 28);
|
||||
signals[30] = Signal_new("SIGIO", 29);
|
||||
signals[31] = Signal_new("SIGPOLL", 29);
|
||||
signals[32] = Signal_new("SIGPWR", 30);
|
||||
signals[33] = Signal_new("SIGSYS", 31);
|
||||
return signals;
|
||||
}
|
39
SignalItem.h
39
SignalItem.h
@ -1,39 +0,0 @@
|
||||
/* Do not edit this file. It was automatically generated. */
|
||||
|
||||
#ifndef HEADER_SignalItem
|
||||
#define HEADER_SignalItem
|
||||
/*
|
||||
htop - SignalItem.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 "String.h"
|
||||
#include "Object.h"
|
||||
#include "RichString.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define SIGNAL_COUNT 34
|
||||
|
||||
|
||||
typedef struct Signal_ {
|
||||
Object super;
|
||||
const char* name;
|
||||
int number;
|
||||
} Signal;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
extern char* SIGNAL_CLASS;
|
||||
#else
|
||||
#define SIGNAL_CLASS NULL
|
||||
#endif
|
||||
|
||||
int Signal_getSignalCount();
|
||||
|
||||
Signal** Signal_getSignalTable();
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include "SignalsPanel.h"
|
||||
#include "Panel.h"
|
||||
#include "SignalItem.h"
|
||||
#include "ListItem.h"
|
||||
#include "RichString.h"
|
||||
|
||||
#include "debug.h"
|
||||
@ -13,37 +13,14 @@
|
||||
|
||||
typedef struct SignalsPanel_ {
|
||||
Panel super;
|
||||
|
||||
int state;
|
||||
Signal** signals;
|
||||
ListItem** signals;
|
||||
} SignalsPanel;
|
||||
|
||||
}*/
|
||||
|
||||
static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) {
|
||||
SignalsPanel* this = (SignalsPanel*) super;
|
||||
|
||||
int size = Panel_size(super);
|
||||
|
||||
if (ch <= 255 && isdigit(ch)) {
|
||||
int sgn = ch-48 + this->state;
|
||||
for (int i = 0; i < size; i++)
|
||||
if (((Signal*) Panel_get(super, i))->number == sgn) {
|
||||
Panel_setSelected(super, i);
|
||||
break;
|
||||
}
|
||||
this->state = sgn * 10;
|
||||
if (this->state > 100)
|
||||
this->state = 0;
|
||||
return HANDLED;
|
||||
} else {
|
||||
this->state = 0;
|
||||
}
|
||||
if (ch == 13) {
|
||||
return BREAK_LOOP;
|
||||
}
|
||||
return IGNORED;
|
||||
}
|
||||
#ifndef SIGNAL_COUNT
|
||||
#define SIGNAL_COUNT 34
|
||||
#endif
|
||||
|
||||
static void SignalsPanel_delete(Object* object) {
|
||||
Panel* super = (Panel*) object;
|
||||
@ -53,16 +30,53 @@ static void SignalsPanel_delete(Object* object) {
|
||||
free(this);
|
||||
}
|
||||
|
||||
static ListItem** Signal_getSignalTable() {
|
||||
ListItem** signals = malloc(sizeof(ListItem*) * SIGNAL_COUNT);
|
||||
signals[0] = ListItem_new(" 0 Cancel", 0);
|
||||
signals[1] = ListItem_new(" 1 SIGHUP", 1);
|
||||
signals[2] = ListItem_new(" 2 SIGINT", 2);
|
||||
signals[3] = ListItem_new(" 3 SIGQUIT", 3);
|
||||
signals[4] = ListItem_new(" 4 SIGILL", 4);
|
||||
signals[5] = ListItem_new(" 5 SIGTRAP", 5);
|
||||
signals[6] = ListItem_new(" 6 SIGABRT", 6);
|
||||
signals[7] = ListItem_new(" 6 SIGIOT", 6);
|
||||
signals[8] = ListItem_new(" 7 SIGBUS", 7);
|
||||
signals[9] = ListItem_new(" 8 SIGFPE", 8);
|
||||
signals[10] = ListItem_new(" 9 SIGKILL", 9);
|
||||
signals[11] = ListItem_new("10 SIGUSR1", 10);
|
||||
signals[12] = ListItem_new("11 SIGSEGV", 11);
|
||||
signals[13] = ListItem_new("12 SIGUSR2", 12);
|
||||
signals[14] = ListItem_new("13 SIGPIPE", 13);
|
||||
signals[15] = ListItem_new("14 SIGALRM", 14);
|
||||
signals[16] = ListItem_new("15 SIGTERM", 15);
|
||||
signals[17] = ListItem_new("16 SIGSTKFLT", 16);
|
||||
signals[18] = ListItem_new("17 SIGCHLD", 17);
|
||||
signals[19] = ListItem_new("18 SIGCONT", 18);
|
||||
signals[20] = ListItem_new("19 SIGSTOP", 19);
|
||||
signals[21] = ListItem_new("20 SIGTSTP", 20);
|
||||
signals[22] = ListItem_new("21 SIGTTIN", 21);
|
||||
signals[23] = ListItem_new("22 SIGTTOU", 22);
|
||||
signals[24] = ListItem_new("23 SIGURG", 23);
|
||||
signals[25] = ListItem_new("24 SIGXCPU", 24);
|
||||
signals[26] = ListItem_new("25 SIGXFSZ", 25);
|
||||
signals[27] = ListItem_new("26 SIGVTALRM", 26);
|
||||
signals[28] = ListItem_new("27 SIGPROF", 27);
|
||||
signals[29] = ListItem_new("28 SIGWINCH", 28);
|
||||
signals[30] = ListItem_new("29 SIGIO", 29);
|
||||
signals[31] = ListItem_new("29 SIGPOLL", 29);
|
||||
signals[32] = ListItem_new("30 SIGPWR", 30);
|
||||
signals[33] = ListItem_new("31 SIGSYS", 31);
|
||||
return signals;
|
||||
}
|
||||
|
||||
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h) {
|
||||
SignalsPanel* this = (SignalsPanel*) malloc(sizeof(SignalsPanel));
|
||||
Panel* super = (Panel*) this;
|
||||
Panel_init(super, x, y, w, h, SIGNAL_CLASS, true);
|
||||
Panel_init(super, x, y, w, h, LISTITEM_CLASS, true);
|
||||
((Object*)this)->delete = SignalsPanel_delete;
|
||||
|
||||
this->signals = Signal_getSignalTable();
|
||||
super->eventHandler = SignalsPanel_eventHandler;
|
||||
int sigCount = Signal_getSignalCount();
|
||||
for(int i = 0; i < sigCount; i++)
|
||||
for(int i = 0; i < SIGNAL_COUNT; i++)
|
||||
Panel_set(super, i, (Object*) this->signals[i]);
|
||||
SignalsPanel_reset(this);
|
||||
return this;
|
||||
@ -73,5 +87,4 @@ void SignalsPanel_reset(SignalsPanel* this) {
|
||||
|
||||
Panel_setHeader(super, "Send signal:");
|
||||
Panel_setSelected(super, 16); // 16th item is SIGTERM
|
||||
this->state = 0;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#define HEADER_SignalsPanel
|
||||
|
||||
#include "Panel.h"
|
||||
#include "SignalItem.h"
|
||||
#include "ListItem.h"
|
||||
#include "RichString.h"
|
||||
|
||||
#include "debug.h"
|
||||
@ -15,12 +15,14 @@
|
||||
|
||||
typedef struct SignalsPanel_ {
|
||||
Panel super;
|
||||
|
||||
int state;
|
||||
Signal** signals;
|
||||
ListItem** signals;
|
||||
} SignalsPanel;
|
||||
|
||||
|
||||
#ifndef SIGNAL_COUNT
|
||||
#define SIGNAL_COUNT 34
|
||||
#endif
|
||||
|
||||
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h);
|
||||
|
||||
void SignalsPanel_reset(SignalsPanel* this);
|
||||
|
38
htop.c
38
htop.c
@ -195,15 +195,41 @@ static bool changePriority(Panel* panel, int delta) {
|
||||
}
|
||||
|
||||
static HandlerResult pickWithEnter(Panel* panel, int ch) {
|
||||
(void) panel;
|
||||
if (ch == 13)
|
||||
int size = Panel_size(panel);
|
||||
|
||||
if (isalnum(ch)) {
|
||||
int len = strlen(panel->eventHandlerBuffer);
|
||||
if (len < 99) {
|
||||
panel->eventHandlerBuffer[len] = ch;
|
||||
panel->eventHandlerBuffer[len+1] = '\0';
|
||||
}
|
||||
for (int try = 0; try < 2; try++) {
|
||||
len = strlen(panel->eventHandlerBuffer);
|
||||
for (int i = 0; i < size; i++) {
|
||||
char* cur = ((ListItem*) Panel_get(panel, i))->value;
|
||||
while (*cur == ' ') cur++;
|
||||
if (strncasecmp(cur, panel->eventHandlerBuffer, len) == 0) {
|
||||
Panel_setSelected(panel, i);
|
||||
return HANDLED;
|
||||
}
|
||||
}
|
||||
panel->eventHandlerBuffer[0] = ch;
|
||||
panel->eventHandlerBuffer[1] = '\0';
|
||||
}
|
||||
return HANDLED;
|
||||
} else if (ch != ERR) {
|
||||
panel->eventHandlerBuffer[0] = '\0';
|
||||
}
|
||||
if (ch == 13) {
|
||||
return BREAK_LOOP;
|
||||
}
|
||||
return IGNORED;
|
||||
}
|
||||
|
||||
static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, const char** keyLabels, FunctionBar* prevBar, Header* header) {
|
||||
const char* fuKeys[] = {"Enter", "Esc", NULL};
|
||||
int fuEvents[] = {13, 27};
|
||||
list->eventHandlerBuffer = calloc(100, 1);
|
||||
if (!list->eventHandler)
|
||||
Panel_setEventHandler(list, pickWithEnter);
|
||||
ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, header, false);
|
||||
@ -213,6 +239,8 @@ static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, const cha
|
||||
int ch;
|
||||
ScreenManager_run(scr, &panelFocus, &ch);
|
||||
ScreenManager_delete(scr);
|
||||
free(list->eventHandlerBuffer);
|
||||
list->eventHandlerBuffer = NULL;
|
||||
Panel_move(panel, 0, y);
|
||||
Panel_resize(panel, COLS, LINES-y-1);
|
||||
FunctionBar_draw(prevBar, NULL);
|
||||
@ -758,7 +786,7 @@ int main(int argc, char** argv) {
|
||||
const char* fuFunctions[] = {"Send ", "Cancel ", NULL};
|
||||
Signal* sgn = (Signal*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar, header);
|
||||
if (sgn) {
|
||||
if (sgn->number != 0) {
|
||||
if (sgn->super.key != 0) {
|
||||
Panel_setHeader(panel, "Sending...");
|
||||
Panel_draw(panel, true);
|
||||
refresh();
|
||||
@ -766,13 +794,13 @@ int main(int argc, char** argv) {
|
||||
for (int i = 0; i < Panel_size(panel); i++) {
|
||||
Process* p = (Process*) Panel_get(panel, i);
|
||||
if (p->tag) {
|
||||
Process_sendSignal(p, sgn->number);
|
||||
Process_sendSignal(p, sgn->super.key);
|
||||
anyTagged = true;
|
||||
}
|
||||
}
|
||||
if (!anyTagged) {
|
||||
Process* p = (Process*) Panel_getSelected(panel);
|
||||
Process_sendSignal(p, sgn->number);
|
||||
Process_sendSignal(p, sgn->super.key);
|
||||
}
|
||||
napms(500);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user