diff --git a/NEWS b/NEWS index aef210c..995e543 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,16 @@ +============ +Evisum 0.3.4 +============ + + * Offer kvm_openfiles means of obtaining PID list on + FreeBSD-based platforms. This requires specific + permissions (s+g kmem). We fallback if that fails. + * Get rid of the horrible entry-based process list and + use a genlist (meh). + * Save settings upon exit (kb/mb/gb) and sorting. + * UI Changes (Too many labels and progress bars). + * Other stuff. + ============ Evisum 0.3.2 ============ diff --git a/VERSION b/VERSION index d15723f..42045ac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.2 +0.3.4 diff --git a/meson.build b/meson.build index 05b1862..ee1a4da 100644 --- a/meson.build +++ b/meson.build @@ -12,7 +12,7 @@ host_os = host_machine.system() deps = dependency('elementary', version: efl_version) deps_os = declare_dependency(link_args : [] ) -if host_os == 'openbsd' +if host_os == 'openbsd' or host_os == 'freebsd' or host_os == 'dragonfly' deps_os = declare_dependency(link_args : [ '-lkvm' ]) endif diff --git a/src/bin/configuration.c b/src/bin/configuration.c new file mode 100644 index 0000000..b8eabb6 --- /dev/null +++ b/src/bin/configuration.c @@ -0,0 +1,70 @@ +#include "config.h" +#include "configuration.h" +#include +#include +#include + +static const char * +_config_file_path(void) +{ + const char *path = eina_slstr_printf("%s/evisum", efreet_config_home_get()); + + if (!ecore_file_exists(path)) + ecore_file_mkpath(path); + + path = eina_slstr_printf("%s/evisum/evisum.cfg", efreet_config_home_get()); + + return path; +} + +void +config_init(void) +{ + efreet_init(); +} + +void +config_shutdown(void) +{ + efreet_shutdown(); +} + +Evisum_Config * +config_load(void) +{ + Eet_File *f; + int size; + Evisum_Config *cfg = NULL; + + const char *path = _config_file_path(); + if (!ecore_file_exists(path)) + { + cfg = calloc(1, sizeof(Evisum_Config)); + cfg->version = CONFIG_VERSION; + f = eet_open(path, EET_FILE_MODE_WRITE); + eet_write(f, "Config", cfg, sizeof(Evisum_Config), 0); + eet_close(f); + } + else + { + f = eet_open(path, EET_FILE_MODE_READ); + if (!f) exit(127); + cfg = eet_read(f, "Config", &size); + eet_close(f); + } + + return cfg; +} + +Eina_Bool +config_save(Evisum_Config *cfg) +{ + Eet_File *f; + const char *path = _config_file_path(); + f = eet_open(path, EET_FILE_MODE_WRITE); + if (!f) exit(127); + eet_write(f, "Config", cfg, sizeof(Evisum_Config), 0); + eet_close(f); + + return EINA_TRUE; +} diff --git a/src/bin/configuration.h b/src/bin/configuration.h new file mode 100644 index 0000000..21e7e2c --- /dev/null +++ b/src/bin/configuration.h @@ -0,0 +1,21 @@ +#ifndef __CONFIGURATION_H__ +#define __CONFIGURATION_H__ + +#include "ui.h" + +#define CONFIG_VERSION 0x0001 + +typedef struct _Evisum_Config +{ + int version; + int sort_type; + Eina_Bool sort_reverse; + int data_unit; +} Evisum_Config; + +void config_init(void); +void config_shutdown(void); +Evisum_Config *config_load(void); +Eina_Bool config_save(Evisum_Config *); + +#endif diff --git a/src/bin/main.c b/src/bin/main.c index 689a9e1..325cc51 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -7,6 +7,7 @@ */ #include "config.h" +#include "configuration.h" #include "ui.h" static void @@ -47,6 +48,7 @@ main(int argc, char **argv) eina_init(); ecore_init(); + config_init(); elm_init(argc, argv); ui = _win_add(); @@ -57,6 +59,7 @@ main(int argc, char **argv) } elm_shutdown(); + config_shutdown(); ecore_shutdown(); eina_shutdown(); diff --git a/src/bin/meson.build b/src/bin/meson.build index 8c14247..bcb4da0 100644 --- a/src/bin/meson.build +++ b/src/bin/meson.build @@ -1,6 +1,8 @@ inc = include_directories('.', '../..') executable('evisum', [ + 'configuration.c', + 'configuration.h', 'disks.c', 'disks.h', 'process.c', diff --git a/src/bin/process.c b/src/bin/process.c index 6039754..86742a5 100644 --- a/src/bin/process.c +++ b/src/bin/process.c @@ -9,7 +9,9 @@ # include #endif -#if defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) +# include +# include # include # include # include @@ -34,6 +36,10 @@ #include #include +#if defined(__linux__) && !defined(PF_KTHREAD) +# define PF_KTHREAD 0x00200000 +#endif + static const char * _process_state_name(char state) { @@ -142,7 +148,7 @@ _process_list_linux_get(void) FILE *f; char *name, *link, state, line[4096], program_name[1024]; int pid, res, utime, stime, cutime, cstime, uid, psr, pri, nice, numthreads; - unsigned int mem_size, mem_rss; + unsigned int mem_size, mem_rss, flags; int pagesize = getpagesize(); list = NULL; @@ -165,9 +171,8 @@ _process_list_linux_get(void) end = strchr(line, ')'); strncpy(program_name, start, end - start); program_name[end - start] = '\0'; - res = sscanf(end + 2, "%c %d %d %d %d %d %u %u %u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d %d %d %d %u %d %d %d %d %d %d %d %d %d", - &state, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &utime, &stime, &cutime, &cstime, + &state, &dummy, &dummy, &dummy, &dummy, &dummy, &flags, &dummy, &dummy, &dummy, &dummy, &utime, &stime, &cutime, &cstime, &pri, &nice, &numthreads, &dummy, &dummy, &mem_size, &mem_rss, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &psr, &dummy, &dummy, &dummy, &dummy, &dummy); } @@ -176,6 +181,8 @@ _process_list_linux_get(void) if (res != 42) continue; + if (flags & PF_KTHREAD) continue; + f = fopen(eina_slstr_printf("/proc/%d/status", pid), "r"); if (!f) continue; @@ -210,6 +217,9 @@ _process_list_linux_get(void) } } + + char *end = strchr(program_name, ' '); + if (end) *end = '\0'; Proc_Stats *p = calloc(1, sizeof(Proc_Stats)); if (!p) return NULL; @@ -489,7 +499,7 @@ proc_info_by_pid(int pid) #if defined(__FreeBSD__) || defined(__DragonFly__) static Eina_List * -_process_list_freebsd_get(void) +_process_list_freebsd_fallback_get(void) { Eina_List *list; struct rusage *usage; @@ -546,6 +556,36 @@ _process_list_freebsd_get(void) return list; } +static Eina_List * +_process_list_freebsd_get(void) +{ + kvm_t *kern; + Eina_List *list = NULL; + struct kinfo_proc *kp; + char errbuf[_POSIX2_LINE_MAX]; + int pid_count; + + kern = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); + if (!kern) + return _process_list_freebsd_fallback_get(); + + kp = kvm_getprocs(kern, KERN_PROC_PROC, 0, &pid_count); + if (!kp) return _process_list_freebsd_fallback_get(); + + for (int i = 0; i < pid_count; i++) + { + if (kp[i].ki_flag & P_KPROC) + continue; + + Proc_Stats *p = proc_info_by_pid(kp[i].ki_pid); + if (!p) continue; + + list = eina_list_append(list, p); + } + + return list; +} + Proc_Stats * proc_info_by_pid(int pid) { diff --git a/src/bin/system.c b/src/bin/system.c index b7c6d0b..2352b63 100644 --- a/src/bin/system.c +++ b/src/bin/system.c @@ -38,7 +38,11 @@ #include #include #include -#include +#if defined(__linux__) +# define BORING_USER 1 +#else +# include +#endif #include #include #include @@ -1271,14 +1275,16 @@ _network_transfer_get_thread_cb(void *arg) return (void *)0; } -void -system_stats_get(results_t *results) +results_t * +system_stats_get(void) { + results_t *results; void *ret; pthread_t tid; int error; - memset(results, 0, sizeof(results_t)); + results = calloc(1, sizeof(results_t)); + if (!results) return NULL; results->cores = _cpu_cores_state_get(&results->cpu_count); @@ -1298,5 +1304,7 @@ system_stats_get(results_t *results) ret = NULL; pthread_join(tid, ret); } + + return results; } diff --git a/src/bin/system.h b/src/bin/system.h index eca6e6a..545eb94 100644 --- a/src/bin/system.h +++ b/src/bin/system.h @@ -61,8 +61,8 @@ struct results_t int temperature; }; -void - system_stats_get(results_t *results); +results_t * + system_stats_get(void); int system_cpu_memory_get(double *percent_cpu, long *memory_total, long *memory_used); diff --git a/src/bin/ui.c b/src/bin/ui.c index 54f916c..3699b90 100644 --- a/src/bin/ui.c +++ b/src/bin/ui.c @@ -1,8 +1,9 @@ #include "config.h" +#include "configuration.h" +#include "ui.h" #include "system.h" #include "process.h" #include "disks.h" -#include "ui.h" #include #include #include @@ -11,21 +12,34 @@ # define __MacOS__ #endif +static Ui *_ui = NULL; static Eina_Lock _lock; +static Eina_List *_list = NULL; +static Evisum_Config *_configuration = NULL; + +static void +_config_save(Ui *ui) +{ + if (!_configuration) return; + + _configuration->sort_type = ui->sort_type; + _configuration->sort_reverse = ui->sort_reverse; + _configuration->data_unit = ui->data_unit; + + config_save(_configuration); +} static void _system_stats(void *data, Ecore_Thread *thread) { Ui *ui = data; - while (EINA_TRUE) + while (1) { - results_t *results = malloc(sizeof(results_t)); - if (results) - { - system_stats_get(results); - ecore_thread_feedback(thread, results); - } + results_t *results = system_stats_get(); + if (!results) ui_shutdown(ui); + + ecore_thread_feedback(thread, results); for (int i = 0; i < 4; i++) { @@ -125,7 +139,7 @@ _tab_misc_update(Ui *ui, results_t *results) evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(frame); - + Eina_Strbuf *buf = eina_strbuf_new(); if (buf) { @@ -345,7 +359,7 @@ _tab_memory_update(Ui *ui, results_t *results) static void _tab_cpu_update(Ui *ui, results_t *results) { - Evas_Object *box, *frame, *progress; + Evas_Object *box, *frame, *label, *progress; if (!ui->cpu_visible) return; @@ -359,15 +373,32 @@ _tab_cpu_update(Ui *ui, results_t *results) for (int i = 0; i < results->cpu_count; i++) { + if (i == 0) + { + frame = elm_frame_add(box); + evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); + evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(frame); + elm_object_style_set(frame, "pad_small"); + + label = elm_label_add(box); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, 0); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(label); + + if (results->temperature != INVALID_TEMP) + elm_object_text_set(label, eina_slstr_printf("CPUs
Total of %d CPUs
Core at (%d °C)
", results->cpu_count, results->temperature)); + else + elm_object_text_set(label, eina_slstr_printf("CPUs
Total of %d CPUs", results->cpu_count)); + elm_box_pack_end(box, frame); + elm_box_pack_end(box, label); + } + frame = elm_frame_add(box); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(frame); - - if (i == 0 && results->temperature != INVALID_TEMP) - elm_object_text_set(frame, eina_slstr_printf("CPU %d (%d °C)", i, results->temperature)); - else - elm_object_text_set(frame, eina_slstr_printf("CPU %d", i)); + elm_object_style_set(frame, "pad_large"); progress = elm_progressbar_add(frame); evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL); @@ -563,112 +594,6 @@ _sort_by_state(const void *p1, const void *p2) return strcmp(inf1->state, inf2->state); } -static void -_entry_cmd_size_set(Ui *ui) -{ - static Evas_Coord winw = 0, winh = 0; - Evas_Coord w, h, ww, wh, ow; - - evas_object_geometry_get(ui->btn_cmd, NULL, NULL, &ow, &h); - evas_object_geometry_get(ui->entry_cmd, NULL, NULL, &w, NULL); - evas_object_geometry_get(ui->win, NULL, NULL, &ww, &wh); - - if (!winw && !winh) - { - winw = ww; winh = wh; - } - - if (winw == ww && winh == wh) - { - if (ow != w) - { - evas_object_size_hint_min_set(ui->btn_cmd, w, h); - evas_object_size_hint_min_set(ui->btn_expand, w, h); - } - } -} - -static void -_text_fields_init(Ui *ui) -{ - for (int i = 0; i < PROCESS_INFO_FIELDS; i++) - { - ui->text_fields[i] = malloc(TEXT_FIELD_MAX * sizeof(char)); - ui->text_fields[i][0] = '\0'; - } -} - -static void -_text_fields_append(Ui *ui, Proc_Stats *proc) -{ - int64_t mem_size, mem_rss; - - if (ui->program_pid == proc->pid) - return; - - ui->searching = EINA_FALSE; - - if (ui->search_text && ui->search_text[0]) - { - ui->searching = EINA_TRUE; - if (strncasecmp(proc->command, ui->search_text, strlen(ui->search_text))) - return; - } - - mem_size = proc->mem_size; - mem_rss = proc->mem_rss; - - if (ui->data_unit == DATA_UNIT_KB) - { - mem_size >>= 10; - mem_rss >>= 10; - } - else if (ui->data_unit == DATA_UNIT_MB) - { - mem_size >>= 20; - mem_rss >>= 20; - } - else - { - mem_size >>= 30; - mem_rss >>= 30; - } - - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_PID], eina_slstr_printf("%d
", proc->pid), TEXT_FIELD_MAX); - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_UID], eina_slstr_printf("%d
", proc->uid), TEXT_FIELD_MAX); - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_SIZE], eina_slstr_printf("%lld%c
", mem_size, ui->data_unit), TEXT_FIELD_MAX); - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_RSS], eina_slstr_printf("%lld%c
", mem_rss, ui->data_unit), TEXT_FIELD_MAX); - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_COMMAND], eina_slstr_printf("%s
", proc->command), TEXT_FIELD_MAX); - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_STATE], eina_slstr_printf("%s
", proc->state), TEXT_FIELD_MAX); - eina_strlcat(ui->text_fields[PROCESS_INFO_FIELD_CPU_USAGE], eina_slstr_printf("%.1f%%
", proc->cpu_usage), TEXT_FIELD_MAX); -} - -static void -_text_fields_show(Ui *ui) -{ - elm_object_text_set(ui->entry_pid, ui->text_fields[PROCESS_INFO_FIELD_PID]); - elm_object_text_set(ui->entry_uid, ui->text_fields[PROCESS_INFO_FIELD_UID]); - elm_object_text_set(ui->entry_size, ui->text_fields[PROCESS_INFO_FIELD_SIZE]); - elm_object_text_set(ui->entry_rss, ui->text_fields[PROCESS_INFO_FIELD_RSS]); - elm_object_text_set(ui->entry_cmd, ui->text_fields[PROCESS_INFO_FIELD_COMMAND]); - elm_object_text_set(ui->entry_state, ui->text_fields[PROCESS_INFO_FIELD_STATE]); - elm_object_text_set(ui->entry_cpu_usage, ui->text_fields[PROCESS_INFO_FIELD_CPU_USAGE]); -} - -static void -_text_fields_clear(Ui *ui) -{ - for (int i = 0; i < PROCESS_INFO_FIELDS; i++) - ui->text_fields[i][0] = '\0'; -} - -static void -_text_fields_free(Ui *ui) -{ - for (int i = 0; i < PROCESS_INFO_FIELDS; i++) - free(ui->text_fields[i]); -} - static Eina_List * _list_sort(Ui *ui, Eina_List *list) { @@ -792,40 +717,311 @@ _proc_pid_cpu_usage_get(Ui *ui, Proc_Stats *proc) _proc_pid_cpu_time_save(ui, proc); } +static void +_item_del(void *data, Evas_Object *obj EINA_UNUSED) +{ + Proc_Stats *proc = data; + free(proc); +} + +static void +_column_expand_init(Ui *ui) +{ + ui->long_pid = strdup(""); + ui->long_uid = strdup(""); + ui->long_size = strdup(""); + ui->long_rss = strdup(""); + ui->long_cmd = strdup(""); + ui->long_state = strdup(""); + ui->long_cpu = strdup(""); +} + +static void +_column_expand_calculate(Ui *ui, Proc_Stats *proc) +{ + const char *text; + + text = eina_slstr_printf("%d", proc->pid); + if (strlen(text) > strlen(ui->long_pid)) + { + if (ui->long_pid) free(ui->long_pid); + ui->long_pid = strdup(text); + } + + text = eina_slstr_printf("%d", proc->uid); + if (strlen(text) > strlen(ui->long_uid)) + { + if (ui->long_uid) free(ui->long_uid); + ui->long_uid = strdup(text); + } + + text = eina_slstr_printf("%lu %c ", _mem_adjust(ui->data_unit, proc->mem_size >> 10), ui->data_unit); + if (strlen(text) > strlen(ui->long_size)) + { + if (ui->long_size) free(ui->long_size); + ui->long_size = strdup(text); + } + + text = eina_slstr_printf("%lu %c ", _mem_adjust(ui->data_unit, proc->mem_rss >> 10), ui->data_unit); + if (strlen(text) > strlen(ui->long_rss)) + { + if (ui->long_rss) free(ui->long_rss); + ui->long_rss = strdup(text); + } + + text = eina_slstr_printf("%sXXX", proc->command); + if (strlen(text) > strlen(ui->long_cmd)) + { + if (ui->long_cmd) free(ui->long_cmd); + ui->long_cmd = strdup(text); + } + + text = eina_slstr_printf("%s", proc->state); + if (strlen(text) > strlen(ui->long_state)) + { + if (ui->long_state) free(ui->long_state); + ui->long_state = strdup(text); + } + + text = eina_slstr_printf("%.1f%%", proc->cpu_usage); + if (strlen(text) > strlen(ui->long_cpu)) + { + if (ui->long_cpu) free(ui->long_cpu); + ui->long_cpu = strdup(text); + } +} + +static Evas_Object * +_column_expand(Evas_Object *parent, const char *text) +{ + Evas_Object *label; + + label = elm_label_add(parent); + elm_object_text_set(label, text); + evas_object_size_hint_align_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + + return label; +} + +static Evas_Object * +_content_get(void *data, Evas_Object *obj, const char *source) +{ + Ui *ui; + Evas_Object *box, *label; + Evas_Object *table, *rect; + Evas_Coord w, h; + Proc_Stats *proc = (void *) data; + + if (strcmp(source, "elm.swallow.content")) return NULL; + if (!proc) return NULL; + + ui = _ui; + + if (!ui->ready) return NULL; + + box = elm_box_add(obj); + elm_box_horizontal_set(box, EINA_TRUE); + evas_object_size_hint_align_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(box); + + table = elm_table_add(obj); + evas_object_size_hint_align_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(table); + + label = elm_label_add(obj); + if (ui->sort_type == SORT_BY_PID) + elm_object_text_set(label, eina_slstr_printf("%d", proc->pid)); + else + elm_object_text_set(label, eina_slstr_printf("%d", proc->pid)); + evas_object_size_hint_align_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(label); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_pid, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 0, 0, 1, 1); + elm_table_pack(table, label, 0, 0, 1, 1); + elm_table_pack(table, _column_expand(table, ui->long_pid), 0, 0, 1, 1); + + label = elm_label_add(table); + if (ui->sort_type == SORT_BY_UID) + elm_object_text_set(label, eina_slstr_printf("%d", proc->uid)); + else + elm_object_text_set(label, eina_slstr_printf("%d", proc->uid)); + evas_object_size_hint_align_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_table_pack(table, label, 1, 0, 1, 1); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_uid, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 1, 0, 1, 1); + elm_table_pack(table, _column_expand(table, ui->long_uid), 1, 0, 1, 1); + evas_object_show(label); + + label = elm_label_add(table); + if (ui->sort_type == SORT_BY_SIZE) + elm_object_text_set(label, eina_slstr_printf("%lu %c", _mem_adjust(ui->data_unit, proc->mem_size >> 10), ui->data_unit)); + else + elm_object_text_set(label, eina_slstr_printf("%lu %c ", _mem_adjust(ui->data_unit, proc->mem_size >> 10), ui->data_unit)); + evas_object_size_hint_align_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(label); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_size, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 2, 0, 1, 1); + evas_object_show(label); + elm_table_pack(table, label, 2, 0, 1, 1); + elm_table_pack(table, _column_expand(table, ui->long_size), 2, 0, 1, 1); + + label = elm_label_add(table); + if (ui->sort_type == SORT_BY_RSS) + elm_object_text_set(label, eina_slstr_printf("%lu %c", _mem_adjust(ui->data_unit, proc->mem_rss >> 10), ui->data_unit)); + else + elm_object_text_set(label, eina_slstr_printf("%lu %c ", _mem_adjust(ui->data_unit, proc->mem_rss >> 10), ui->data_unit)); + + evas_object_size_hint_align_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(label); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_rss, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 3, 0, 1, 1); + elm_table_pack(table, label, 3, 0, 1, 1); + elm_table_pack(table, _column_expand(table,ui->long_rss), 3, 0, 1, 1); + + label = elm_label_add(table); + if (ui->sort_type == SORT_BY_CMD) + elm_object_text_set(label, eina_slstr_printf("%s", proc->command)); + else + elm_object_text_set(label, eina_slstr_printf("%s", proc->command)); + evas_object_size_hint_align_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_cmd, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 4, 0, 1, 1); + evas_object_show(label); + elm_table_pack(table, label, 4, 0, 1, 1); + elm_table_pack(table, _column_expand(table,ui->long_cmd), 4, 0, 1, 1); + + label = elm_label_add(table); + if (ui->sort_type == SORT_BY_STATE) + elm_object_text_set(label, eina_slstr_printf("%s", proc->state)); + else + elm_object_text_set(label, eina_slstr_printf("%s", proc->state)); + evas_object_size_hint_align_set(label, 0.5, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(label); + elm_table_pack(table, label, 5, 0, 1, 1); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_state, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 5, 0, 1, 1); + elm_table_pack(table, _column_expand(table, ui->long_state), 5, 0, 1, 1); + + label = elm_label_add(table); + if (ui->sort_type == SORT_BY_CPU_USAGE) + elm_object_text_set(label, eina_slstr_printf("%.1f%%", proc->cpu_usage)); + else + elm_object_text_set(label, eina_slstr_printf("%.1f%%", proc->cpu_usage)); + evas_object_size_hint_align_set(label, 0.5, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(label); + elm_table_pack(table, label, 6, 0, 1, 1); + rect = evas_object_rectangle_add(table); + evas_object_geometry_get(ui->btn_cpu, NULL, NULL, &w, &h); + evas_object_size_hint_min_set(rect, w, 1); + elm_table_pack(table, rect, 6, 0, 1, 1); + elm_table_pack(table, _column_expand(table, ui->long_cpu), 6, 0, 1, 1); + + return table; +} + +static void +_genlist_ensure_n_items(Evas_Object *genlist, unsigned int items) +{ + Elm_Object_Item *it; + Elm_Genlist_Item_Class *itc; + unsigned int i, existing = elm_genlist_items_count(genlist); + + if (items < existing) + { + for (i = existing - items; i > 0; i--) + { + it = elm_genlist_last_item_get(genlist); + if (it) + { + elm_object_item_del(it); + } + } + } + + if (items == existing) return; + + itc = elm_genlist_item_class_new(); + itc->item_style = "full"; + itc->func.text_get = NULL; + itc->func.content_get = _content_get; + itc->func.filter_get = NULL; + itc->func.del = _item_del; + + for (i = existing; i < items; i++) + { + elm_genlist_item_append(genlist, itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + } + + elm_genlist_item_class_free(itc); +} + static void _process_list_feedback_cb(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg EINA_UNUSED) { Ui *ui; - Eina_List *list, *l; + Eina_List *list, *l, *l_next; Proc_Stats *proc; - - eina_lock_take(&_lock); + Elm_Object_Item *it; ui = data; + eina_lock_take(&_lock); + list = proc_info_all_get(); - EINA_LIST_FOREACH(list, l, proc) + EINA_LIST_FOREACH_SAFE(list, l, l_next, proc) { - _proc_pid_cpu_usage_get(ui, proc); + if ((ui->search_text && ui->search_text[0] && + strncasecmp(proc->command, ui->search_text, strlen(ui->search_text))) || + (!ui->show_self && proc->pid == ui->program_pid)) + { + free(proc); + list = eina_list_remove_list(list, l); + } + else + { + _proc_pid_cpu_usage_get(ui, proc); + _column_expand_calculate(ui, proc); + } } - list = _list_sort(ui, list); + _genlist_ensure_n_items(ui->genlist_procs, eina_list_count(list)); + it = elm_genlist_first_item_get(ui->genlist_procs); + + list = _list = _list_sort(ui, list); EINA_LIST_FREE(list, proc) { - _text_fields_append(ui, proc); - free(proc); + elm_object_item_data_set(it, proc); + it = elm_genlist_item_next_get(it); } + elm_genlist_realized_items_update(ui->genlist_procs); if (list) eina_list_free(list); - _text_fields_show(ui); - _text_fields_clear(ui); - - _entry_cmd_size_set(ui); - eina_lock_release(&_lock); } @@ -840,7 +1036,7 @@ _process_list(void *data, Ecore_Thread *thread) { Ui *ui = data; - while (EINA_TRUE) + while (1) { ecore_thread_feedback(thread, ui); for (int i = 0; i < ui->poll_delay * 4; i++) @@ -854,6 +1050,7 @@ _process_list(void *data, Ecore_Thread *thread) } usleep(250000); } + ui->ready = EINA_TRUE; } } @@ -896,9 +1093,8 @@ _btn_pid_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info E ui->sort_type = SORT_BY_PID; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -913,9 +1109,8 @@ _btn_uid_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info E ui->sort_type = SORT_BY_UID; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -930,9 +1125,8 @@ _btn_cpu_usage_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_ ui->sort_type = SORT_BY_CPU_USAGE; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -947,9 +1141,8 @@ _btn_size_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info ui->sort_type = SORT_BY_SIZE; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -964,9 +1157,8 @@ _btn_rss_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info E ui->sort_type = SORT_BY_RSS; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -981,9 +1173,8 @@ _btn_cmd_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info E ui->sort_type = SORT_BY_CMD; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -998,9 +1189,8 @@ _btn_state_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info ui->sort_type = SORT_BY_STATE; + _config_save(ui); _process_list_update(ui); - - elm_scroller_page_bring_in(ui->scroller, 0, 0); } static void @@ -1188,47 +1378,21 @@ _btn_kill_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info } static void -_entry_pid_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +_item_pid_clicked_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Ui *ui; - Evas_Object *textblock; - Evas_Textblock_Cursor *pos; - const char *text; - char *pid_text, *start, *end; + Evas_Event_Mouse_Up *ev; + Elm_Object_Item *it; + Proc_Stats *proc; ui = data; - textblock = elm_entry_textblock_get(obj); - if (!textblock) - return; - - pos = evas_object_textblock_cursor_get(textblock); - if (!pos) - return; - - text = evas_textblock_cursor_paragraph_text_get(pos); - if (!text || !text[0]) - return; - - pid_text = strdup(text); - - start = strchr(pid_text, '>') + 1; - if (start) - { - end = strchr(start, '<'); - if (end) - *end = '\0'; - } - else - { - free(pid_text); - return; - } - - ui->selected_pid = atol(start); - - free(pid_text); + ev = event_info; + it = elm_genlist_at_xy_item_get(obj, ev->output.x, ev->output.y, NULL); + proc = elm_object_item_data_get(it); + if (!proc) return; + ui->selected_pid = proc->pid; _process_panel_update(ui); if (ui->timer_pid) @@ -1247,8 +1411,8 @@ static void _ui_tab_system_add(Ui *ui) { Evas_Object *parent, *box, *hbox, *frame, *table; - Evas_Object *progress, *button, *entry; - Evas_Object *scroller; + Evas_Object *progress, *button; + Evas_Object *scroller, *plist; parent = ui->content; @@ -1301,7 +1465,14 @@ _ui_tab_system_add(Ui *ui) elm_box_pack_end(box, table); ui->btn_pid = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_PID) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "PID"); @@ -1309,7 +1480,14 @@ _ui_tab_system_add(Ui *ui) elm_table_pack(table, button, 0, 0, 1, 1); ui->btn_uid = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_UID) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "UID"); @@ -1317,7 +1495,14 @@ _ui_tab_system_add(Ui *ui) elm_table_pack(table, button, 1, 0, 1, 1); ui->btn_size = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_SIZE) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "Size"); @@ -1325,7 +1510,14 @@ _ui_tab_system_add(Ui *ui) elm_table_pack(table, button, 2, 0, 1, 1); ui->btn_rss = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_RSS) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "Res"); @@ -1333,7 +1525,14 @@ _ui_tab_system_add(Ui *ui) elm_table_pack(table, button, 3, 0, 1, 1); ui->btn_cmd = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_CMD) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "Command"); @@ -1341,7 +1540,14 @@ _ui_tab_system_add(Ui *ui) elm_table_pack(table, button, 4, 0, 1, 1); ui->btn_state = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_STATE) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "State"); @@ -1349,7 +1555,14 @@ _ui_tab_system_add(Ui *ui) elm_table_pack(table, button, 5, 0, 1, 1); ui->btn_cpu_usage = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); + if (ui->sort_type == SORT_BY_CPU_USAGE) + { + _btn_icon_state_set(button, ui->sort_reverse); + elm_object_focus_set(button, EINA_TRUE); + } + else + _btn_icon_state_set(button, EINA_FALSE); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(button, "CPU %"); @@ -1364,154 +1577,27 @@ _ui_tab_system_add(Ui *ui) ui->scroller = scroller = elm_scroller_add(parent); evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON); + elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); elm_scroller_content_min_limit(scroller, EINA_TRUE, EINA_FALSE); elm_scroller_wheel_disabled_set(scroller, EINA_FALSE); evas_object_show(scroller); elm_object_content_set(scroller, table); + ui->genlist_procs = plist = elm_genlist_add(parent); + elm_object_focus_allow_set(plist, EINA_FALSE); + elm_genlist_homogeneous_set(plist, EINA_TRUE); + elm_genlist_select_mode_set(plist, ELM_OBJECT_SELECT_MODE_NONE); + evas_object_size_hint_weight_set(plist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(plist, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(plist); + frame = elm_frame_add(box); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_style_set(frame, "pad_small"); elm_box_pack_end(box, frame); evas_object_show(frame); - elm_object_content_set(frame, scroller); - - button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "PID"); - elm_table_pack(table, button, 0, 0, 1, 1); - - ui->entry_pid = entry = elm_entry_add(parent); - elm_entry_text_style_user_push(entry, "DEFAULT='align=center'"); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_entry_scrollable_set(entry, EINA_FALSE); - elm_entry_editable_set(entry, EINA_FALSE); - elm_entry_select_allow_set(entry, EINA_FALSE); - evas_object_show(entry); - elm_table_pack(table, entry, 0, 0, 1, 1); - - button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "UID"); - elm_table_pack(table, button, 1, 0, 1, 1); - - ui->entry_uid = entry = elm_entry_add(parent); - elm_entry_text_style_user_push(entry, "DEFAULT='align=center'"); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - elm_entry_select_allow_set(entry, EINA_FALSE); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_entry_editable_set(entry, EINA_FALSE); - evas_object_show(entry); - elm_table_pack(table, entry, 1, 0, 1, 1); - - button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "Size"); - elm_table_pack(table, button, 2, 0, 1, 1); - - ui->entry_size = entry = elm_entry_add(parent); - elm_entry_text_style_user_push(entry, "DEFAULT='align=right'"); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_entry_scrollable_set(entry, EINA_FALSE); - elm_entry_editable_set(entry, EINA_FALSE); - elm_entry_select_allow_set(entry, EINA_FALSE); - evas_object_show(entry); - elm_table_pack(table, entry, 2, 0, 1, 1); - - button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "Res"); - elm_table_pack(table, button, 3, 0, 1, 1); - - ui->entry_rss = entry = elm_entry_add(parent); - elm_entry_text_style_user_push(entry, "DEFAULT='align=right'"); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_entry_scrollable_set(entry, EINA_FALSE); - elm_entry_editable_set(entry, EINA_FALSE); - elm_entry_select_allow_set(entry, EINA_FALSE); - evas_object_show(entry); - elm_table_pack(table, entry, 3, 0, 1, 1); - - ui->btn_expand = button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "Command"); - elm_table_pack(table, button, 4, 0, 1, 1); - - ui->entry_cmd = entry = elm_entry_add(parent); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - elm_entry_scrollable_set(entry, EINA_FALSE); - elm_entry_editable_set(entry, EINA_FALSE); - elm_entry_select_allow_set(entry, EINA_FALSE); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(entry); - elm_table_pack(table, entry, 4, 0, 1, 1); - - button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "State"); - elm_table_pack(table, button, 5, 0, 1, 1); - - ui->entry_state = entry = elm_entry_add(parent); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - elm_entry_text_style_user_push(entry, "DEFAULT='align=center'"); - elm_entry_select_allow_set(entry, EINA_FALSE); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_entry_single_line_set(entry, EINA_TRUE); - elm_entry_scrollable_set(entry, EINA_FALSE); - elm_entry_editable_set(entry, EINA_FALSE); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - evas_object_show(entry); - elm_table_pack(table, entry, 5, 0, 1, 1); - - button = elm_button_add(parent); - _btn_icon_state_set(button, EINA_FALSE); - evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(button, "CPU %"); - elm_table_pack(table, button, 6, 0, 1, 1); - - ui->entry_cpu_usage = entry = elm_entry_add(parent); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - elm_entry_text_style_user_push(entry, "DEFAULT='align=center'"); - evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_entry_single_line_set(entry, EINA_TRUE); - elm_entry_scrollable_set(entry, EINA_FALSE); - elm_entry_editable_set(entry, EINA_FALSE); - elm_entry_select_allow_set(entry, EINA_FALSE); - elm_entry_line_wrap_set(entry, ELM_WRAP_NONE); - evas_object_show(entry); - elm_table_pack(table, entry, 6, 0, 1, 1); - - hbox = elm_box_add(parent); - evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, 0); - evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_box_horizontal_set(hbox, EINA_TRUE); - evas_object_show(hbox); - elm_box_pack_end(box, hbox); + elm_object_content_set(frame, plist); evas_object_smart_callback_add(ui->btn_pid, "clicked", _btn_pid_clicked_cb, ui); evas_object_smart_callback_add(ui->btn_uid, "clicked", _btn_uid_clicked_cb, ui); @@ -1520,7 +1606,7 @@ _ui_tab_system_add(Ui *ui) evas_object_smart_callback_add(ui->btn_cmd, "clicked", _btn_cmd_clicked_cb, ui); evas_object_smart_callback_add(ui->btn_state, "clicked", _btn_state_clicked_cb, ui); evas_object_smart_callback_add(ui->btn_cpu_usage, "clicked", _btn_cpu_usage_clicked_cb, ui); - evas_object_smart_callback_add(ui->entry_pid, "clicked", _entry_pid_clicked_cb, ui); + evas_object_event_callback_add(ui->genlist_procs, EVAS_CALLBACK_MOUSE_UP, _item_pid_clicked_cb, ui); } static void @@ -1842,7 +1928,7 @@ _ui_tab_disk_add(Ui *ui) frame = elm_frame_add(box); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(frame, "Storage Overview"); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); scroller = elm_scroller_add(parent); @@ -1875,9 +1961,9 @@ _ui_tab_misc_add(Ui *ui) evas_object_show(hbox); frame = elm_frame_add(box); + elm_object_style_set(frame, "pad_small"); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(frame, "Misc"); evas_object_show(frame); scroller = elm_scroller_add(parent); @@ -1912,7 +1998,7 @@ _ui_tab_cpu_add(Ui *ui) frame = elm_frame_add(box); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(frame, "Processor Overview"); + elm_object_style_set(frame, "outdent_bottom"); evas_object_show(frame); scroller = elm_scroller_add(parent); @@ -1926,10 +2012,23 @@ _ui_tab_cpu_add(Ui *ui) elm_box_pack_end(box, frame); } +static Evas_Object * +_label(Evas_Object *parent, const char *text) +{ + Evas_Object *label = elm_label_add(parent); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(label, eina_slstr_printf("%s",text)); + evas_object_show(label); + + return label; +} + static void _ui_tab_memory_add(Ui *ui) { Evas_Object *parent, *box, *hbox, *frame, *progress, *scroller; + Evas_Object *label; parent = ui->content; @@ -1947,7 +2046,7 @@ _ui_tab_memory_add(Ui *ui) frame = elm_frame_add(box); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_text_set(frame, "Memory Overview"); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); scroller = elm_scroller_add(parent); @@ -1967,7 +2066,38 @@ _ui_tab_memory_add(Ui *ui) frame = elm_frame_add(box); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_text_set(frame, "Memory Used"); + evas_object_show(frame); + elm_object_style_set(frame, "pad_small"); + elm_box_pack_end(box, frame); + + label = elm_label_add(parent); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(label, "Memory"); + evas_object_show(label); + elm_box_pack_end(box, label); + + frame = elm_frame_add(box); + evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); + evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_style_set(frame, "pad_small"); + evas_object_show(frame); + elm_box_pack_end(box, frame); + + frame = elm_frame_add(box); + evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); + evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_style_set(frame, "pad_small"); + evas_object_show(frame); + elm_box_pack_end(box, frame); + + label = _label(box, "Used"); + elm_box_pack_end(box, label); + + frame = elm_frame_add(box); + evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); + evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); ui->progress_mem_used = progress = elm_progressbar_add(frame); @@ -1978,10 +2108,13 @@ _ui_tab_memory_add(Ui *ui) elm_object_content_set(frame, progress); elm_box_pack_end(box, frame); + label = _label(box, "Cached"); + elm_box_pack_end(box, label); + frame = elm_frame_add(box); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_text_set(frame, "Memory Cached"); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); ui->progress_mem_cached = progress = elm_progressbar_add(frame); @@ -1992,10 +2125,13 @@ _ui_tab_memory_add(Ui *ui) elm_object_content_set(frame, progress); elm_box_pack_end(box, frame); + label = _label(box, "Buffered"); + elm_box_pack_end(box, label); + frame = elm_frame_add(box); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_text_set(frame, "Memory Buffered"); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); ui->progress_mem_buffered = progress = elm_progressbar_add(frame); @@ -2006,10 +2142,13 @@ _ui_tab_memory_add(Ui *ui) elm_object_content_set(frame, progress); elm_box_pack_end(box, frame); + label = _label(box, "Shared"); + elm_box_pack_end(box, label); + frame = elm_frame_add(box); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_text_set(frame, "Memory Shared"); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); ui->progress_mem_shared = progress = elm_progressbar_add(frame); @@ -2019,10 +2158,13 @@ _ui_tab_memory_add(Ui *ui) elm_object_content_set(frame, progress); elm_box_pack_end(box, frame); + label = _label(box, "Swapped"); + elm_box_pack_end(box, label); + frame = elm_frame_add(box); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_text_set(frame, "Memory Swapped"); + elm_object_style_set(frame, "pad_small"); evas_object_show(frame); ui->progress_mem_swap = progress = elm_progressbar_add(frame); @@ -2391,6 +2533,20 @@ _evisum_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) ui->data_unit = DATA_UNIT_MB; else if ((ev->keyname[0] == 'G' || ev->keyname[0] == 'g')) ui->data_unit = DATA_UNIT_GB; + + if (ev->keyname[0] == 'e' || ev->keyname[0] == 'E') + ui->show_self = !ui->show_self; + + _config_save(ui); +} + +static void +_evisum_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Ui *ui = data; + + elm_genlist_clear(ui->genlist_procs); + _process_panel_update(ui); } void @@ -2412,7 +2568,6 @@ ui_shutdown(Ui *ui) if (ui->thread_process) ecore_thread_wait(ui->thread_process, 1.0); - _text_fields_free(ui); _proc_pid_cpu_times_free(ui); eina_lock_free(&_lock); @@ -2423,8 +2578,8 @@ ui_shutdown(Ui *ui) static void _ui_launch(Ui *ui) { - _process_list_update(ui); _process_panel_update(ui); + _process_list_update(ui); ui->thread_system = ecore_thread_feedback_run(_system_stats, _system_stats_feedback_cb, _thread_end_cb, _thread_error_cb, ui, @@ -2434,12 +2589,9 @@ _ui_launch(Ui *ui) _thread_end_cb, _thread_error_cb, ui, EINA_FALSE); + evas_object_event_callback_add(ui->win, EVAS_CALLBACK_RESIZE, _evisum_resize_cb, ui); evas_object_event_callback_add(ui->content, EVAS_CALLBACK_KEY_DOWN, _evisum_key_down_cb, ui); evas_object_event_callback_add(ui->entry_search, EVAS_CALLBACK_KEY_DOWN, _evisum_search_keypress_cb, ui); - - /* Final UI actions post create. */ - - elm_object_focus_set(ui->entry_search, EINA_TRUE); } static Ui * @@ -2458,10 +2610,13 @@ _ui_init(Evas_Object *parent) ui->panel_visible = ui->disk_visible = ui->cpu_visible = ui->mem_visible = ui->misc_visible = EINA_TRUE; ui->data_unit = DATA_UNIT_MB; - _text_fields_init(ui); - ui->cpu_times = NULL; + _configuration = config_load(); + ui->sort_type = _configuration->sort_type; + ui->sort_reverse = _configuration->sort_reverse; + ui->data_unit = _configuration->data_unit == 0 ? DATA_UNIT_MB : _configuration->data_unit; + /* UI content creation */ _ui_tabs_add(parent, ui); _ui_tab_system_add(ui); @@ -2471,6 +2626,8 @@ _ui_init(Evas_Object *parent) _ui_tab_disk_add(ui); _ui_tab_misc_add(ui); + _column_expand_init(ui); + return ui; } @@ -2480,7 +2637,7 @@ ui_add(Evas_Object *parent) eina_lock_new(&_lock); /* Create our user interface. */ - Ui *ui = _ui_init(parent); + Ui *ui = _ui = _ui_init(parent); if (!ui) return NULL; /* Start polling our data */ diff --git a/src/bin/ui.h b/src/bin/ui.h index 25a9160..92354b3 100644 --- a/src/bin/ui.h +++ b/src/bin/ui.h @@ -1,11 +1,12 @@ - #ifndef __UI_H__ +#ifndef __UI_H__ #define __UI_H__ #include #include "process.h" +#include "configuration.h" -#define EVISUM_SIZE_WIDTH 500 -#define EVISUM_SIZE_HEIGHT 600 +#define EVISUM_SIZE_WIDTH 600 +#define EVISUM_SIZE_HEIGHT 520 typedef enum { @@ -90,14 +91,6 @@ typedef struct Ui Evas_Object *progress_mem_shared; Evas_Object *progress_mem_swap; - Evas_Object *entry_pid; - Evas_Object *entry_uid; - Evas_Object *entry_size; - Evas_Object *entry_rss; - Evas_Object *entry_cmd; - Evas_Object *entry_state; - Evas_Object *entry_cpu_usage; - Evas_Object *btn_pid; Evas_Object *btn_uid; Evas_Object *btn_size; @@ -105,7 +98,16 @@ typedef struct Ui Evas_Object *btn_cmd; Evas_Object *btn_state; Evas_Object *btn_cpu_usage; - Evas_Object *btn_expand; + + char *long_pid; + char *long_uid; + char *long_size; + char *long_rss; + char *long_cmd; + char *long_state; + char *long_cpu; + + Evas_Object *genlist_procs; Evas_Object *entry_pid_cmd; Evas_Object *entry_pid_user; @@ -135,6 +137,7 @@ typedef struct Ui Evas_Object *list_pid; Eina_Bool skip_wait; + Eina_Bool ready; Eina_List *cpu_times; int64_t pid_cpu_time; @@ -146,6 +149,7 @@ typedef struct Ui Eina_Bool panel_visible; Eina_Bool shutting_down; Eina_Bool searching; + Eina_Bool show_self; uint64_t incoming_max; uint64_t outgoing_max;