[gnome-usage/pstetka/gnome-usage-disk-io: 6/7] disk-subview: Add UI for disk-io monitoring
- From: Petr Štětka <pstetka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-usage/pstetka/gnome-usage-disk-io: 6/7] disk-subview: Add UI for disk-io monitoring
- Date: Tue, 9 Apr 2019 12:56:22 +0000 (UTC)
commit 836b83fa678775b91932d867f9d59a284e6eb3db
Author: Petr Štětka <pstetka redhat com>
Date: Mon Sep 11 16:04:16 2017 +0200
disk-subview: Add UI for disk-io monitoring
Add subview and graph for disk-io monitoring.
https://bugzilla.gnome.org/show_bug.cgi?id=787549
data/org.gnome.Usage.gresource.xml | 1 +
data/ui/disk-sub-view.ui | 90 ++++++++++++++++++++++++++++++
src/application.vala | 10 ++++
src/disk-graph-model.vala | 92 +++++++++++++++++++++++++++++++
src/disk-graph.vala | 109 +++++++++++++++++++++++++++++++++++++
src/disk-sub-view.vala | 53 ++++++++++++++++++
src/graph-stack-switcher.vala | 3 +-
src/graph-switcher-button.vala | 6 ++
src/memory-sub-view.vala | 3 +-
src/meson.build | 3 +
src/performance-view.vala | 3 +-
src/process-list-box.vala | 37 ++++++++++---
src/process-row.vala | 3 +
13 files changed, 402 insertions(+), 11 deletions(-)
---
diff --git a/data/org.gnome.Usage.gresource.xml b/data/org.gnome.Usage.gresource.xml
index e793a36..0887342 100644
--- a/data/org.gnome.Usage.gresource.xml
+++ b/data/org.gnome.Usage.gresource.xml
@@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/Usage">
<file compressed="true">interface/adwaita.css</file>
<file preprocess="xml-stripblanks">ui/primary-menu.ui</file>
+ <file preprocess="xml-stripblanks">ui/disk-sub-view.ui</file>
<file preprocess="xml-stripblanks">ui/header-bar.ui</file>
<file preprocess="xml-stripblanks">ui/memory-speedometer.ui</file>
<file preprocess="xml-stripblanks">ui/no-results-found-view.ui</file>
diff --git a/data/ui/disk-sub-view.ui b/data/ui/disk-sub-view.ui
new file mode 100644
index 0000000..82d209f
--- /dev/null
+++ b/data/ui/disk-sub-view.ui
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.9"/>
+ <template class="UsageDiskSubView" parent="UsageView">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="halign">center</property>
+ <property name="margin_bottom">30</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Disk I/O</property>
+ <property name="use_markup">True</property>
+ <property name="margin_bottom">15</property>
+ <attributes>
+ <attribute name="scale" value="1.2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="UsageGraphBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="height_request">225</property>
+ <property name="width_request">600</property>
+ <property name="valign">start</property>
+ <style>
+ <class name="graph-box"/>
+ </style>
+ <child>
+ <object class="UsageDiskGraphBig">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">true</property>
+ <property name="fill">true</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">True</property>
+ <property name="margin_top">30</property>
+ <property name="height_request">250</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="UsageNoResultsFoundView" id="no_process_view"></object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="UsageProcessListBox" id="process_list_box">
+ <property name="margin_top">30</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/application.vala b/src/application.vala
index 4d2579a..d478ee2 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -49,6 +49,7 @@ namespace Usage
if (window != null)
return;
+ ensure_types();
window = new Window(this);
set_accels_for_action("app.quit", {"<Primary>q"});
@@ -63,6 +64,15 @@ namespace Usage
set_accels_for_action ("app.search", {"<Primary>f"});
}
+ private void ensure_types()
+ {
+ var disk_graph = typeof (Usage.DiskGraphBig);
+ disk_graph.ensure();
+
+ var disk_sub_view = typeof (Usage.DiskSubView);
+ disk_sub_view.ensure();
+ }
+
private void on_about(GLib.SimpleAction action, GLib.Variant? parameter)
{
string[] authors = {
diff --git a/src/disk-graph-model.vala b/src/disk-graph-model.vala
new file mode 100644
index 0000000..3d6891f
--- /dev/null
+++ b/src/disk-graph-model.vala
@@ -0,0 +1,92 @@
+/* disk-graph-model.vala
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Petr Štětka <pstetka redhat com>
+ */
+
+using Dazzle;
+
+namespace Usage {
+
+ public class DiskGraphModel : GraphModel {
+ public const int COLUMN_READ_ID = 0;
+ public const int COLUMN_WRITE_ID = 1;
+
+ private const double MIN_VALUE = 10;
+ private const double GROW_UP_FACTOR = 1.5;
+ private const double GROW_DOWN_LIMIT = 4;
+
+ private double max_value = MIN_VALUE;
+
+ construct {
+ var settings = Settings.get_default();
+ set_timespan (settings.graph_timespan * 1000);
+ set_max_samples (settings.graph_max_samples);
+
+ var column_download = new GraphColumn("READ", Type.from_name("gdouble"));
+ add_column(column_download);
+ var column_upload = new GraphColumn("WRITE", Type.from_name("gdouble"));
+ add_column(column_upload);
+
+ Timeout.add(settings.graph_update_interval, update_data);
+ }
+
+ bool update_data() {
+ GraphModelIter iter;
+ push (out iter, get_monotonic_time ());
+
+ SystemMonitor monitor = SystemMonitor.get_default();
+
+ double disk_read = monitor.disk_read;
+ double disk_write = monitor.disk_write;
+
+ iter_set_value(iter, COLUMN_READ_ID, disk_read);
+ iter_set_value(iter, COLUMN_WRITE_ID, disk_write);
+
+ double max_iter_value_read = get_max_iter_val(COLUMN_READ_ID);
+ double max_iter_value_write = get_max_iter_val(COLUMN_WRITE_ID);
+ double max_actual_iter_value = max_iter_value_read > max_iter_value_write ? max_iter_value_read
: max_iter_value_write;
+
+ if(max_actual_iter_value > max_value || max_actual_iter_value < (max_value / GROW_DOWN_LIMIT))
+ max_value = max_actual_iter_value * GROW_UP_FACTOR;
+
+ if(max_value < MIN_VALUE)
+ max_value = MIN_VALUE;
+
+ this.value_max = max_value;
+
+ return true;
+ }
+
+ double get_max_iter_val (uint column_index) {
+ double max_value = 0.0;
+ GraphModelIter iter;
+
+ if (get_iter_first (out iter)) {
+ var val = iter_get_value(iter, column_index);
+ max_value = val.get_double();
+
+ while (iter_next (ref iter)) {
+ var val_next = iter_get_value(iter, column_index);
+ max_value = val_next.get_double() > max_value ? val_next.get_double() : max_value;
+ }
+ }
+
+ return max_value;
+ }
+ }
+}
diff --git a/src/disk-graph.vala b/src/disk-graph.vala
new file mode 100644
index 0000000..fdd377b
--- /dev/null
+++ b/src/disk-graph.vala
@@ -0,0 +1,109 @@
+/* disk-graph.vala
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Petr Štětka <pstetka redhat com>
+ */
+
+using Dazzle;
+
+namespace Usage
+{
+ public class DiskGraph : GraphView
+ {
+ private const double LINE_WIDTH = 1.2;
+ private static DiskGraphModel graph_model;
+
+ class construct {
+ set_css_name("rg-graph");
+ }
+
+ construct {
+ get_style_context().add_class("line");
+ var color_line_read = get_style_context().get_color(get_style_context().get_state());
+ get_style_context().remove_class("line");
+
+ get_style_context().add_class("stacked");
+ var color_read = get_style_context().get_color(get_style_context().get_state());
+ get_style_context().remove_class("stacked");
+
+ get_style_context().add_class("line_orange");
+ var color_line_write = get_style_context().get_color(get_style_context().get_state());
+ get_style_context().remove_class("line_orange");
+
+ get_style_context().add_class("stacked_orange");
+ var color_write = get_style_context().get_color(get_style_context().get_state());
+ get_style_context().remove_class("stacked_orange");
+
+ if(graph_model == null)
+ graph_model = new DiskGraphModel();
+
+ set_model(graph_model);
+
+ var renderer_read = new GraphStackedRenderer();
+ renderer_read.column = DiskGraphModel.COLUMN_READ_ID;
+ renderer_read.stroke_color_rgba = color_line_read;
+ renderer_read.stacked_color_rgba = color_read;
+ renderer_read.line_width = LINE_WIDTH;
+ add_renderer(renderer_read);
+
+ var renderer_write = new GraphStackedRenderer();
+ renderer_write.column = DiskGraphModel.COLUMN_WRITE_ID;
+ renderer_write.stroke_color_rgba = color_line_write;
+ renderer_write.stacked_color_rgba = color_write;
+ renderer_write.line_width = LINE_WIDTH;
+ add_renderer(renderer_write);
+ }
+ }
+
+ public class DiskGraphBig : GraphView {
+ private static DiskGraphModel graph_model;
+ private const double LINE_WIDTH = 1.5;
+
+ class construct {
+ set_css_name("rg-graph");
+ }
+
+ construct {
+ get_style_context().add_class("line");
+ var color_read = get_style_context().get_color(get_style_context().get_state());
+ get_style_context().remove_class("line");
+
+ get_style_context().add_class("line_orange");
+ var color_write = get_style_context().get_color(get_style_context().get_state());
+ get_style_context().remove_class("line_orange");
+
+ get_style_context().add_class("big");
+
+ if(graph_model == null)
+ graph_model = new DiskGraphModel();
+
+ set_model(graph_model);
+
+ var renderer_read = new GraphLineRenderer();
+ renderer_read.column = DiskGraphModel.COLUMN_READ_ID;
+ renderer_read.stroke_color_rgba = color_read;
+ renderer_read.line_width = LINE_WIDTH;
+ add_renderer(renderer_read);
+
+ var renderer_write = new GraphLineRenderer();
+ renderer_write.column = DiskGraphModel.COLUMN_WRITE_ID;
+ renderer_write.stroke_color_rgba = color_write;
+ renderer_write.line_width = LINE_WIDTH;
+ add_renderer(renderer_write);
+ }
+ }
+}
diff --git a/src/disk-sub-view.vala b/src/disk-sub-view.vala
new file mode 100644
index 0000000..cc5eccf
--- /dev/null
+++ b/src/disk-sub-view.vala
@@ -0,0 +1,53 @@
+/* disk-sub-view.vala
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Petr Štětka <pstetka redhat com>
+ */
+
+namespace Usage
+{
+ [GtkTemplate (ui = "/org/gnome/Usage/ui/disk-sub-view.ui")]
+ public class DiskSubView : View, SubView {
+ [GtkChild]
+ private Gtk.Spinner spinner;
+
+ [GtkChild]
+ private NoResultsFoundView no_process_view;
+
+ [GtkChild]
+ private Usage.ProcessListBox process_list_box;
+
+ construct {
+ process_list_box.type = ProcessListBoxType.DISK;
+
+ var system_monitor = SystemMonitor.get_default();
+
+ system_monitor.notify["disk-process-list-ready"].connect ((sender, property) => {
+ if(system_monitor.disk_process_list_ready) {
+ spinner.active = false;
+ spinner.visible = false;
+ }
+ });
+
+ process_list_box.bind_property ("visible", no_process_view, "visible",
BindingFlags.INVERT_BOOLEAN);
+ }
+
+ public void search_in_processes(string text) {
+ process_list_box.search_text = text;
+ }
+ }
+}
diff --git a/src/graph-stack-switcher.vala b/src/graph-stack-switcher.vala
index 3423648..a1fba7b 100644
--- a/src/graph-stack-switcher.vala
+++ b/src/graph-stack-switcher.vala
@@ -43,7 +43,8 @@ namespace Usage
buttons = {
new GraphSwitcherButton.processor(_("Processor")),
- new GraphSwitcherButton.memory(_("Memory"))
+ new GraphSwitcherButton.memory(_("Memory")),
+ new GraphSwitcherButton.disk(_("Disk I/O"))
};
foreach(GraphSwitcherButton button in buttons)
diff --git a/src/graph-switcher-button.vala b/src/graph-switcher-button.vala
index f0863c4..42ca431 100644
--- a/src/graph-switcher-button.vala
+++ b/src/graph-switcher-button.vala
@@ -36,6 +36,12 @@ namespace Usage
child = createContent(memory_graph, label);
}
+ public GraphSwitcherButton.disk(string label)
+ {
+ var disk_graph = new DiskGraph();
+ child = createContent(disk_graph, label);
+ }
+
private Gtk.Box createContent(Dazzle.GraphView graph, string label_text)
{
graph.height_request = 80;
diff --git a/src/memory-sub-view.vala b/src/memory-sub-view.vala
index bc5bbf9..b020b85 100644
--- a/src/memory-sub-view.vala
+++ b/src/memory-sub-view.vala
@@ -34,8 +34,7 @@ namespace Usage
label.margin_top = 25;
label.margin_bottom = 15;
- process_list_box = new ProcessListBox();
- process_list_box.type = ProcessListBoxType.MEMORY;
+ process_list_box = new ProcessListBox.with_type(ProcessListBox.MEMORY);
process_list_box.margin_bottom = 20;
process_list_box.margin_top = 30;
diff --git a/src/meson.build b/src/meson.build
index 0a754f1..c01b2d8 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -7,7 +7,10 @@ vala_sources = [
'cpu-graph.vala',
'cpu-monitor.vala',
'cpu-sub-view.vala',
+ 'disk-graph.vala',
+ 'disk-graph-model.vala',
'disk-monitor.vala',
+ 'disk-sub-view.vala',
'gnome-usage.vala',
'graph-box.vala',
'graph-stacked-renderer.vala',
diff --git a/src/performance-view.vala b/src/performance-view.vala
index 4253964..4399168 100644
--- a/src/performance-view.vala
+++ b/src/performance-view.vala
@@ -50,7 +50,8 @@ namespace Usage
sub_views = new View[]
{
new ProcessorSubView(),
- new MemorySubView()
+ new MemorySubView(),
+ new DiskSubView()
};
foreach(var sub_view in sub_views)
diff --git a/src/process-list-box.vala b/src/process-list-box.vala
index 90322d6..9e08fa1 100644
--- a/src/process-list-box.vala
+++ b/src/process-list-box.vala
@@ -21,26 +21,33 @@
namespace Usage
{
public enum ProcessListBoxType {
+ NONE,
PROCESSOR,
- MEMORY
+ MEMORY,
+ DISK
}
public class ProcessListBox : Gtk.ListBox
{
public bool empty { get; set; default = true; }
public string search_text { get; set; default = ""; }
- public ProcessListBoxType type = ProcessListBoxType.PROCESSOR;
+ public ProcessListBoxType type = ProcessListBoxType.NONE;
private const double APP_CPU_MIN_LOAD_LIMIT = 1;
private const double APP_MEM_MIN_USAGE_LIMIT = 0;
+ private const double APP_DISK_MIN_USAGE_LIMIT = 0;
private ListStore model;
+ public ProcessListBox.with_type(ProcessListBoxType type) {
+ this.type = type;
+ update();
+ }
+
construct
{
set_selection_mode (Gtk.SelectionMode.NONE);
set_header_func (update_header);
- this.type = type;
model = new ListStore(typeof(AppItem));
bind_model(model, on_row_created);
@@ -53,15 +60,18 @@ namespace Usage
update();
});
+ var settings = Settings.get_default();
var system_monitor = SystemMonitor.get_default();
- system_monitor.notify["process-list-ready"].connect (() => {
- if(system_monitor.process_list_ready)
+ system_monitor.notify["cpu-process-list-ready"].connect (() => {
+ if(type == ProcessListBoxType.PROCESSOR && system_monitor.cpu_process_list_ready)
+ update();
+ });
+ system_monitor.notify["disk-process-list-ready"].connect (() => {
+ if(type == ProcessListBoxType.DISK && system_monitor.disk_process_list_ready)
update();
});
- var settings = Settings.get_default();
Timeout.add(settings.list_update_interval_UI, update);
-
bind_property ("empty", this, "visible", BindingFlags.INVERT_BOOLEAN);
}
@@ -69,6 +79,9 @@ namespace Usage
{
model.remove_all();
+ if(type == ProcessListBoxType.NONE)
+ return true;
+
CompareDataFunc<AppItem> app_cmp = (a, b) => {
AppItem app_a = (AppItem) a;
AppItem app_b = (AppItem) b;
@@ -79,6 +92,10 @@ namespace Usage
return (int) ((uint64) (app_a.cpu_load < app_b.cpu_load) - (uint64) (app_a.cpu_load
app_b.cpu_load));
case ProcessListBoxType.MEMORY:
return (int) ((uint64) (app_a.mem_usage < app_b.mem_usage) - (uint64)
(app_a.mem_usage > app_b.mem_usage));
+ case ProcessListBoxType.DISK:
+ var app_a_disk = app_a.disk_read + app_a.disk_write;
+ var app_b_disk = app_b.disk_read + app_b.disk_write;
+ return (int) ((uint64) (app_a_disk < app_b_disk) - (uint64) (app_a_disk >
app_b_disk));
}
};
@@ -98,6 +115,12 @@ namespace Usage
if(app.mem_usage > APP_MEM_MIN_USAGE_LIMIT)
model.insert_sorted(app, app_cmp);
break;
+ case ProcessListBoxType.DISK:
+ foreach(unowned AppItem app in system_monitor.get_apps()) {
+ if((app.disk_read + app.disk_write) > APP_DISK_MIN_USAGE_LIMIT)
+ model.insert_sorted(app, app_cmp);
+ }
+ break;
}
}
else {
diff --git a/src/process-row.vala b/src/process-row.vala
index b9de945..ed501c3 100644
--- a/src/process-row.vala
+++ b/src/process-row.vala
@@ -73,6 +73,9 @@ namespace Usage
case ProcessListBoxType.MEMORY:
load_label.label = Utils.format_size_values(app.mem_usage);
break;
+ case ProcessListBoxType.DISK:
+ load_label.label = Utils.format_size_speed_values(app.disk_read) + " / " +
Utils.format_size_speed_values(app.disk_write);
+ break;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]