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 ee846b07a343bcf659e916f4669e717241167bb5
Author: Alastair Poole <[email protected]>
AuthorDate: Fri May 29 22:16:54 2026 +0100

    feature: allow disk i/o graphs as well as usage over time.
---
 NEWS                                    |   1 +
 src/bin/enigmatic/system/file_systems.c |  26 ++-
 src/bin/evisum_config.c                 |   3 +
 src/bin/evisum_config.h                 |   8 +-
 src/bin/ui/evisum_ui.c                  |  57 ++++++
 src/bin/ui/evisum_ui.h                  |   1 +
 src/bin/ui/evisum_ui_disk.c             | 327 +++++++++++++++++++++++---------
 src/bin/ui/evisum_ui_disk.h             |   2 +
 8 files changed, 335 insertions(+), 90 deletions(-)

diff --git a/NEWS b/NEWS
index f7cdc03..3a89634 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Evisum 2.0.11
   * Keep track of disk read and writes.
   * Fix the history bounds to include up to the current time.
   * Add a basic uptime API libenigmatic can provide.
+  * Add UI for disk i/o as well as disk usage.
 
 =============
 Evisum 2.0.10
diff --git a/src/bin/enigmatic/system/file_systems.c b/src/bin/enigmatic/system/file_systems.c
index a4afbb5..cf30a55 100644
--- a/src/bin/enigmatic/system/file_systems.c
+++ b/src/bin/enigmatic/system/file_systems.c
@@ -7,6 +7,8 @@
 
 #if defined(__linux__)
  #include <sys/vfs.h>
+ #include <sys/stat.h>
+ #include <sys/sysmacros.h>
 #endif
 
 #if defined(__APPLE__) && defined(__MACH__)
@@ -107,20 +109,36 @@ _linux_disk_usage_hash_get(void)
    return hash;
 }
 
-static void
-_linux_file_system_disk_usage_set(File_System *fs, Eina_Hash *disk_usage, unsigned int major_id, unsigned int minor_id)
+static Eina_Bool
+_linux_file_system_disk_usage_key_set(File_System *fs, Eina_Hash *disk_usage, unsigned int major_id,
+                                      unsigned int minor_id)
 {
    Linux_Disk_Usage *usage;
    char key[64];
 
-   if (!disk_usage) return;
+   if (!disk_usage) return EINA_FALSE;
 
    snprintf(key, sizeof(key), "%u:%u", major_id, minor_id);
    usage = eina_hash_find(disk_usage, key);
-   if (!usage) return;
+   if (!usage) return EINA_FALSE;
 
    fs->usage.read = usage->read;
    fs->usage.write = usage->write;
+   return EINA_TRUE;
+}
+
+static void
+_linux_file_system_disk_usage_set(File_System *fs, Eina_Hash *disk_usage, unsigned int major_id, unsigned int minor_id)
+{
+   struct stat st;
+
+   if (_linux_file_system_disk_usage_key_set(fs, disk_usage, major_id, minor_id))
+     return;
+
+   if ((stat(fs->path, &st) < 0) || (!S_ISBLK(st.st_mode)))
+     return;
+
+   _linux_file_system_disk_usage_key_set(fs, disk_usage, major(st.st_rdev), minor(st.st_rdev));
 }
 #endif
 
diff --git a/src/bin/evisum_config.c b/src/bin/evisum_config.c
index 5c70dad..39dab0a 100644
--- a/src/bin/evisum_config.c
+++ b/src/bin/evisum_config.c
@@ -172,6 +172,8 @@ config_init(void) {
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "disk.x", disk.x, EET_T_INT);
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "disk.y", disk.y, EET_T_INT);
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "disk.restart", disk.restart, EET_T_UCHAR);
+    EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "disk.graph_mode", disk.graph_mode,
+                                  EET_T_INT);
 
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "sensors.width", sensors.width, EET_T_INT);
     EET_DATA_DESCRIPTOR_ADD_BASIC(_evisum_conf_descriptor, Evisum_Config, "sensors.height", sensors.height, EET_T_INT);
@@ -247,6 +249,7 @@ _config_init() {
     for (int i = PROC_FIELD_CMD; i < PROC_FIELD_MAX; i++) cfg->proc.field_order[i] = i;
 
     cfg->cpu.visual = eina_stringshare_add("default");
+    cfg->disk.graph_mode = EVISUM_DISK_GRAPH_USAGE;
 
     return cfg;
 }
diff --git a/src/bin/evisum_config.h b/src/bin/evisum_config.h
index 58e9b3e..e3e44ad 100644
--- a/src/bin/evisum_config.h
+++ b/src/bin/evisum_config.h
@@ -3,7 +3,12 @@
 
 #include "ui/evisum_ui.h"
 
-#define CONFIG_VERSION 0x0020
+#define CONFIG_VERSION 0x0021
+
+typedef enum {
+    EVISUM_DISK_GRAPH_USAGE = 0,
+    EVISUM_DISK_GRAPH_TRANSFER = 1,
+} Evisum_Disk_Graph_Mode;
 
 typedef struct _Evisum_Config {
     int version;
@@ -53,6 +58,7 @@ typedef struct _Evisum_Config {
         int height;
         int x, y;
         Eina_Bool restart;
+        int graph_mode;
     } disk;
 
     struct {
diff --git a/src/bin/ui/evisum_ui.c b/src/bin/ui/evisum_ui.c
index 5941d2a..2993971 100644
--- a/src/bin/ui/evisum_ui.c
+++ b/src/bin/ui/evisum_ui.c
@@ -116,6 +116,7 @@ evisum_ui_config_save(Evisum_Ui *ui) {
         config()->disk.x = ui->disk.x;
         config()->disk.y = ui->disk.y;
         config()->disk.restart = ui->disk.restart;
+        config()->disk.graph_mode = ui->disk.graph_mode;
     }
 
     if (ui->sensors.win) {
@@ -204,6 +205,9 @@ evisum_ui_config_load(Evisum_Ui *ui) {
     ui->disk.x = config()->disk.x;
     ui->disk.y = config()->disk.y;
     ui->disk.restart = config()->disk.restart;
+    ui->disk.graph_mode = config()->disk.graph_mode;
+    if ((ui->disk.graph_mode < EVISUM_DISK_GRAPH_USAGE) || (ui->disk.graph_mode > EVISUM_DISK_GRAPH_TRANSFER))
+        ui->disk.graph_mode = EVISUM_DISK_GRAPH_USAGE;
 
     ui->sensors.width = config()->sensors.width;
     ui->sensors.height = config()->sensors.height;
@@ -366,6 +370,20 @@ _main_menu_history_range_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, vo
     evisum_ui_config_save(ui);
 }
 
+static void
+_main_menu_disk_graph_mode_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) {
+    Evisum_Ui *ui = data;
+    int graph_mode;
+
+    graph_mode = elm_radio_value_get(obj);
+    if ((graph_mode < EVISUM_DISK_GRAPH_USAGE) || (graph_mode > EVISUM_DISK_GRAPH_TRANSFER)) return;
+    if (ui->disk.graph_mode == graph_mode) return;
+
+    ui->disk.graph_mode = graph_mode;
+    evisum_ui_config_save(ui);
+    if (ui->disk.win) evisum_ui_disk_win_restart(ui);
+}
+
 static void
 _main_menu_slider_poll_delay_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) {
     Evisum_Ui *ui = data;
@@ -577,6 +595,45 @@ evisum_ui_main_menu_create(Evisum_Ui *ui, Evas_Object *parent, Evas_Object *obj)
         return o;
     }
 
+    if (parent == ui->disk.win) {
+        options_fr = elm_frame_add(o);
+        elm_object_text_set(options_fr, _("Storage Graph"));
+        evas_object_size_hint_weight_set(options_fr, EXPAND, EXPAND);
+        evas_object_size_hint_align_set(options_fr, FILL, FILL);
+        evas_object_show(options_fr);
+
+        hbx = elm_box_add(o);
+        evas_object_size_hint_weight_set(hbx, EXPAND, 0);
+        evas_object_size_hint_align_set(hbx, FILL, FILL);
+        elm_box_horizontal_set(hbx, 1);
+        evas_object_show(hbx);
+
+        radio_group = radio = elm_radio_add(hbx);
+        elm_object_text_set(radio, _("Usage"));
+        elm_radio_state_value_set(radio, EVISUM_DISK_GRAPH_USAGE);
+        evas_object_size_hint_weight_set(radio, EXPAND, EXPAND);
+        evas_object_size_hint_align_set(radio, FILL, FILL);
+        evas_object_smart_callback_add(radio, "changed", _main_menu_disk_graph_mode_changed_cb, ui);
+        elm_box_pack_end(hbx, radio);
+        evas_object_show(radio);
+
+        radio = elm_radio_add(hbx);
+        elm_object_text_set(radio, _("Transfer"));
+        elm_radio_state_value_set(radio, EVISUM_DISK_GRAPH_TRANSFER);
+        elm_radio_group_add(radio, radio_group);
+        evas_object_size_hint_weight_set(radio, EXPAND, EXPAND);
+        evas_object_size_hint_align_set(radio, FILL, FILL);
+        evas_object_smart_callback_add(radio, "changed", _main_menu_disk_graph_mode_changed_cb, ui);
+        elm_box_pack_end(hbx, radio);
+        evas_object_show(radio);
+        elm_radio_value_set(radio_group, ui->disk.graph_mode);
+
+        elm_object_content_set(options_fr, hbx);
+        elm_box_pack_end(obx, options_fr);
+
+        return o;
+    }
+
     if (parent != ui->proc.win) return o;
 
     options_fr = elm_frame_add(o);
diff --git a/src/bin/ui/evisum_ui.h b/src/bin/ui/evisum_ui.h
index cfa84d9..235aa59 100644
--- a/src/bin/ui/evisum_ui.h
+++ b/src/bin/ui/evisum_ui.h
@@ -83,6 +83,7 @@ typedef struct _Evisum_Ui {
         int height;
         int x, y;
         Eina_Bool restart;
+        int graph_mode;
     } disk;
 
     struct {
diff --git a/src/bin/ui/evisum_ui_disk.c b/src/bin/ui/evisum_ui_disk.c
index 626bf8e..571729c 100644
--- a/src/bin/ui/evisum_ui_disk.c
+++ b/src/bin/ui/evisum_ui_disk.c
@@ -2,6 +2,7 @@
 #include "evisum_ui_graph.h"
 #include "../engine/evisum_engine.h"
 #include "../background/evisum_background.h"
+#include "../evisum_config.h"
 #include "config.h"
 #include "evisum_ui_colors.h"
 
@@ -16,6 +17,7 @@ typedef struct {
     Eina_Bool skip_wait;
     Eina_List *history;
     Eina_Bool btn_visible;
+    double graph_peak;
 
     Evisum_Ui *ui;
 } Evisum_Ui_Disk_View;
@@ -24,24 +26,37 @@ typedef struct {
 #define DISK_GRID_X_STEP_SAMPLES 5
 #define DISK_GRID_Y_STEP_PERCENT 10
 
+typedef enum {
+    DISK_LINE_USAGE,
+    DISK_LINE_READ,
+    DISK_LINE_WRITE,
+    DISK_LINE_MAX
+} Disk_Line;
+
 typedef struct {
     char *key;
     char *name;
-    uint8_t color_r;
-    uint8_t color_g;
-    uint8_t color_b;
-    double history[DISK_GRAPH_SAMPLES];
-    int history_count;
+    uint8_t color_r[DISK_LINE_MAX];
+    uint8_t color_g[DISK_LINE_MAX];
+    uint8_t color_b[DISK_LINE_MAX];
+    double history[DISK_LINE_MAX][DISK_GRAPH_SAMPLES];
+    int history_count[DISK_LINE_MAX];
     Eina_Bool seen;
-    Eina_Bool enabled;
+    Eina_Bool enabled[DISK_LINE_MAX];
     Evisum_Ui_Disk_View *view;
-    Evas_Object *legend_row;
-    Evas_Object *legend_btn;
-    Evas_Object *legend_swatch;
-    Evas_Object *legend_label;
-    Evas_Object *legend_pb;
+    Evas_Object *legend_row[DISK_LINE_MAX];
+    Evas_Object *legend_btn[DISK_LINE_MAX];
+    Evas_Object *legend_swatch[DISK_LINE_MAX];
+    Evas_Object *legend_label[DISK_LINE_MAX];
+    Evas_Object *legend_pb[DISK_LINE_MAX];
+    void *legend_data[DISK_LINE_MAX];
 } Disk_History;
 
+typedef struct {
+    Disk_History *entry;
+    Disk_Line line;
+} Disk_Legend_Data;
+
 static void _evisum_ui_disk_graph_redraw(Evisum_Ui_Disk_View *view);
 static const Evisum_Ui_Graph_Layer _disk_layers[] = {
     { -0.6, 0.24 },
@@ -55,29 +70,51 @@ _evisum_ui_disk_graph_objects_valid(Evisum_Ui_Disk_View *view) {
            && evas_object_evas_get(view->graph_img);
 }
 
+static Eina_Bool
+_evisum_ui_disk_transfer_mode_get(Evisum_Ui_Disk_View *view) {
+    return view && view->ui && (view->ui->disk.graph_mode == EVISUM_DISK_GRAPH_TRANSFER);
+}
+
 static void
-_evisum_ui_disk_legend_toggle_state_apply(Disk_History *entry) {
+_evisum_ui_disk_legend_toggle_state_apply(Disk_History *entry, Disk_Line line) {
     if (!entry) return;
 
-    if (!entry->enabled && entry->legend_swatch) evas_object_hide(entry->legend_swatch);
-    else if (entry->enabled && entry->legend_swatch) evas_object_show(entry->legend_swatch);
+    if (!entry->enabled[line] && entry->legend_swatch[line]) evas_object_hide(entry->legend_swatch[line]);
+    else if (entry->enabled[line] && entry->legend_swatch[line]) evas_object_show(entry->legend_swatch[line]);
 
-    if (entry->legend_pb && evas_object_evas_get(entry->legend_pb))
-        elm_object_disabled_set(entry->legend_pb, !entry->enabled);
-    else entry->legend_pb = NULL;
+    if ((line == DISK_LINE_READ) || (line == DISK_LINE_WRITE)) {
+        if (entry->legend_pb[DISK_LINE_READ] && evas_object_evas_get(entry->legend_pb[DISK_LINE_READ]))
+            elm_object_disabled_set(entry->legend_pb[DISK_LINE_READ],
+                                    !entry->enabled[DISK_LINE_READ] && !entry->enabled[DISK_LINE_WRITE]);
+        else entry->legend_pb[DISK_LINE_READ] = NULL;
+    } else if (entry->legend_pb[line] && evas_object_evas_get(entry->legend_pb[line]))
+        elm_object_disabled_set(entry->legend_pb[line], !entry->enabled[line]);
+    else entry->legend_pb[line] = NULL;
 }
 
 static void
 _evisum_ui_disk_legend_toggle_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) {
-    Disk_History *entry = data;
+    Disk_Legend_Data *legend = data;
+    Disk_History *entry;
 
-    if (!entry || !entry->view || !entry->legend_btn || !entry->legend_row) return;
+    if (!legend) return;
+    entry = legend->entry;
+    if (!entry || !entry->view || !entry->legend_btn[legend->line]) return;
+    if (!entry->legend_row[legend->line] && !entry->legend_row[DISK_LINE_READ]) return;
     if (!_evisum_ui_disk_graph_objects_valid(entry->view)) return;
-    entry->enabled = !entry->enabled;
-    _evisum_ui_disk_legend_toggle_state_apply(entry);
+    entry->enabled[legend->line] = !entry->enabled[legend->line];
+    _evisum_ui_disk_legend_toggle_state_apply(entry, legend->line);
     _evisum_ui_disk_graph_redraw(entry->view);
 }
 
+static Eina_Bool
+_evisum_ui_disk_line_visible(Evisum_Ui_Disk_View *view, Disk_Line line) {
+    if (_evisum_ui_disk_transfer_mode_get(view))
+        return (line == DISK_LINE_READ) || (line == DISK_LINE_WRITE);
+
+    return line == DISK_LINE_USAGE;
+}
+
 static void
 _evisum_ui_disk_history_legend_repack(Evisum_Ui_Disk_View *view) {
     Eina_List *l;
@@ -89,30 +126,88 @@ _evisum_ui_disk_history_legend_repack(Evisum_Ui_Disk_View *view) {
     elm_table_clear(view->legend_tb, 0);
 
     EINA_LIST_FOREACH(view->history, l, entry) {
-        if (!entry->legend_row || !entry->legend_pb) continue;
-        elm_table_pack(view->legend_tb, entry->legend_row, 0, row, 1, 1);
-        elm_table_pack(view->legend_tb, entry->legend_pb, 1, row, 1, 1);
-        evas_object_show(entry->legend_row);
-        evas_object_show(entry->legend_pb);
-        row++;
+        if (_evisum_ui_disk_transfer_mode_get(view)) {
+            if (!entry->legend_row[DISK_LINE_READ] || !entry->legend_pb[DISK_LINE_READ]) continue;
+            elm_table_pack(view->legend_tb, entry->legend_row[DISK_LINE_READ], 0, row, 1, 1);
+            elm_table_pack(view->legend_tb, entry->legend_pb[DISK_LINE_READ], 1, row, 1, 1);
+            evas_object_show(entry->legend_row[DISK_LINE_READ]);
+            evas_object_show(entry->legend_pb[DISK_LINE_READ]);
+            row++;
+        } else {
+            if (!entry->legend_row[DISK_LINE_USAGE] || !entry->legend_pb[DISK_LINE_USAGE]) continue;
+            elm_table_pack(view->legend_tb, entry->legend_row[DISK_LINE_USAGE], 0, row, 1, 1);
+            elm_table_pack(view->legend_tb, entry->legend_pb[DISK_LINE_USAGE], 1, row, 1, 1);
+            evas_object_show(entry->legend_row[DISK_LINE_USAGE]);
+            evas_object_show(entry->legend_pb[DISK_LINE_USAGE]);
+            row++;
+        }
     }
 }
 
 static void
-_evisum_ui_disk_history_add_sample(Disk_History *entry, double value) {
-    if (entry->history_count < DISK_GRAPH_SAMPLES) entry->history[entry->history_count++] = value;
+_evisum_ui_disk_history_add_sample(Disk_History *entry, Disk_Line line, double value) {
+    if (entry->history_count[line] < DISK_GRAPH_SAMPLES) entry->history[line][entry->history_count[line]++] = value;
     else {
-        memmove(&entry->history[0], &entry->history[1], sizeof(double) * (DISK_GRAPH_SAMPLES - 1));
-        entry->history[DISK_GRAPH_SAMPLES - 1] = value;
+        memmove(&entry->history[line][0], &entry->history[line][1], sizeof(double) * (DISK_GRAPH_SAMPLES - 1));
+        entry->history[line][DISK_GRAPH_SAMPLES - 1] = value;
     }
 }
 
 static void
-_evisum_ui_disk_history_legend_add(Evisum_Ui_Disk_View *view, Disk_History *entry) {
-    Evas_Object *left, *swatch, *lb, *pb, *btn;
+_evisum_ui_disk_history_seed_zero(Evisum_Ui_Disk_View *view, Disk_History *entry) {
+    for (Disk_Line line = DISK_LINE_USAGE; line < DISK_LINE_MAX; line++) {
+        if (!_evisum_ui_disk_line_visible(view, line)) continue;
+        if (entry->history_count[line]) continue;
+        _evisum_ui_disk_history_add_sample(entry, line, 0.0);
+    }
+}
+
+static void
+_evisum_ui_disk_legend_swatch_add(Disk_History *entry, Disk_Line line, Evas_Object *left) {
+    Evas_Object *btn, *swatch;
+    Disk_Legend_Data *legend;
     Evas *evas;
 
-    if (!view->legend_tb || entry->legend_row) return;
+    if (!entry || !left || entry->legend_btn[line]) return;
+
+    evas = evas_object_evas_get(left);
+    btn = elm_button_add(left);
+    evas_object_size_hint_min_set(btn, 16 * elm_config_scale_get(), 16 * elm_config_scale_get());
+    evas_object_size_hint_max_set(btn, 16 * elm_config_scale_get(), 16 * elm_config_scale_get());
+    evas_object_size_hint_align_set(btn, 0.0, 0.5);
+    evas_object_show(btn);
+    legend = calloc(1, sizeof(*legend));
+    if (legend) {
+        legend->entry = entry;
+        legend->line = line;
+        entry->legend_data[line] = legend;
+        evas_object_smart_callback_add(btn, "clicked", _evisum_ui_disk_legend_toggle_cb, legend);
+    }
+    elm_box_pack_end(left, btn);
+
+    swatch = evas_object_rectangle_add(evas);
+    evas_object_color_set(swatch, entry->color_r[line], entry->color_g[line], entry->color_b[line], 255);
+    evas_object_size_hint_min_set(swatch, 12 * elm_config_scale_get(), 12 * elm_config_scale_get());
+    evas_object_size_hint_max_set(swatch, 12 * elm_config_scale_get(), 12 * elm_config_scale_get());
+    evas_object_size_hint_align_set(swatch, 0.0, 0.5);
+    elm_object_content_set(btn, swatch);
+    evas_object_show(swatch);
+
+    entry->legend_btn[line] = btn;
+    entry->legend_swatch[line] = swatch;
+    _evisum_ui_disk_legend_toggle_state_apply(entry, line);
+}
+
+static void
+_evisum_ui_disk_history_legend_add(Evisum_Ui_Disk_View *view, Disk_History *entry, Disk_Line line) {
+    Evas_Object *left, *lb, *pb;
+
+    if (!view->legend_tb) return;
+
+    if (_evisum_ui_disk_transfer_mode_get(view)) {
+        line = DISK_LINE_READ;
+        if (entry->legend_row[line]) return;
+    } else if (entry->legend_row[line]) return;
 
     left = elm_box_add(view->legend_tb);
     elm_box_horizontal_set(left, EINA_TRUE);
@@ -121,22 +216,10 @@ _evisum_ui_disk_history_legend_add(Evisum_Ui_Disk_View *view, Disk_History *entr
     evas_object_size_hint_align_set(left, EVAS_HINT_FILL, 0.5);
     evas_object_show(left);
 
-    evas = evas_object_evas_get(left);
-    btn = elm_button_add(left);
-    evas_object_size_hint_min_set(btn, 16 * elm_config_scale_get(), 16 * elm_config_scale_get());
-    evas_object_size_hint_max_set(btn, 16 * elm_config_scale_get(), 16 * elm_config_scale_get());
-    evas_object_size_hint_align_set(btn, 0.0, 0.5);
-    evas_object_show(btn);
-    evas_object_smart_callback_add(btn, "clicked", _evisum_ui_disk_legend_toggle_cb, entry);
-    elm_box_pack_end(left, btn);
-
-    swatch = evas_object_rectangle_add(evas);
-    evas_object_color_set(swatch, entry->color_r, entry->color_g, entry->color_b, 255);
-    evas_object_size_hint_min_set(swatch, 12 * elm_config_scale_get(), 12 * elm_config_scale_get());
-    evas_object_size_hint_max_set(swatch, 12 * elm_config_scale_get(), 12 * elm_config_scale_get());
-    evas_object_size_hint_align_set(swatch, 0.0, 0.5);
-    elm_object_content_set(btn, swatch);
-    evas_object_show(swatch);
+    if (_evisum_ui_disk_transfer_mode_get(view)) {
+        _evisum_ui_disk_legend_swatch_add(entry, DISK_LINE_READ, left);
+        _evisum_ui_disk_legend_swatch_add(entry, DISK_LINE_WRITE, left);
+    } else _evisum_ui_disk_legend_swatch_add(entry, DISK_LINE_USAGE, left);
 
     lb = elm_label_add(left);
     evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
@@ -153,35 +236,65 @@ _evisum_ui_disk_history_legend_add(Evisum_Ui_Disk_View *view, Disk_History *entr
     evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
     evas_object_show(pb);
 
-    entry->legend_row = left;
-    entry->legend_btn = btn;
-    entry->legend_swatch = swatch;
-    entry->legend_label = lb;
-    entry->legend_pb = pb;
-    _evisum_ui_disk_legend_toggle_state_apply(entry);
+    entry->legend_row[line] = left;
+    entry->legend_label[line] = lb;
+    entry->legend_pb[line] = pb;
     _evisum_ui_disk_history_legend_repack(view);
 }
 
 static void
 _evisum_ui_disk_history_legend_del(Disk_History *entry) {
-    if (entry->legend_pb) evas_object_del(entry->legend_pb);
-    if (entry->legend_row) evas_object_del(entry->legend_row);
+    for (Disk_Line line = DISK_LINE_USAGE; line < DISK_LINE_MAX; line++) {
+        if (entry->legend_pb[line]) evas_object_del(entry->legend_pb[line]);
+        if (entry->legend_row[line]) evas_object_del(entry->legend_row[line]);
+        free(entry->legend_data[line]);
+        entry->legend_row[line] = NULL;
+        entry->legend_btn[line] = NULL;
+        entry->legend_swatch[line] = NULL;
+        entry->legend_label[line] = NULL;
+        entry->legend_pb[line] = NULL;
+        entry->legend_data[line] = NULL;
+    }
     entry->view = NULL;
-    entry->legend_row = NULL;
-    entry->legend_btn = NULL;
-    entry->legend_swatch = NULL;
-    entry->legend_label = NULL;
-    entry->legend_pb = NULL;
 }
 
 static void
-_evisum_ui_disk_history_legend_update(Disk_History *entry, double used_percent, int64_t used, int64_t total) {
-    if (!entry->legend_pb || !entry->legend_label) return;
+_evisum_ui_disk_transfer_format(char *buf, size_t buflen, uint64_t rate) {
+    if (!buf || !buflen) return;
 
-    elm_object_text_set(entry->legend_label, entry->name ? entry->name : entry->key);
-    elm_progressbar_value_set(entry->legend_pb, used_percent / 100.0);
-    elm_progressbar_unit_format_set(
-            entry->legend_pb, eina_slstr_printf("%s / %s", evisum_size_format(used, 0), evisum_size_format(total, 0)));
+    snprintf(buf, buflen, "%s/s", evisum_size_format(rate, 0));
+}
+
+static void
+_evisum_ui_disk_history_legend_update(Disk_History *entry, const File_System *fs, double used_percent,
+                                      double transfer_peak) {
+    if (entry->view && _evisum_ui_disk_transfer_mode_get(entry->view)) {
+        char read_buf[64];
+        char write_buf[64];
+
+        if (transfer_peak < 1.0) transfer_peak = 1.0;
+        _evisum_ui_disk_transfer_format(read_buf, sizeof(read_buf), fs->usage.read);
+        _evisum_ui_disk_transfer_format(write_buf, sizeof(write_buf), fs->usage.write);
+
+        if (entry->legend_label[DISK_LINE_READ])
+            elm_object_text_set(entry->legend_label[DISK_LINE_READ], entry->name ? entry->name : entry->key);
+        if (entry->legend_pb[DISK_LINE_READ]) {
+            double value = fs->usage.read > fs->usage.write ? (double) fs->usage.read : (double) fs->usage.write;
+
+            elm_progressbar_value_set(entry->legend_pb[DISK_LINE_READ], value / transfer_peak);
+            elm_progressbar_unit_format_set(entry->legend_pb[DISK_LINE_READ],
+                                            eina_slstr_printf(_("Read %s | Write %s"), read_buf, write_buf));
+        }
+    } else {
+        if (entry->legend_label[DISK_LINE_USAGE])
+            elm_object_text_set(entry->legend_label[DISK_LINE_USAGE], entry->name ? entry->name : entry->key);
+        if (entry->legend_pb[DISK_LINE_USAGE]) {
+            elm_progressbar_value_set(entry->legend_pb[DISK_LINE_USAGE], used_percent / 100.0);
+            elm_progressbar_unit_format_set(entry->legend_pb[DISK_LINE_USAGE],
+                                            eina_slstr_printf("%s / %s", evisum_size_format(fs->usage.used, 0),
+                                                              evisum_size_format(fs->usage.total, 0)));
+        }
+    }
 }
 
 static Disk_History *
@@ -227,10 +340,16 @@ _evisum_ui_disk_history_find_or_create(Evisum_Ui_Disk_View *view, const File_Sys
 
     entry->name = strdup(fs->mount);
     if (!entry->name) entry->name = strdup(fs->path);
-    entry->enabled = EINA_TRUE;
+    for (Disk_Line line = DISK_LINE_USAGE; line < DISK_LINE_MAX; line++)
+        entry->enabled[line] = EINA_TRUE;
     entry->view = view;
 
-    evisum_graph_color_get(entry->key, &entry->color_r, &entry->color_g, &entry->color_b);
+    evisum_graph_color_get(entry->key, &entry->color_r[DISK_LINE_USAGE], &entry->color_g[DISK_LINE_USAGE],
+                           &entry->color_b[DISK_LINE_USAGE]);
+    evisum_graph_color_get(eina_slstr_printf("%s|read", entry->key), &entry->color_r[DISK_LINE_READ],
+                           &entry->color_g[DISK_LINE_READ], &entry->color_b[DISK_LINE_READ]);
+    evisum_graph_color_get(eina_slstr_printf("%s|write", entry->key), &entry->color_r[DISK_LINE_WRITE],
+                           &entry->color_g[DISK_LINE_WRITE], &entry->color_b[DISK_LINE_WRITE]);
 
     view->history = eina_list_append(view->history, entry);
     if (created) *created = EINA_TRUE;
@@ -260,9 +379,13 @@ _evisum_ui_disk_history_reset(Evisum_Ui_Disk_View *view) {
     Disk_History *entry;
 
     EINA_LIST_FOREACH(view->history, l, entry) {
-        entry->history_count = 0;
-        memset(entry->history, 0, sizeof(entry->history));
+        for (Disk_Line line = DISK_LINE_USAGE; line < DISK_LINE_MAX; line++) {
+            entry->history_count[line] = 0;
+            memset(entry->history[line], 0, sizeof(entry->history[line]));
+        }
+        _evisum_ui_disk_history_seed_zero(view, entry);
     }
+    view->graph_peak = 0.0;
 }
 
 static void
@@ -274,23 +397,27 @@ _evisum_ui_disk_graph_redraw(Evisum_Ui_Disk_View *view) {
 
     if (!_evisum_ui_disk_graph_objects_valid(view)) return;
 
-    total = eina_list_count(view->history);
+    total = eina_list_count(view->history) * (_evisum_ui_disk_transfer_mode_get(view) ? 2 : 1);
     nseries = 0;
     series = calloc(total, sizeof(Evisum_Ui_Graph_Series));
     if ((total > 0) && (!series)) return;
 
     EINA_LIST_FOREACH(view->history, l, entry) {
-        if (!entry->enabled || (entry->history_count < 2)) continue;
-        series[nseries].history = entry->history;
-        series[nseries].history_count = entry->history_count;
-        series[nseries].color_r = entry->color_r;
-        series[nseries].color_g = entry->color_g;
-        series[nseries].color_b = entry->color_b;
-        nseries++;
+        for (Disk_Line line = DISK_LINE_USAGE; line < DISK_LINE_MAX; line++) {
+            if (!_evisum_ui_disk_line_visible(view, line)) continue;
+            if (!entry->enabled[line] || (entry->history_count[line] < 2)) continue;
+            series[nseries].history = entry->history[line];
+            series[nseries].history_count = entry->history_count[line];
+            series[nseries].color_r = entry->color_r[line];
+            series[nseries].color_g = entry->color_g[line];
+            series[nseries].color_b = entry->color_b[line];
+            nseries++;
+        }
     }
 
     evisum_ui_graph_draw(view->graph_bg, view->graph_img, DISK_GRAPH_SAMPLES, DISK_GRID_X_STEP_SAMPLES,
-                         DISK_GRID_Y_STEP_PERCENT, 100.0, series, nseries, _disk_layers,
+                         DISK_GRID_Y_STEP_PERCENT,
+                         view->ui->disk.graph_mode == EVISUM_DISK_GRAPH_TRANSFER ? view->graph_peak : 100.0, series, nseries, _disk_layers,
                          EINA_C_ARRAY_LENGTH(_disk_layers));
     free(series);
 }
@@ -345,6 +472,7 @@ _evisum_ui_disk_disks_poll_feedback_cb(void *data, Ecore_Thread *thread EINA_UNU
         entry = _evisum_ui_disk_history_find_or_create(view, fs, &created);
         if (!entry) continue;
         if (created) graph_reset_needed = EINA_TRUE;
+        if (created) _evisum_ui_disk_history_seed_zero(view, entry);
     }
 
     if (graph_reset_needed) {
@@ -352,6 +480,17 @@ _evisum_ui_disk_disks_poll_feedback_cb(void *data, Ecore_Thread *thread EINA_UNU
         evisum_ui_graph_reset(view->graph_img);
     }
 
+    if (_evisum_ui_disk_transfer_mode_get(view)) {
+        EINA_LIST_FOREACH(mounted, l, fs) {
+            double read = (double) fs->usage.read;
+            double write = (double) fs->usage.write;
+
+            if (read > view->graph_peak) view->graph_peak = read;
+            if (write > view->graph_peak) view->graph_peak = write;
+        }
+        if (view->graph_peak < 1.0) view->graph_peak = 1.0;
+    }
+
     EINA_LIST_FOREACH(mounted, l, fs) {
         double used_percent = 0.0;
 
@@ -363,9 +502,17 @@ _evisum_ui_disk_disks_poll_feedback_cb(void *data, Ecore_Thread *thread EINA_UNU
         if (used_percent < 0.0) used_percent = 0.0;
         if (used_percent > 100.0) used_percent = 100.0;
 
-        _evisum_ui_disk_history_add_sample(entry, used_percent);
-        _evisum_ui_disk_history_legend_add(view, entry);
-        _evisum_ui_disk_history_legend_update(entry, used_percent, fs->usage.used, fs->usage.total);
+        if (_evisum_ui_disk_transfer_mode_get(view)) {
+            _evisum_ui_disk_history_add_sample(entry, DISK_LINE_READ, (double) fs->usage.read);
+            _evisum_ui_disk_history_add_sample(entry, DISK_LINE_WRITE, (double) fs->usage.write);
+            _evisum_ui_disk_history_legend_add(view, entry, DISK_LINE_READ);
+            _evisum_ui_disk_history_legend_add(view, entry, DISK_LINE_WRITE);
+        } else {
+            _evisum_ui_disk_history_add_sample(entry, DISK_LINE_USAGE, used_percent);
+            _evisum_ui_disk_history_legend_add(view, entry, DISK_LINE_USAGE);
+        }
+
+        _evisum_ui_disk_history_legend_update(entry, fs, used_percent, view->graph_peak);
         entry->seen = EINA_TRUE;
     }
     _evisum_ui_disk_history_compact(view);
@@ -580,3 +727,13 @@ evisum_ui_disk_win_add(Evisum_Ui *ui) {
     view->thread = ecore_thread_feedback_run(_evisum_ui_disk_disks_poll, _evisum_ui_disk_disks_poll_feedback_cb, NULL,
                                              NULL, view, 1);
 }
+
+void
+evisum_ui_disk_win_restart(Evisum_Ui *ui) {
+    if (!ui || !ui->disk.win) return;
+
+    elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_NONE);
+    evas_object_del(ui->disk.win);
+    elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+    evisum_ui_disk_win_add(ui);
+}
diff --git a/src/bin/ui/evisum_ui_disk.h b/src/bin/ui/evisum_ui_disk.h
index 088fd0c..f3cd149 100644
--- a/src/bin/ui/evisum_ui_disk.h
+++ b/src/bin/ui/evisum_ui_disk.h
@@ -5,4 +5,6 @@
 
 void evisum_ui_disk_win_add(Evisum_Ui *ui);
 
+void evisum_ui_disk_win_restart(Evisum_Ui *ui);
+
 #endif

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

Reply via email to