This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository evisum.

View the commit online.

commit d8f92c83a517dd949e1bcae046a065303917b134
Author: Alastair Poole <[email protected]>
AuthorDate: Mon Mar 30 04:37:57 2026 +0100

    changes: thrice requested this.
    
    Add disk usage statistics per-process based, then update the
    process_view UI to scroll (this is getting quite long and spacey,
    so add a scroller and ensure the next process view in the current
    session remembers the resize so you have to keep resizing all the
    time.
    
    Also fix so we now handle GB/s transfer rates.
    
    Plug it into the existing infrastucture and bump up the config.
    
    Maybe the exel_widget can be much more efficient, I don't know.
---
 src/bin/evisum_config.c             |  20 ++--
 src/bin/evisum_config.h             |   2 +-
 src/bin/system/process.c            |  88 ++++++++++++++
 src/bin/system/process.h            |   6 +
 src/bin/ui/evisum_ui.h              |   2 +-
 src/bin/ui/evisum_ui_network.c      |   5 +-
 src/bin/ui/evisum_ui_process_list.c |  53 ++++++++-
 src/bin/ui/evisum_ui_process_list.h |  20 ++--
 src/bin/ui/evisum_ui_process_view.c | 223 ++++++++++++++++++++++++++++--------
 9 files changed, 351 insertions(+), 68 deletions(-)

diff --git a/src/bin/evisum_config.c b/src/bin/evisum_config.c
index e0e5e5e..baa503b 100644
--- a/src/bin/evisum_config.c
+++ b/src/bin/evisum_config.c
@@ -20,13 +20,15 @@ enum {
     PROC_FIELD_WIDTH_FILES = 8,
     PROC_FIELD_WIDTH_NET_IN = 9,
     PROC_FIELD_WIDTH_NET_OUT = 10,
-    PROC_FIELD_WIDTH_SIZE = 11,
-    PROC_FIELD_WIDTH_VIRT = 12,
-    PROC_FIELD_WIDTH_RSS = 13,
-    PROC_FIELD_WIDTH_SHARED = 14,
-    PROC_FIELD_WIDTH_STATE = 15,
-    PROC_FIELD_WIDTH_TIME = 16,
-    PROC_FIELD_WIDTH_CPU_USAGE = 17
+    PROC_FIELD_WIDTH_DISK_READ = 11,
+    PROC_FIELD_WIDTH_DISK_WRITE = 12,
+    PROC_FIELD_WIDTH_SIZE = 13,
+    PROC_FIELD_WIDTH_VIRT = 14,
+    PROC_FIELD_WIDTH_RSS = 15,
+    PROC_FIELD_WIDTH_SHARED = 16,
+    PROC_FIELD_WIDTH_STATE = 17,
+    PROC_FIELD_WIDTH_TIME = 18,
+    PROC_FIELD_WIDTH_CPU_USAGE = 19
 };
 
 static const char *
@@ -100,6 +102,10 @@ config_init(void) {
                                   proc.field_widths[PROC_FIELD_WIDTH_NET_IN], EET_T_INT);
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "proc.field_widths.net_out",
                                   proc.field_widths[PROC_FIELD_WIDTH_NET_OUT], EET_T_INT);
+    EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "proc.field_widths.disk_read",
+                                  proc.field_widths[PROC_FIELD_WIDTH_DISK_READ], EET_T_INT);
+    EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "proc.field_widths.disk_write",
+                                  proc.field_widths[PROC_FIELD_WIDTH_DISK_WRITE], EET_T_INT);
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "proc.show_statusbar", proc.show_statusbar,
                                   EET_T_UCHAR);
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "proc.transparent", proc.transparent,
diff --git a/src/bin/evisum_config.h b/src/bin/evisum_config.h
index df0245c..0bcfc3b 100644
--- a/src/bin/evisum_config.h
+++ b/src/bin/evisum_config.h
@@ -3,7 +3,7 @@
 
 #include "ui/evisum_ui.h"
 
-#define CONFIG_VERSION 0x001B
+#define CONFIG_VERSION 0x001C
 
 typedef struct _Evisum_Config {
     int version;
diff --git a/src/bin/system/process.c b/src/bin/system/process.c
index 0dece22..8367a0c 100644
--- a/src/bin/system/process.c
+++ b/src/bin/system/process.c
@@ -366,6 +366,54 @@ _net_transfer_get(Proc_Info *p) {
     fclose(f);
 }
 
+static uint64_t
+_disk_write_get(int pid) {
+    FILE *f;
+    char path[PATH_MAX];
+    char buf[4096];
+    uint64_t write_bytes = 0;
+
+    snprintf(path, sizeof(path), "/proc/%d/io", pid);
+    f = fopen(path, "r");
+    if (!f) return 0;
+
+    while (fgets(buf, sizeof(buf), f)) {
+        unsigned long long value = 0;
+        if (sscanf(buf, "write_bytes: %llu", &value) == 1) {
+            write_bytes = value;
+            break;
+        }
+    }
+
+    fclose(f);
+
+    return write_bytes;
+}
+
+static uint64_t
+_disk_read_get(int pid) {
+    FILE *f;
+    char path[PATH_MAX];
+    char buf[4096];
+    uint64_t read_bytes = 0;
+
+    snprintf(path, sizeof(path), "/proc/%d/io", pid);
+    f = fopen(path, "r");
+    if (!f) return 0;
+
+    while (fgets(buf, sizeof(buf), f)) {
+        unsigned long long value = 0;
+        if (sscanf(buf, "read_bytes: %llu", &value) == 1) {
+            read_bytes = value;
+            break;
+        }
+    }
+
+    fclose(f);
+
+    return read_bytes;
+}
+
 static Eina_List *
 _process_list_linux_get(void) {
     Eina_List *files, *list;
@@ -408,6 +456,8 @@ _process_list_linux_get(void) {
         _mem_size(p);
         _cmd_args(p, st.name, sizeof(st.name));
         _net_transfer_get(p);
+        p->disk_read = _disk_read_get(pid);
+        p->disk_write = _disk_write_get(pid);
 
         Eina_List *next = eina_list_append(list, p);
         if (!next) {
@@ -449,6 +499,8 @@ _proc_thread_info(Proc_Info *p) {
         t->mem_rss = st.mem_rss;
         t->net_in = 0;
         t->net_out = 0;
+        t->disk_read = 0;
+        t->disk_write = 0;
 
         t->tid = tid;
         t->thread_name = strdup(st.name);
@@ -495,6 +547,8 @@ proc_info_by_pid(int pid) {
     _mem_size(p);
     _cmd_args(p, st.name, sizeof(st.name));
     _net_transfer_get(p);
+    p->disk_read = _disk_read_get(pid);
+    p->disk_write = _disk_write_get(pid);
 
     _proc_thread_info(p);
 
@@ -532,6 +586,8 @@ _proc_get(Proc_Info *p, struct kinfo_proc *kp) {
     p->tid = kp->p_tid;
     p->net_in = 0;
     p->net_out = 0;
+    p->disk_read = 0;
+    p->disk_write = 0;
 }
 
 static void
@@ -826,6 +882,8 @@ _proc_pidinfo(size_t pid) {
     p->numthreads = taskinfo.ptinfo.pti_threadnum;
     p->net_in = 0;
     p->net_out = 0;
+    p->disk_read = 0;
+    p->disk_write = 0;
     _cmd_get(p, pid);
 
     return p;
@@ -913,6 +971,8 @@ proc_info_by_pid(int pid) {
     p->numthreads = taskinfo.ptinfo.pti_threadnum;
     p->net_in = 0;
     p->net_out = 0;
+    p->disk_read = 0;
+    p->disk_write = 0;
     _cmd_get(p, pid);
 
     return p;
@@ -1043,6 +1103,8 @@ _proc_thread_info(struct kinfo_proc *kp, Eina_Bool is_thread) {
     p->numthreads = kp->ki_numthreads;
     p->net_in = 0;
     p->net_out = 0;
+    p->disk_read = 0;
+    p->disk_write = 0;
 
     p->tid = kp->ki_tid;
     p->thread_name = strdup(kp->ki_tdname);
@@ -1482,6 +1544,32 @@ proc_sort_by_net_out(const void *p1, const void *p2) {
     return 0;
 }
 
+int
+proc_sort_by_disk_read(const void *p1, const void *p2) {
+    const Proc_Info *inf1, *inf2;
+
+    inf1 = p1;
+    inf2 = p2;
+
+    if (inf1->disk_read > inf2->disk_read) return 1;
+    if (inf1->disk_read < inf2->disk_read) return -1;
+
+    return 0;
+}
+
+int
+proc_sort_by_disk_write(const void *p1, const void *p2) {
+    const Proc_Info *inf1, *inf2;
+
+    inf1 = p1;
+    inf2 = p2;
+
+    if (inf1->disk_write > inf2->disk_write) return 1;
+    if (inf1->disk_write < inf2->disk_write) return -1;
+
+    return 0;
+}
+
 int
 proc_sort_by_time(const void *p1, const void *p2) {
     const Proc_Info *inf1, *inf2;
diff --git a/src/bin/system/process.h b/src/bin/system/process.h
index d4cb524..040e34a 100644
--- a/src/bin/system/process.h
+++ b/src/bin/system/process.h
@@ -28,6 +28,8 @@ typedef struct _Proc_Info {
     uint64_t mem_shared;
     uint64_t net_in;
     uint64_t net_out;
+    uint64_t disk_read;
+    uint64_t disk_write;
 
     char *command;
     char *arguments;
@@ -87,6 +89,10 @@ int proc_sort_by_net_in(const void *p1, const void *p2);
 
 int proc_sort_by_net_out(const void *p1, const void *p2);
 
+int proc_sort_by_disk_read(const void *p1, const void *p2);
+
+int proc_sort_by_disk_write(const void *p1, const void *p2);
+
 int proc_sort_by_time(const void *p1, const void *p2);
 
 int proc_sort_by_cpu_usage(const void *p1, const void *p2);
diff --git a/src/bin/ui/evisum_ui.h b/src/bin/ui/evisum_ui.h
index f7d8738..6da24d4 100644
--- a/src/bin/ui/evisum_ui.h
+++ b/src/bin/ui/evisum_ui.h
@@ -15,7 +15,7 @@
 
 #define EVISUM_WIN_WIDTH             540
 #define EVISUM_WIN_HEIGHT            360
-#define EVISUM_PROC_FIELD_WIDTHS_MAX 18
+#define EVISUM_PROC_FIELD_WIDTHS_MAX 20
 
 typedef struct _Evisum_Ui {
     pid_t program_pid;
diff --git a/src/bin/ui/evisum_ui_network.c b/src/bin/ui/evisum_ui_network.c
index 9646623..adfa53c 100644
--- a/src/bin/ui/evisum_ui_network.c
+++ b/src/bin/ui/evisum_ui_network.c
@@ -139,7 +139,10 @@ _evisum_ui_network_transfer_format(double rate) {
     const char *unit = _("B/s");
     char buf[256];
 
-    if (rate > 1048576) {
+    if (rate > 1073741824) {
+        rate /= 1073741824;
+        unit = _("GB/s");
+    } else if (rate > 1048576) {
         rate /= 1048576;
         unit = _("MB/s");
     } else if ((rate > 1024) && (rate < 1048576)) {
diff --git a/src/bin/ui/evisum_ui_process_list.c b/src/bin/ui/evisum_ui_process_list.c
index 7def133..601f2ca 100644
--- a/src/bin/ui/evisum_ui_process_list.c
+++ b/src/bin/ui/evisum_ui_process_list.c
@@ -80,6 +80,8 @@ typedef struct {
     int64_t cpu_time;
     uint64_t net_in;
     uint64_t net_out;
+    uint64_t disk_read;
+    uint64_t disk_write;
 } Proc_Usage_Cache;
 
 static void _evisum_ui_process_list_content_reset(Evisum_Ui_Process_List_View *view);
@@ -112,6 +114,8 @@ static const Proc_Field_Info _proc_field_info[PROC_FIELD_MAX] = {
     [PROC_FIELD_CPU_USAGE] = { "cpu %",   "CPU Usage",       PROC_SORT_BY_CPU_USAGE },
     [PROC_FIELD_NET_IN] = { "net in",  "Network In",      PROC_SORT_BY_NET_IN    },
     [PROC_FIELD_NET_OUT] = { "net out", "Network Out",     PROC_SORT_BY_NET_OUT   },
+    [PROC_FIELD_DISK_READ] = { "disk read", "Disk Read", PROC_SORT_BY_DISK_READ },
+    [PROC_FIELD_DISK_WRITE] = { "disk write", "Disk Write", PROC_SORT_BY_DISK_WRITE },
 };
 
 static const Proc_Field_Info *
@@ -126,7 +130,9 @@ _evisum_ui_process_list_field_default_width_get(Proc_Field id) {
     if (id == PROC_FIELD_CMD) return 2.0 * ELM_SCALE_SIZE(BTN_WIDTH);
     if (id == PROC_FIELD_UID) return 1.8 * ELM_SCALE_SIZE(BTN_WIDTH);
     if (id == PROC_FIELD_CPU_USAGE) return 1.75 * ELM_SCALE_SIZE(BTN_WIDTH);
-    if (id == PROC_FIELD_NET_IN || id == PROC_FIELD_NET_OUT) return 1.5 * ELM_SCALE_SIZE(BTN_WIDTH);
+    if (id == PROC_FIELD_NET_IN || id == PROC_FIELD_NET_OUT || id == PROC_FIELD_DISK_READ
+        || id == PROC_FIELD_DISK_WRITE)
+        return 1.5 * ELM_SCALE_SIZE(BTN_WIDTH);
 
     return ELM_SCALE_SIZE(BTN_WIDTH);
 }
@@ -181,6 +187,8 @@ _evisum_ui_process_list_field_row_def_get(Proc_Field id, Evisum_Ui_Widget_Exel_I
         case PROC_FIELD_FILES: def->key = "files"; return EINA_TRUE;
         case PROC_FIELD_NET_IN: def->key = "net_in"; return EINA_TRUE;
         case PROC_FIELD_NET_OUT: def->key = "net_out"; return EINA_TRUE;
+        case PROC_FIELD_DISK_READ: def->key = "disk_read"; return EINA_TRUE;
+        case PROC_FIELD_DISK_WRITE: def->key = "disk_write"; return EINA_TRUE;
         case PROC_FIELD_SIZE: def->key = "size"; return EINA_TRUE;
         case PROC_FIELD_VIRT: def->key = "virt"; return EINA_TRUE;
         case PROC_FIELD_RSS: def->key = "rss"; return EINA_TRUE;
@@ -355,7 +363,10 @@ _evisum_ui_process_list_net_rate_set(char *buf, size_t n, uint64_t rate) {
     const char *unit = _("B/s");
     double value = rate;
 
-    if (value > 1048576.0) {
+    if (value > 1073741824.0) {
+        value /= 1073741824.0;
+        unit = _("GB/s");
+    } else if (value > 1048576.0) {
         value /= 1048576.0;
         unit = _("MB/s");
     } else if (value > 1024.0) {
@@ -503,6 +514,20 @@ _evisum_ui_process_list_content_get(void *data, Evas_Object *obj, const char *so
     }
     evisum_ui_widget_exel_item_field_text_set(view->widget_exel, row, PROC_FIELD_NET_OUT, "net_out", buf);
 
+    if (!proc->is_kernel) _evisum_ui_process_list_net_rate_set(buf, sizeof(buf), proc->disk_read);
+    else {
+        buf[0] = '-';
+        buf[1] = '\0';
+    }
+    evisum_ui_widget_exel_item_field_text_set(view->widget_exel, row, PROC_FIELD_DISK_READ, "disk_read", buf);
+
+    if (!proc->is_kernel) _evisum_ui_process_list_net_rate_set(buf, sizeof(buf), proc->disk_write);
+    else {
+        buf[0] = '-';
+        buf[1] = '\0';
+    }
+    evisum_ui_widget_exel_item_field_text_set(view->widget_exel, row, PROC_FIELD_DISK_WRITE, "disk_write", buf);
+
     return row;
 }
 
@@ -642,6 +667,8 @@ _evisum_ui_process_list_search_trim(Eina_List *list, Evisum_Ui_Process_List_View
             if ((cache = eina_hash_find(view->proc_usage_cache, &id))) {
                 uint64_t net_in_abs = 0;
                 uint64_t net_out_abs = 0;
+                uint64_t disk_read_abs = proc->disk_read;
+                uint64_t disk_write_abs = proc->disk_write;
                 int elapsed = view->ui->proc.poll_delay;
                 if (elapsed <= 0) elapsed = 1;
                 evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
@@ -651,9 +678,13 @@ _evisum_ui_process_list_search_trim(Eina_List *list, Evisum_Ui_Process_List_View
                     cache->cpu_time = proc->cpu_time;
                     cache->net_in = net_in_abs;
                     cache->net_out = net_out_abs;
+                    cache->disk_read = proc->disk_read;
+                    cache->disk_write = proc->disk_write;
                     proc->cpu_usage = 0.0;
                     proc->net_in = 0;
                     proc->net_out = 0;
+                    proc->disk_read = 0;
+                    proc->disk_write = 0;
                     continue;
                 }
 
@@ -668,8 +699,18 @@ _evisum_ui_process_list_search_trim(Eina_List *list, Evisum_Ui_Process_List_View
                 if (cache->net_out && net_out_abs >= cache->net_out) proc->net_out = (net_out_abs - cache->net_out) / elapsed;
                 else proc->net_out = 0;
 
+                if (cache->disk_read && disk_read_abs >= cache->disk_read)
+                    proc->disk_read = (disk_read_abs - cache->disk_read) / elapsed;
+                else proc->disk_read = 0;
+
+                if (cache->disk_write && disk_write_abs >= cache->disk_write)
+                    proc->disk_write = (disk_write_abs - cache->disk_write) / elapsed;
+                else proc->disk_write = 0;
+
                 cache->net_in = net_in_abs;
                 cache->net_out = net_out_abs;
+                cache->disk_read = disk_read_abs;
+                cache->disk_write = disk_write_abs;
             } else {
                 cache = calloc(1, sizeof(Proc_Usage_Cache));
                 if (cache) {
@@ -680,8 +721,12 @@ _evisum_ui_process_list_search_trim(Eina_List *list, Evisum_Ui_Process_List_View
                     cache->cpu_time = proc->cpu_time;
                     cache->net_in = net_in_abs;
                     cache->net_out = net_out_abs;
+                    cache->disk_read = proc->disk_read;
+                    cache->disk_write = proc->disk_write;
                     proc->net_in = 0;
                     proc->net_out = 0;
+                    proc->disk_read = 0;
+                    proc->disk_write = 0;
                     eina_hash_add(view->proc_usage_cache, &id, cache);
                 }
             }
@@ -1449,6 +1494,8 @@ _evisum_ui_process_list_config_changed_cb(void *data, int type EINA_UNUSED, void
         cache->cpu_time = 0;
         cache->net_in = 0;
         cache->net_out = 0;
+        cache->disk_read = 0;
+        cache->disk_write = 0;
     }
     eina_iterator_free(it);
 
@@ -1559,6 +1606,8 @@ _evisum_ui_process_list_init(Evisum_Ui_Process_List_View *view) {
     view->sorters[PROC_SORT_BY_CPU_USAGE].sort_cb = proc_sort_by_cpu_usage;
     view->sorters[PROC_SORT_BY_NET_IN].sort_cb = proc_sort_by_net_in;
     view->sorters[PROC_SORT_BY_NET_OUT].sort_cb = proc_sort_by_net_out;
+    view->sorters[PROC_SORT_BY_DISK_READ].sort_cb = proc_sort_by_disk_read;
+    view->sorters[PROC_SORT_BY_DISK_WRITE].sort_cb = proc_sort_by_disk_write;
 }
 
 void
diff --git a/src/bin/ui/evisum_ui_process_list.h b/src/bin/ui/evisum_ui_process_list.h
index cfbdc86..3c60df5 100644
--- a/src/bin/ui/evisum_ui_process_list.h
+++ b/src/bin/ui/evisum_ui_process_list.h
@@ -22,6 +22,8 @@ typedef enum {
     PROC_SORT_BY_CPU_USAGE,
     PROC_SORT_BY_NET_IN,
     PROC_SORT_BY_NET_OUT,
+    PROC_SORT_BY_DISK_READ,
+    PROC_SORT_BY_DISK_WRITE,
     PROC_SORT_BY_MAX,
 } Proc_Sort;
 
@@ -36,14 +38,16 @@ typedef enum {
     PROC_FIELD_FILES = 8,
     PROC_FIELD_NET_IN = 9,
     PROC_FIELD_NET_OUT = 10,
-    PROC_FIELD_SIZE = 11,
-    PROC_FIELD_VIRT = 12,
-    PROC_FIELD_RSS = 13,
-    PROC_FIELD_SHARED = 14,
-    PROC_FIELD_STATE = 15,
-    PROC_FIELD_TIME = 16,
-    PROC_FIELD_CPU_USAGE = 17,
-    PROC_FIELD_MAX = 18,
+    PROC_FIELD_DISK_READ = 11,
+    PROC_FIELD_DISK_WRITE = 12,
+    PROC_FIELD_SIZE = 13,
+    PROC_FIELD_VIRT = 14,
+    PROC_FIELD_RSS = 15,
+    PROC_FIELD_SHARED = 16,
+    PROC_FIELD_STATE = 17,
+    PROC_FIELD_TIME = 18,
+    PROC_FIELD_CPU_USAGE = 19,
+    PROC_FIELD_MAX = 20,
 } Proc_Field;
 
 void evisum_ui_process_list_win_add(Evisum_Ui *ui);
diff --git a/src/bin/ui/evisum_ui_process_view.c b/src/bin/ui/evisum_ui_process_view.c
index b2f1181..773dfb3 100644
--- a/src/bin/ui/evisum_ui_process_view.c
+++ b/src/bin/ui/evisum_ui_process_view.c
@@ -9,7 +9,6 @@
 typedef struct {
     Evisum_Ui *ui;
     Evas_Object *win;
-    Evas_Object *tb_content;
 
     Evas_Object *tab_general;
     Evas_Object *tab_children;
@@ -28,17 +27,14 @@ typedef struct {
     char *selected_cmd;
     int selected_pid;
     uint32_t poll_count;
-    int64_t pid_cpu_time;
-#if defined(__linux__)
-    uint64_t pid_net_in;
-    uint64_t pid_net_out;
-#endif
 
     Ecore_Thread *thread;
 
     Eina_Bool kthreads_has_rss;
+    Eina_Bool ignore_initial_resize;
 
     Eina_Hash *icon_cache;
+    Eina_Hash *proc_usage_cache;
 
     struct {
         Evas_Object *entry_cmd;
@@ -63,6 +59,8 @@ typedef struct {
 #if defined(__linux__)
         Evas_Object *entry_net_in;
         Evas_Object *entry_net_out;
+        Evas_Object *entry_disk_read;
+        Evas_Object *entry_disk_write;
 #endif
         Evas_Object *btn_start;
         Evas_Object *btn_stop;
@@ -99,11 +97,25 @@ typedef struct {
 
 } Evisum_Ui_Process_View;
 
+static int _process_view_last_width = 0;
+static int _process_view_last_height = 0;
+
 typedef struct {
     long cpu_time;
     long cpu_time_prev;
 } Thread_Cpu_Info;
 
+typedef struct {
+    int64_t start;
+    int64_t cpu_time;
+#if defined(__linux__)
+    uint64_t net_in;
+    uint64_t net_out;
+    uint64_t disk_read;
+    uint64_t disk_write;
+#endif
+} Proc_Usage_Cache;
+
 typedef struct {
     int tid;
     char *name;
@@ -176,6 +188,12 @@ _evisum_ui_process_view_hash_free_cb(void *data) {
     free(inf);
 }
 
+static void
+_evisum_ui_process_view_usage_cache_free_cb(void *data) {
+    Proc_Usage_Cache *cache = data;
+    free(cache);
+}
+
 static Evas_Object *
 _evisum_ui_process_view_content_get(void *data, Evas_Object *obj, const char *source) {
     Evisum_Ui_Process_View *view;
@@ -627,12 +645,15 @@ _evisum_ui_process_view_run_time_string(int64_t secs) {
 
 #if defined(__linux__)
 static char *
-_evisum_ui_process_view_net_rate_string(uint64_t rate) {
+_evisum_ui_process_view_rate_string(uint64_t rate) {
     const char *unit = _("B/s");
     char buf[256];
     double value = rate;
 
-    if (value > 1048576.0) {
+    if (value > 1073741824.0) {
+        value /= 1073741824.0;
+        unit = _("GB/s");
+    } else if (value > 1048576.0) {
         value /= 1048576.0;
         unit = _("MB/s");
     } else if (value > 1024.0) {
@@ -762,20 +783,34 @@ _evisum_ui_process_view_general_view_update(Evisum_Ui_Process_View *view, Proc_I
 
 #if defined(__linux__)
     if (!proc->is_kernel) {
-        s = _evisum_ui_process_view_net_rate_string(proc->net_in);
+        s = _evisum_ui_process_view_rate_string(proc->net_in);
         if (s) {
             elm_object_text_set(view->general.entry_net_in, s);
             free(s);
         }
 
-        s = _evisum_ui_process_view_net_rate_string(proc->net_out);
+        s = _evisum_ui_process_view_rate_string(proc->net_out);
         if (s) {
             elm_object_text_set(view->general.entry_net_out, s);
             free(s);
         }
+
+        s = _evisum_ui_process_view_rate_string(proc->disk_read);
+        if (s) {
+            elm_object_text_set(view->general.entry_disk_read, s);
+            free(s);
+        }
+
+        s = _evisum_ui_process_view_rate_string(proc->disk_write);
+        if (s) {
+            elm_object_text_set(view->general.entry_disk_write, s);
+            free(s);
+        }
     } else {
         elm_object_text_set(view->general.entry_net_in, _("-"));
         elm_object_text_set(view->general.entry_net_out, _("-"));
+        elm_object_text_set(view->general.entry_disk_read, _("-"));
+        elm_object_text_set(view->general.entry_disk_write, _("-"));
     }
 #endif
 }
@@ -798,13 +833,14 @@ static void
 _evisum_ui_process_view_proc_info_feedback_cb(void *data, Ecore_Thread *thread, void *msg) {
     Evisum_Ui_Process_View *view;
     Proc_Info *proc;
-    double cpu_usage = 0.0;
+    Proc_Usage_Cache *cache;
+    int64_t id;
     int elapsed;
 #if defined(__linux__)
-    uint64_t net_in = 0;
-    uint64_t net_out = 0;
     uint64_t net_in_abs = 0;
     uint64_t net_out_abs = 0;
+    uint64_t disk_read_abs = 0;
+    uint64_t disk_write_abs = 0;
 #endif
 
     view = data;
@@ -831,21 +867,84 @@ _evisum_ui_process_view_proc_info_feedback_cb(void *data, Ecore_Thread *thread,
         view->poll_count++;
         return;
     }
+    if (!view->proc_usage_cache) view->proc_usage_cache = eina_hash_int64_new(_evisum_ui_process_view_usage_cache_free_cb);
 
-    if ((view->pid_cpu_time) && (proc->cpu_time >= view->pid_cpu_time))
-        cpu_usage = (double) (proc->cpu_time - view->pid_cpu_time) / elapsed;
-
-    proc->cpu_usage = cpu_usage;
+    id = proc->pid;
+    cache = view->proc_usage_cache ? eina_hash_find(view->proc_usage_cache, &id) : NULL;
 #if defined(__linux__)
-    evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
-
-    if ((view->pid_net_in) && (net_in_abs >= view->pid_net_in)) net_in = (net_in_abs - view->pid_net_in) / elapsed;
-    if ((view->pid_net_out) && (net_out_abs >= view->pid_net_out))
-        net_out = (net_out_abs - view->pid_net_out) / elapsed;
-
-    proc->net_in = net_in;
-    proc->net_out = net_out;
+    disk_read_abs = proc->disk_read;
+    disk_write_abs = proc->disk_write;
 #endif
+    if (!cache) {
+        cache = calloc(1, sizeof(Proc_Usage_Cache));
+        if (cache) {
+            cache->start = proc->start;
+            cache->cpu_time = proc->cpu_time;
+#if defined(__linux__)
+            evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
+            cache->net_in = net_in_abs;
+            cache->net_out = net_out_abs;
+            cache->disk_read = disk_read_abs;
+            cache->disk_write = disk_write_abs;
+            proc->net_in = 0;
+            proc->net_out = 0;
+            proc->disk_read = 0;
+            proc->disk_write = 0;
+#endif
+            proc->cpu_usage = 0.0;
+            if (view->proc_usage_cache) eina_hash_add(view->proc_usage_cache, &id, cache);
+            else free(cache);
+        } else {
+            proc->cpu_usage = 0.0;
+#if defined(__linux__)
+            proc->net_in = 0;
+            proc->net_out = 0;
+            proc->disk_read = 0;
+            proc->disk_write = 0;
+#endif
+        }
+    } else if (cache->start != proc->start) {
+        cache->start = proc->start;
+        cache->cpu_time = proc->cpu_time;
+#if defined(__linux__)
+        evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
+        cache->net_in = net_in_abs;
+        cache->net_out = net_out_abs;
+        cache->disk_read = disk_read_abs;
+        cache->disk_write = disk_write_abs;
+        proc->net_in = 0;
+        proc->net_out = 0;
+        proc->disk_read = 0;
+        proc->disk_write = 0;
+#endif
+        proc->cpu_usage = 0.0;
+    } else {
+        if (cache->cpu_time && (proc->cpu_time >= cache->cpu_time))
+            proc->cpu_usage = (double) (proc->cpu_time - cache->cpu_time) / elapsed;
+        else proc->cpu_usage = 0.0;
+        cache->cpu_time = proc->cpu_time;
+#if defined(__linux__)
+        evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
+        if (cache->net_in && (net_in_abs >= cache->net_in)) proc->net_in = (net_in_abs - cache->net_in) / elapsed;
+        else proc->net_in = 0;
+
+        if (cache->net_out && (net_out_abs >= cache->net_out)) proc->net_out = (net_out_abs - cache->net_out) / elapsed;
+        else proc->net_out = 0;
+
+        if (cache->disk_read && (disk_read_abs >= cache->disk_read))
+            proc->disk_read = (disk_read_abs - cache->disk_read) / elapsed;
+        else proc->disk_read = 0;
+
+        if (cache->disk_write && (disk_write_abs >= cache->disk_write))
+            proc->disk_write = (disk_write_abs - cache->disk_write) / elapsed;
+        else proc->disk_write = 0;
+
+        cache->net_in = net_in_abs;
+        cache->net_out = net_out_abs;
+        cache->disk_read = disk_read_abs;
+        cache->disk_write = disk_write_abs;
+#endif
+    }
 
     _evisum_ui_process_view_graph_update(view, proc);
     _evisum_ui_process_view_graph_summary_update(view, proc);
@@ -853,11 +952,6 @@ _evisum_ui_process_view_proc_info_feedback_cb(void *data, Ecore_Thread *thread,
     _evisum_ui_process_view_general_view_update(view, proc);
 
     view->poll_count++;
-    view->pid_cpu_time = proc->cpu_time;
-#if defined(__linux__)
-    view->pid_net_in = net_in_abs;
-    view->pid_net_out = net_out_abs;
-#endif
 
     proc_info_free(proc);
 }
@@ -914,7 +1008,7 @@ _evisum_ui_process_view_lb_add(Evas_Object *parent, const char *text) {
 
 static Evas_Object *
 _evisum_ui_process_view_general_tab_add(Evas_Object *parent, Evisum_Ui_Process_View *view) {
-    Evas_Object *fr, *hbx, *tb;
+    Evas_Object *fr, *hbx, *tb, *scr;
     Evas_Object *lb, *entry, *btn, *pad, *ic;
     Evas_Object *rec;
     Proc_Info *proc;
@@ -925,12 +1019,20 @@ _evisum_ui_process_view_general_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
     evas_object_size_hint_weight_set(fr, EXPAND, EXPAND);
     evas_object_size_hint_align_set(fr, FILL, FILL);
 
+    scr = elm_scroller_add(parent);
+    evas_object_size_hint_weight_set(scr, EXPAND, EXPAND);
+    evas_object_size_hint_align_set(scr, FILL, FILL);
+    elm_scroller_policy_set(scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
+    elm_scroller_bounce_set(scr, 0, 1);
+    evas_object_show(scr);
+    elm_object_content_set(fr, scr);
+
     tb = elm_table_add(parent);
     evas_object_size_hint_weight_set(tb, EXPAND, EXPAND);
     evas_object_size_hint_align_set(tb, FILL, FILL);
     evas_object_show(tb);
     elm_object_focus_allow_set(tb, 1);
-    elm_object_content_set(fr, tb);
+    elm_object_content_set(scr, tb);
 
     rec = evas_object_rectangle_add(evas_object_evas_get(tb));
     evas_object_size_hint_min_set(rec, ELM_SCALE_SIZE(64), ELM_SCALE_SIZE(64));
@@ -1008,18 +1110,6 @@ _evisum_ui_process_view_general_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
     view->general.entry_files = entry = _evisum_ui_process_view_entry_add(parent);
     elm_table_pack(tb, entry, 1, i++, 1, 1);
 
-#if defined(__linux__)
-    lb = _evisum_ui_process_view_lb_add(parent, _(" Network In:"));
-    elm_table_pack(tb, lb, 0, i, 1, 1);
-    view->general.entry_net_in = entry = _evisum_ui_process_view_entry_add(parent);
-    elm_table_pack(tb, entry, 1, i++, 1, 1);
-
-    lb = _evisum_ui_process_view_lb_add(parent, _(" Network Out:"));
-    elm_table_pack(tb, lb, 0, i, 1, 1);
-    view->general.entry_net_out = entry = _evisum_ui_process_view_entry_add(parent);
-    elm_table_pack(tb, entry, 1, i++, 1, 1);
-#endif
-
     lb = _evisum_ui_process_view_lb_add(parent, _(" Memory :"));
     elm_table_pack(tb, lb, 0, i, 1, 1);
     view->general.entry_size = entry = _evisum_ui_process_view_entry_add(parent);
@@ -1040,6 +1130,28 @@ _evisum_ui_process_view_general_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
     view->general.entry_virt = entry = _evisum_ui_process_view_entry_add(parent);
     elm_table_pack(tb, entry, 1, i++, 1, 1);
 
+#if defined(__linux__)
+    lb = _evisum_ui_process_view_lb_add(parent, _(" Disk Read:"));
+    elm_table_pack(tb, lb, 0, i, 1, 1);
+    view->general.entry_disk_read = entry = _evisum_ui_process_view_entry_add(parent);
+    elm_table_pack(tb, entry, 1, i++, 1, 1);
+
+    lb = _evisum_ui_process_view_lb_add(parent, _(" Disk Write:"));
+    elm_table_pack(tb, lb, 0, i, 1, 1);
+    view->general.entry_disk_write = entry = _evisum_ui_process_view_entry_add(parent);
+    elm_table_pack(tb, entry, 1, i++, 1, 1);
+
+    lb = _evisum_ui_process_view_lb_add(parent, _(" Network In:"));
+    elm_table_pack(tb, lb, 0, i, 1, 1);
+    view->general.entry_net_in = entry = _evisum_ui_process_view_entry_add(parent);
+    elm_table_pack(tb, entry, 1, i++, 1, 1);
+
+    lb = _evisum_ui_process_view_lb_add(parent, _(" Network Out:"));
+    elm_table_pack(tb, lb, 0, i, 1, 1);
+    view->general.entry_net_out = entry = _evisum_ui_process_view_entry_add(parent);
+    elm_table_pack(tb, entry, 1, i++, 1, 1);
+#endif
+
     lb = _evisum_ui_process_view_lb_add(parent, _(" Start time:"));
     elm_table_pack(tb, lb, 0, i, 1, 1);
     view->general.entry_started = entry = _evisum_ui_process_view_entry_add(parent);
@@ -1445,6 +1557,7 @@ _evisum_ui_process_view_win_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object
     }
 
     if (view->threads.hash_cpu_times) eina_hash_free(view->threads.hash_cpu_times);
+    if (view->proc_usage_cache) eina_hash_free(view->proc_usage_cache);
     free(view->selected_cmd);
     if (view->threads.widget_exel) evisum_ui_widget_exel_free(view->threads.widget_exel);
     if (view->children.widget_exel) evisum_ui_widget_exel_free(view->children.widget_exel);
@@ -1459,6 +1572,17 @@ _evisum_ui_process_view_win_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object
 static void
 _evisum_ui_process_view_win_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) {
     Evisum_Ui_Process_View *view = data;
+    Evas_Coord w, h;
+
+    if (view->ignore_initial_resize) {
+        view->ignore_initial_resize = 0;
+        evisum_ui_widget_exel_genlist_realized_items_update(view->threads.widget_exel);
+        return;
+    }
+
+    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+    if (w > 0) _process_view_last_width = w;
+    if (h > 0) _process_view_last_height = h;
 
     evisum_ui_widget_exel_genlist_realized_items_update(view->threads.widget_exel);
 }
@@ -1566,14 +1690,14 @@ evisum_ui_process_view_win_add(Evisum_Ui *ui, int pid, Evisum_Proc_Action action
     tabs = _evisum_ui_process_view_tabs_add(win, view);
 
     bx = elm_box_add(win);
-    evas_object_size_hint_weight_set(bx, EXPAND, 0);
+    evas_object_size_hint_weight_set(bx, EXPAND, EXPAND);
     evas_object_size_hint_align_set(bx, FILL, FILL);
     evas_object_show(bx);
     elm_box_pack_end(bx, tabs);
 
-    view->tb_content = tb = elm_table_add(bx);
+    tb = elm_table_add(bx);
     evas_object_size_hint_weight_set(tb, EXPAND, EXPAND);
-    evas_object_size_hint_align_set(tb, FILL, 0.0);
+    evas_object_size_hint_align_set(tb, FILL, FILL);
     evas_object_show(tb);
 
     view->general_view = _evisum_ui_process_view_general_tab_add(tabs, view);
@@ -1593,7 +1717,10 @@ evisum_ui_process_view_win_add(Evisum_Ui *ui, int pid, Evisum_Proc_Action action
     evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _evisum_ui_process_view_win_resize_cb, view);
     evas_object_event_callback_add(bx, EVAS_CALLBACK_KEY_DOWN, _evisum_ui_process_view_win_key_down_cb, view);
 
-    evas_object_resize(win, ELM_SCALE_SIZE(460), 1);
+    view->ignore_initial_resize = 1;
+    if (_process_view_last_width > 0 && _process_view_last_height > 0)
+        evas_object_resize(win, _process_view_last_width, _process_view_last_height);
+    else evas_object_resize(win, ELM_SCALE_SIZE(460), ELM_SCALE_SIZE(600));
     elm_win_center(win, 1, 1);
     evas_object_show(win);
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to