diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 24edbd7d..8b137891 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1 +1 @@
-patreon: stsdc
+
diff --git a/data/Application.css b/data/Application.css
index 4a728fba..74f90a78 100644
--- a/data/Application.css
+++ b/data/Application.css
@@ -14,6 +14,33 @@
border-width: 0;
}
+/* .vertical-label,
+.vertical-label:hover,
+.vertical-label:selected,
+.vertical-label:selected:focus,
+.vertical-label:hover:selected {
+
+} */
+
+.label-vertical {
+
+}
+
+.label-vertical-val {
+ color: alpha(@text_color, 1);
+ font-size: 30px;
+ font-weight: 100;
+ /* padding: 0 6px;
+ margin: 0 3px; */
+ border-width: 0;
+}
+
+.usage-label-container {
+ border: 1px solid @SILVER_300;;
+ border-radius: 3px;
+ background-color: alpha(@SILVER_100, 0.5);
+ }
+
.username-current {
background-color: @SILVER_300;
color: @SILVER_900;
@@ -45,6 +72,35 @@
border-width: 0;
}
+.core_badge {
+ background-color: @SILVER_100;
+ border-radius: 8px;
+ padding-right: 4px;
+ padding-left:2px;
+ font-size: 10px;
+ /* font-weight:bold; */
+ color: black;
+ border: 1px solid @SILVER_300;
+}
+
+.core_badge-mild-warning {
+ background-color: @BANANA_100;
+ color: @BANANA_900;
+ border: 1px solid @BANANA_300;
+}
+
+.core_badge-strong-warning {
+ background-color: @ORANGE_100;
+ color: @ORANGE_900;
+ border: 1px solid @ORANGE_300;
+}
+
+.core_badge-critical-warning {
+ background-color: @STRAWBERRY_100;
+ color: @STRAWBERRY_700;
+ border: 1px solid @STRAWBERRY_300;
+}
+
.command_wrapper {
background-color: #fdf6e3;
border-radius: 3px;
@@ -59,10 +115,10 @@
font-family: monospace;
}
-.pid {
+.small-text {
color:grey;
-font-weight:bold;
-font-size:9px;
+ font-weight:bold;
+ font-size:9px;
}
.graph {
@@ -93,3 +149,11 @@ font-size:9px;
color: @SILVER_700;
margin: 6px;
}
+
+.bold {
+ font-weight: bold;
+}
+
+.text-secondary {
+ color: @SILVER_700;
+}
\ No newline at end of file
diff --git a/data/com.github.stsdc.monitor.appdata.xml.in b/data/com.github.stsdc.monitor.appdata.xml.in
index bdf8725b..c2c49120 100644
--- a/data/com.github.stsdc.monitor.appdata.xml.in
+++ b/data/com.github.stsdc.monitor.appdata.xml.in
@@ -28,6 +28,15 @@
https://github.com/stsdc/monitor/issues
+
+
+
+ - Better System Tab
+ - Update Portuguese translation (@rottenpants466)
+ - Save last opened view (@ryonakano)
+
+
+
diff --git a/data/com.github.stsdc.monitor.gschema.xml b/data/com.github.stsdc.monitor.gschema.xml
index b7f8c63b..90fc778d 100644
--- a/data/com.github.stsdc.monitor.gschema.xml
+++ b/data/com.github.stsdc.monitor.gschema.xml
@@ -40,5 +40,10 @@
To start Monitor in background or not
To start Monitor in background or not
+
+ 'process_view'
+ Opened view
+ The last opened view
+
diff --git a/data/screenshots/monitor-system.png b/data/screenshots/monitor-system.png
index da9946d8..65d77500 100644
Binary files a/data/screenshots/monitor-system.png and b/data/screenshots/monitor-system.png differ
diff --git a/meson.build b/meson.build
index 230091e3..fb04f056 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('com.github.stsdc.monitor', 'vala', 'c', version: '0.8.1')
+project('com.github.stsdc.monitor', 'vala', 'c', version: '0.9.0')
# these are Meson modules
gnome = import('gnome')
@@ -67,14 +67,13 @@ executable(
'src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala',
'src/Views/SystemView/SystemView.vala',
- 'src/Views/SystemView/SystemCPUChart.vala',
'src/Views/SystemView/SystemCPUView.vala',
+ 'src/Views/SystemView/SystemCPUInfoPopover.vala',
'src/Views/SystemView/SystemMemoryView.vala',
+ 'src/Views/SystemView/SystemNetworkView.vala',
# Widgets related only to ProcessInfoView
'src/Views/ProcessView/ProcessInfoView/Preventor.vala',
- 'src/Views/ProcessView/ProcessInfoView/RoundyLabel.vala',
- 'src/Views/ProcessView/ProcessInfoView/Chart.vala',
'src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala',
'src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala',
'src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala',
@@ -84,7 +83,13 @@ executable(
'src/Widgets/Headerbar/Headerbar.vala',
'src/Widgets/Headerbar/Search.vala',
'src/Widgets/Statusbar/Statusbar.vala',
-
+ 'src/Widgets/Labels/LabelVertical.vala',
+ 'src/Widgets/Labels/LabelRoundy.vala',
+ 'src/Widgets/Labels/LabelH4.vala',
+ 'src/Widgets/Chart/Chart.vala',
+ 'src/Widgets/Chart/ProcessChart.vala',
+ 'src/Widgets/Chart/NetworkChart.vala',
+
# Models
'src/Models/TreeViewModel.vala',
@@ -106,6 +111,8 @@ executable(
'src/Resources/Core.vala',
'src/Resources/Memory.vala',
'src/Resources/Swap.vala',
+ 'src/Resources/TemperatureSensor.vala',
+ 'src/Resources/Network.vala',
c_args: c_args,
dependencies: [
glib,
diff --git a/po/pt.po b/po/pt.po
index daab273e..d02e8a09 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -9,14 +9,14 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-28 22:18+0400\n"
-"PO-Revision-Date: 2019-11-04 11:58+0000\n"
-"Last-Translator: Hugo Carvalho \n"
+"PO-Revision-Date: 2020-08-16 14:07+0100\n"
+"Last-Translator: André Barata \n"
"Language-Team: \n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Poedit 2.4.1\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: src/Utils.vala:13
@@ -29,11 +29,11 @@ msgstr ""
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:34
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:35
msgid "N/A"
-msgstr ""
+msgstr "N/A"
#: src/Utils.vala:45
msgid "B"
-msgstr ""
+msgstr "B"
#: src/Utils.vala:50
#: src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala:113
@@ -55,19 +55,19 @@ msgstr "Fechar Monitor"
#: src/Views/ProcessView/ProcessInfoView/OpenFilesListBox.vala:56
msgid "Deleted"
-msgstr ""
+msgstr "Apagado"
#: src/Views/ProcessView/ProcessInfoView/Preventor.vala:21
msgid "Are you sure you want to do this?"
-msgstr ""
+msgstr "Tem a certeza que quer fazer isso?"
#: src/Views/ProcessView/ProcessInfoView/Preventor.vala:24
msgid "Yes"
-msgstr ""
+msgstr "Sim"
#: src/Views/ProcessView/ProcessInfoView/Preventor.vala:28
msgid "No"
-msgstr ""
+msgstr "Não"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala:39
#: src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala:59
@@ -76,36 +76,35 @@ msgstr "PID"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala:40
msgid "NI"
-msgstr ""
+msgstr "NI"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala:41
-#, fuzzy
msgid "PRI"
-msgstr "PID"
+msgstr "PRI"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala:42
msgid "THR"
-msgstr ""
+msgstr "THR"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:18
msgid "Opened files"
-msgstr ""
+msgstr "Ficheiros abertos"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:22
msgid "Characters"
-msgstr ""
+msgstr "Caracteres"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:27
msgid "System calls"
-msgstr ""
+msgstr "Chamadas de sistema"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:32
msgid "Read/Written"
-msgstr ""
+msgstr "Ler/Escrita"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoIOStats.vala:37
msgid "Cancelled write"
-msgstr ""
+msgstr "Escrita cancelada"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala:79
msgid "End Process"
@@ -125,11 +124,11 @@ msgstr "Matar processo selecionado"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala:96
msgid "Confirm kill of the process?"
-msgstr ""
+msgstr "Confirma matar o processo?"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala:103
msgid "Confirm end of the process?"
-msgstr ""
+msgstr "Confirma terminar o processo?"
#. setup name column
#: src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala:17
@@ -155,12 +154,12 @@ msgstr "GiB"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala:50
#, c-format
msgid "CPU: %.1f%%"
-msgstr ""
+msgstr "CPU: %.1f%%"
#: src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala:51
#, c-format
msgid "RAM: %.1f%%"
-msgstr ""
+msgstr "RAM: %.1f%%"
#: src/Widgets/Headerbar/Headerbar.vala:13
msgid "Monitor"
@@ -188,7 +187,7 @@ msgstr "Escreva o nome do processo ou PID a pesquisar"
#: src/Widgets/Statusbar/Statusbar.vala:14
msgid "Swap"
-msgstr ""
+msgstr "Trocar"
#: src/Widgets/Statusbar/Statusbar.vala:16
#: src/Widgets/Statusbar/Statusbar.vala:20
@@ -198,7 +197,7 @@ msgstr "A calcular…"
#: src/Widgets/Statusbar/Statusbar.vala:38
msgid "GHz"
-msgstr ""
+msgstr "GHz"
#~ msgid "Monitor Indicator"
#~ msgstr "Indicador do monitor"
@@ -213,7 +212,7 @@ msgstr ""
#~ msgstr "Ctrl+E"
#~ msgid "CPU:"
-#~ msgstr "CPU :"
+#~ msgstr "CPU:"
#~ msgid "Memory:"
-#~ msgstr "Memória :"
+#~ msgstr "Memória:"
diff --git a/src/MainWindow.vala b/src/MainWindow.vala
index 7adce5b4..f36441ac 100644
--- a/src/MainWindow.vala
+++ b/src/MainWindow.vala
@@ -10,6 +10,7 @@
public ProcessView process_view;
public SystemView system_view;
+ private Gtk.Stack stack;
private Statusbar statusbar;
@@ -29,7 +30,7 @@
process_view = new ProcessView ();
system_view = new SystemView (resources);
- Gtk.Stack stack = new Gtk.Stack ();
+ stack = new Gtk.Stack ();
stack.set_transition_type (Gtk.StackTransitionType.SLIDE_LEFT_RIGHT);
stack.add_titled (process_view, "process_view", _("Processes"));
stack.add_titled (system_view, "system_view", _("System"));
@@ -48,6 +49,8 @@
main_box.pack_start (statusbar, false, true, 0);
this.add (main_box);
+ show_all ();
+
dbusserver = DBusServer.get_default ();
stack.notify["visible-child-name"].connect (() => {
@@ -87,6 +90,8 @@
MonitorApp.settings.set_int ("position-y", position_y);
MonitorApp.settings.set_boolean ("is-maximized", this.is_maximized);
+ MonitorApp.settings.set_string ("opened-view", stack.visible_child_name);
+
if (MonitorApp.settings.get_boolean ("indicator-state")) {
this.hide_on_delete ();
} else {
@@ -98,6 +103,7 @@
});
dbusserver.indicator_state (MonitorApp.settings.get_boolean ("indicator-state"));
+ stack.visible_child_name = MonitorApp.settings.get_string ("opened-view");
}
private void setup_window_state () {
diff --git a/src/Resources/CPU.vala b/src/Resources/CPU.vala
index df0ded16..8700a4f7 100644
--- a/src/Resources/CPU.vala
+++ b/src/Resources/CPU.vala
@@ -2,6 +2,17 @@ public class Monitor.CPU : Object {
private float last_used;
private float last_total;
private float load;
+ private TemperatureSensor temperature_sensor;
+
+ public string? model_name;
+ public string? model;
+ public string? family;
+ public string? microcode;
+ public string? cache_size;
+ public string? flags;
+ public string? bogomips;
+ public string? bugs;
+ public string? address_sizes;
GTop.Cpu ? cpu;
@@ -21,18 +32,31 @@ public class Monitor.CPU : Object {
}
}
+ public double temperature {
+ get {
+ return temperature_sensor.cpu / 1000;
+ }
+ }
+
construct {
last_used = 0;
last_total = 0;
core_list = new Gee.ArrayList ();
+ model_name = get_cpu_info ();
+
+ parse_cpuinfo ();
debug ("Number of cores: %d", (int) get_num_processors ());
for (int i = 0; i < (int) get_num_processors (); i++) {
var core = new Core(i);
core_list.add (core);
}
+
+ // Temperature sensor shouldn't be created here since it
+ // will provides not only cpu temperature
+ temperature_sensor = new TemperatureSensor ();
}
public void update () {
@@ -83,4 +107,86 @@ public class Monitor.CPU : Object {
_frequency = (double)maxcur;
}
+
+ private void parse_cpuinfo () {
+ unowned GTop.SysInfo? info = GTop.glibtop_get_sysinfo ();
+
+ if (info == null) {
+ warning ("No CPU info");
+ return;
+ }
+
+ // let core 0 represents whole processor
+ // TODO: parse all the values to corresponding core objects in core_list
+ // does it even makes sense??
+
+ unowned GLib.HashTable values = info.cpuinfo[0].values;
+ model = values["model"];
+ family = values["cpu family"];
+ microcode = values["microcode"];
+ cache_size = values["cache size"];
+ flags = values["flags"];
+ bogomips = values["bogomips"];
+ bugs = values["bugs"];
+ address_sizes = values["address sizes"];
+ }
+
+ // straight from elementary about-plug
+ private string? get_cpu_info () {
+ unowned GTop.SysInfo? info = GTop.glibtop_get_sysinfo ();
+
+ if (info == null) {
+ return null;
+ }
+
+ var counts = new Gee.HashMap ();
+ const string[] KEYS = { "model name", "cpu", "Processor" };
+
+ for (int i = 0; i < info.ncpu; i++) {
+ unowned GLib.HashTable values = info.cpuinfo[i].values;
+ string? model = null;
+ foreach (var key in KEYS) {
+ model = values.lookup (key);
+
+ if (model != null) {
+ break;
+ }
+ }
+
+ string? core_count = values.lookup ("cpu cores");
+ if (core_count != null) {
+ counts.@set (model, int.parse (core_count));
+ continue;
+ }
+
+ if (!counts.has_key (model)) {
+ counts.@set (model, 1);
+ } else {
+ counts.@set (model, counts.@get (model) + 1);
+ }
+ }
+
+ if (counts.size == 0) {
+ return null;
+ }
+
+ string result = "";
+ foreach (var cpu in counts.entries) {
+ if (result.length > 0) {
+ result += "\n";
+ }
+
+ if (cpu.@value == 2) {
+ result += _("Dual-Core %s").printf ( (cpu.key));
+ } else if (cpu.@value == 4) {
+ result += _("Quad-Core %s").printf ( (cpu.key));
+ } else if (cpu.@value == 6) {
+ result += _("Hexa-Core %s").printf ( (cpu.key));
+ } else {
+ result += "%u\u00D7 %s ".printf (cpu.@value, (cpu.key));
+ }
+ }
+
+ return Utils.Strings.beautify (result);
+ }
}
diff --git a/src/Resources/Network.vala b/src/Resources/Network.vala
new file mode 100644
index 00000000..272f2978
--- /dev/null
+++ b/src/Resources/Network.vala
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2020 Tudor Plugaru (https://github.com/PlugaruT/wingpanel-monitor)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Authored by: Tudor Plugaru
+ */
+
+
+public class Monitor.Network : GLib.Object {
+ private int _bytes_in;
+ private int _bytes_in_old;
+ private bool control;
+
+ private int _bytes_out;
+ private int _bytes_out_old;
+
+ // flag first run
+ // bc first calculasion is wrong
+ private bool dumb_flag;
+
+ public Network () {
+ _bytes_in = 0;
+ _bytes_in_old = 0;
+ _bytes_out = 0;
+ _bytes_out_old = 0;
+ control = false;
+ dumb_flag = true;
+ }
+
+ public int[] get_bytes () {
+ if (control == false) {
+ control = true;
+ update_bytes_total ();
+ } else {
+ control = false;
+ }
+ int[] ret;
+ ret = {_bytes_out, _bytes_in};
+ return ret;
+ }
+
+ private void update_bytes_total () {
+ GTop.NetList netlist;
+ GTop.NetLoad netload;
+
+ var devices = GTop.get_netlist (out netlist);
+ var n_bytes_out = 0;
+ var n_bytes_in = 0;
+ for (uint j = 0; j < netlist.number; ++j) {
+ var device = devices[j];
+ if (device != "lo" && device.substring (0, 3) != "tun") {
+ GTop.get_netload (out netload, device);
+
+ n_bytes_out += (int)netload.bytes_out;
+ n_bytes_in += (int)netload.bytes_in;
+ }
+ }
+
+ var bout = (n_bytes_out - _bytes_out_old) / 1;
+ var bin = (n_bytes_in - _bytes_in_old) / 1;
+
+ _bytes_out_old = n_bytes_out;
+ _bytes_in_old = n_bytes_in;
+
+ if (!dumb_flag) {
+ _bytes_out = bout;
+ _bytes_in = bin;
+ }
+ dumb_flag = false;
+
+ }
+ }
diff --git a/src/Resources/Resources.vala b/src/Resources/Resources.vala
index 1deef74c..04f2b898 100644
--- a/src/Resources/Resources.vala
+++ b/src/Resources/Resources.vala
@@ -2,11 +2,13 @@ public class Monitor.Resources : Object {
public CPU cpu;
public Memory memory;
public Swap swap;
+ public Network network;
construct {
memory = new Memory ();
cpu = new CPU ();
swap = new Swap ();
+ network = new Network ();
}
public void update() {
diff --git a/src/Resources/TemperatureSensor.vala b/src/Resources/TemperatureSensor.vala
new file mode 100644
index 00000000..b64a8e20
--- /dev/null
+++ b/src/Resources/TemperatureSensor.vala
@@ -0,0 +1,81 @@
+class TemperatureSensor : Object {
+ private const string hwmon_path = "/sys/class/hwmon";
+
+ // contains list of paths to files with a temperature values
+ // Intel reports per core temperature, while AMD Ryzen Tdie
+ public Gee.ArrayList cpu_temp_paths;
+
+ public double cpu {
+ get {
+ double total_temperature = 0;
+ foreach (var path in cpu_temp_paths) {
+ total_temperature += double.parse (open_file (path));
+ }
+ return total_temperature / cpu_temp_paths.size;
+ }
+ }
+
+ construct {
+ cpu_temp_paths = new Gee.ArrayList ();
+ traverser ();
+ }
+
+ public TemperatureSensor() {
+
+ }
+
+
+ private void traverser () {
+ Dir hwmon_dir = Dir.open (hwmon_path, 0);
+
+ string ? hwmonx = null;
+ while ((hwmonx = hwmon_dir.read_name ()) != null) {
+ string hwmonx_name = Path.build_filename (hwmon_path, hwmonx, "name");
+ string sensor_location = open_file (hwmonx_name);
+
+ if (sensor_location == "coretemp" || sensor_location == "k10temp") {
+ debug ("Found temp. sensor: %s", sensor_location);
+
+ Dir hwmonx_dir = Dir.open (Path.build_filename (hwmon_path, hwmonx), 0);
+ string ? hwmonx_prop = null;
+ while ((hwmonx_prop = hwmonx_dir.read_name ()) != null) {
+ // debug (open_file (hwmonx_name));
+
+ if (hwmonx_prop.contains ("temp")) {
+ // AMD stuff
+ // Tdie contains true temperature value, while Tctl contains value for fans
+ // Tctl = Tdie + offset in some processors
+ if ("Tdie" == open_file (Path.build_filename (hwmon_path, hwmonx, hwmonx_prop))) {
+ string tempx_input = "temp%c_input".printf(hwmonx_prop[4]);
+ cpu_temp_paths.add (Path.build_filename (hwmon_path, hwmonx, tempx_input));
+
+ debug (open_file (cpu_temp_paths[0]));
+
+ // Intel stuff
+ // Intel reports per core
+ } else if (open_file (Path.build_filename (hwmon_path, hwmonx, hwmonx_prop)).contains ("Core")) {
+ string tempx_input = "temp%c_input".printf(hwmonx_prop[4]);
+ cpu_temp_paths.add (Path.build_filename (hwmon_path, hwmonx, tempx_input));
+ debug (open_file (cpu_temp_paths[0]));
+ }
+ }
+ }
+ } else if (sensor_location == "amdgpu" ) {
+ debug ("Found temp. sensor: %s", sensor_location);
+ } else {
+ debug ("Found temp. sensor: %s", sensor_location);
+ }
+ }
+ }
+
+ private string open_file (string filename) {
+ try {
+ string read;
+ FileUtils.get_contents (filename, out read);
+ return read.replace ("\n","");
+ } catch (FileError e) {
+ error ("%s\n", e.message);
+ return "0";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Utils.vala b/src/Utils.vala
index 4d020acf..628dbaf9 100644
--- a/src/Utils.vala
+++ b/src/Utils.vala
@@ -1,54 +1,88 @@
namespace Monitor.Utils {
- const string NOT_AVAILABLE = (_("N/A"));
+ const string NOT_AVAILABLE = (_ ("N/A"));
const string NO_DATA = "\u2014";
}
+public class Monitor.Utils.Strings {
+ // straight from elementary about-plug
+
+ struct GraphicsReplaceStrings {
+ string regex;
+ string replacement;
+ }
+
+ public static string beautify (string info) {
+ string pretty = GLib.Markup.escape_text (info).strip ();
+
+
+ const GraphicsReplaceStrings REPLACE_STRINGS[] = {
+ // { "Mesa DRI ", ""},
+ { "[(]R[)]", "®"},
+ { "[(]TM[)]", "™"},
+ // { "Gallium .* on (AMD .*)", "\\1"},
+ // { "(AMD .*) [(].*", "\\1"},
+ // { "(AMD [A-Z])(.*)", "\\1\\L\\2\\E"},
+ // { "Graphics Controller", "Graphics"},
+ };
+
+ try {
+ foreach (GraphicsReplaceStrings replace_string in REPLACE_STRINGS) {
+ GLib.Regex re = new GLib.Regex (replace_string.regex, 0, 0);
+ pretty = re.replace (pretty, -1, 0, replace_string.replacement, 0);
+ }
+ } catch (Error e) {
+ critical ("Couldn't cleanup vendor string: %s", e.message);
+ }
+
+ return pretty;
+ }
+}
+
+/**
+ * Static helper class for unit formatting
+ * Author: Laurent Callarec @lcallarec
+ */
+public class Monitor.Utils.HumanUnitFormatter {
+ const string[] SIZE_UNITS = {"B", "KiB", "MiB", "GiB", "TiB"};
+ const double KFACTOR = 1024;
+
/**
- * Static helper class for unit formatting
- * Author: Laurent Callarec @lcallarec
+ * format a string of bytes to an human readable format with units
*/
- public class Monitor.Utils.HumanUnitFormatter {
-
- const string[] SIZE_UNITS = {"B", "KiB", "MiB", "GiB", "TiB"};
- const double KFACTOR = 1024;
-
- /**
- * format a string of bytes to an human readable format with units
- */
- public static string string_bytes_to_human(string bytes) {
- double current_size = double.parse(bytes);
- string current_size_formatted = bytes.to_string() + HumanUnitFormatter.SIZE_UNITS[0];
-
- for (int i = 0; i<= HumanUnitFormatter.SIZE_UNITS.length; i++) {
- if (current_size < HumanUnitFormatter.KFACTOR) {
- return GLib.Math.round(current_size).to_string() + HumanUnitFormatter.SIZE_UNITS[i];
- }
- current_size = current_size / HumanUnitFormatter.KFACTOR;
- }
-
- return current_size_formatted;
- }
-
- public static string double_bytes_to_human(double bytes) {
- string units = _ ("B");
-
- // convert to MiB if needed
- if (bytes > 1024.0) {
- bytes /= 1024.0;
- units = _ ("KiB");
- }
-
- // convert to GiB if needed
- if (bytes > 1024.0) {
- bytes /= 1024.0;
- units = _ ("MiB");
- }
+ public static string string_bytes_to_human (string bytes) {
+ double current_size = double.parse (bytes);
+ string current_size_formatted = bytes.to_string () + HumanUnitFormatter.SIZE_UNITS[0];
- if (bytes > 1024.0) {
- bytes /= 1024.0;
- units = _ ("GiB");
+ for (int i = 0; i<= HumanUnitFormatter.SIZE_UNITS.length; i++) {
+ if (current_size < HumanUnitFormatter.KFACTOR) {
+ return GLib.Math.round (current_size).to_string () + HumanUnitFormatter.SIZE_UNITS[i];
}
+ current_size = current_size / HumanUnitFormatter.KFACTOR;
+ }
+
+ return current_size_formatted;
+ }
+
+ public static string double_bytes_to_human (double bytes) {
+ string units = _ ("B");
- return "%.1f %s".printf (bytes, units);
- }
- }
+ // convert to MiB if needed
+ if (bytes > 1024.0) {
+ bytes /= 1024.0;
+ units = _ ("KiB");
+ }
+
+ // convert to GiB if needed
+ if (bytes > 1024.0) {
+ bytes /= 1024.0;
+ units = _ ("MiB");
+ }
+
+ if (bytes > 1024.0) {
+ bytes /= 1024.0;
+ units = _ ("GiB");
+ }
+
+ return "%.1f %s".printf (bytes, units);
+ }
+}
diff --git a/src/Views/ProcessView/ProcessInfoView/Preventor.vala b/src/Views/ProcessView/ProcessInfoView/Preventor.vala
index f09f5673..df5e80bc 100644
--- a/src/Views/ProcessView/ProcessInfoView/Preventor.vala
+++ b/src/Views/ProcessView/ProcessInfoView/Preventor.vala
@@ -5,7 +5,7 @@ public class Monitor.Preventor : Gtk.Stack {
private Gtk.Button confirm_button;
private Gtk.Button deny_button;
- private Gtk.Widget child;
+ private Gtk.Widget child_widget;
public signal void confirmed (bool is_confirmed);
@@ -33,19 +33,19 @@ public class Monitor.Preventor : Gtk.Stack {
}
public Preventor (Gtk.Widget _child, string name) {
- child = _child;
- add_named (child, name);
+ child_widget = _child;
+ add_named (child_widget, name);
add_named (preventive_action_bar, "preventive_action_bar");
deny_button.clicked.connect (() => {
set_transition_type(Gtk.StackTransitionType.SLIDE_UP);
- set_visible_child (child);
+ set_visible_child (child_widget);
confirmed(false);
});
confirm_button.clicked.connect(() => {
set_transition_type(Gtk.StackTransitionType.SLIDE_UP);
- set_visible_child (child);
+ set_visible_child (child_widget);
confirmed(true);
});
}
diff --git a/src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala b/src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala
index 70ca1541..755c321c 100644
--- a/src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala
+++ b/src/Views/ProcessView/ProcessInfoView/ProcessInfoCPURAM.vala
@@ -2,8 +2,8 @@ public class Monitor.ProcessInfoCPURAM : Gtk.Grid {
private Gtk.Label cpu_label;
private Gtk.Label ram_label;
- private Chart cpu_chart;
- private Chart ram_chart;
+ private ProcessChart cpu_chart;
+ private ProcessChart ram_chart;
construct {
column_spacing = 6;
@@ -12,8 +12,8 @@ public class Monitor.ProcessInfoCPURAM : Gtk.Grid {
column_homogeneous = true;
row_homogeneous = false;
- cpu_chart = new Chart ();
- ram_chart = new Chart ();
+ cpu_chart = new ProcessChart ();
+ ram_chart = new ProcessChart ();
var cpu_graph_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
diff --git a/src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala b/src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala
index aa072fbf..1704d346 100644
--- a/src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala
+++ b/src/Views/ProcessView/ProcessInfoView/ProcessInfoHeader.vala
@@ -2,13 +2,13 @@ public class Monitor.ProcessInfoHeader : Gtk.Grid {
private Gtk.Image icon;
public Gtk.Label state;
public Gtk.Label application_name;
- public RoundyLabel pid;
- public RoundyLabel ppid;
- public RoundyLabel pgrp;
- public RoundyLabel nice;
- public RoundyLabel priority;
- public RoundyLabel num_threads;
- public RoundyLabel username;
+ public LabelRoundy pid;
+ public LabelRoundy ppid;
+ public LabelRoundy pgrp;
+ public LabelRoundy nice;
+ public LabelRoundy priority;
+ public LabelRoundy num_threads;
+ public LabelRoundy username;
private Regex ? regex;
@@ -36,15 +36,15 @@ public class Monitor.ProcessInfoHeader : Gtk.Grid {
application_name.halign = Gtk.Align.START;
application_name.valign = Gtk.Align.START;
- pid = new RoundyLabel (_ ("PID"));
- nice = new RoundyLabel (_ ("NI"));
- priority = new RoundyLabel (_ ("PRI"));
- num_threads = new RoundyLabel (_ ("THR"));
- // ppid = new RoundyLabel (_("PPID"));
- // pgrp = new RoundyLabel (_("PGRP"));
+ pid = new LabelRoundy (_ ("PID"));
+ nice = new LabelRoundy (_ ("NI"));
+ priority = new LabelRoundy (_ ("PRI"));
+ num_threads = new LabelRoundy (_ ("THR"));
+ // ppid = new LabelRoundy (_("PPID"));
+ // pgrp = new LabelRoundy (_("PGRP"));
// TODO: tooltip_text UID
- username = new RoundyLabel ("");
+ username = new LabelRoundy ("");
var wrapper = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
wrapper.add (pid);
diff --git a/src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala b/src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala
index 26929c1f..c0163bd7 100644
--- a/src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala
+++ b/src/Views/ProcessView/ProcessInfoView/ProcessInfoView.vala
@@ -22,7 +22,6 @@ public class Monitor.ProcessInfoView : Gtk.Box {
}
}
public string ? icon_name;
- private Gtk.ScrolledWindow command_wrapper;
private Gtk.InfoBar permission_error_infobar;
private Gtk.Label permission_error_label;
@@ -31,15 +30,9 @@ public class Monitor.ProcessInfoView : Gtk.Box {
private ProcessInfoIOStats process_info_io_stats;
private ProcessInfoCPURAM process_info_cpu_ram;
-
- private Regex ? regex;
- private Gtk.Grid grid;
-
private Gtk.Button end_process_button;
private Gtk.Button kill_process_button;
- private Preventor preventor;
-
public ProcessInfoView () {
orientation = Gtk.Orientation.VERTICAL;
hexpand = true;
diff --git a/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala
index 149c910f..31ae9d01 100644
--- a/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala
+++ b/src/Views/ProcessView/ProcessTreeView/CPUProcessTreeView.vala
@@ -82,12 +82,12 @@ public class Monitor.CPUProcessTreeView : Gtk.TreeView {
try {
Gdk.Pixbuf icon = new Gdk.Pixbuf.from_file_at_size (path, 16, -1);
- (icon_cell as Gtk.CellRendererPixbuf).pixbuf = icon;
+ ((Gtk.CellRendererPixbuf)icon_cell).pixbuf = icon;
} catch (Error e) {
warning (e.message);
}
} else {
- (icon_cell as Gtk.CellRendererPixbuf).icon_name = path;
+ ((Gtk.CellRendererPixbuf)icon_cell).icon_name = path;
}
}
@@ -99,9 +99,9 @@ public class Monitor.CPUProcessTreeView : Gtk.TreeView {
// format the double into a string
if (cpu_usage < 0.0)
- (cell as Gtk.CellRendererText).text = Utils.NO_DATA;
+ ((Gtk.CellRendererText)cell).text = Utils.NO_DATA;
else
- (cell as Gtk.CellRendererText).text = "%.0f%%".printf (cpu_usage);
+ ((Gtk.CellRendererText)cell).text = "%.0f%%".printf (cpu_usage);
}
public void memory_usage_cell_layout (Gtk.CellLayout cell_layout, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) {
@@ -126,9 +126,9 @@ public class Monitor.CPUProcessTreeView : Gtk.TreeView {
// format the double into a string
if (memory_usage == 0)
- (cell as Gtk.CellRendererText).text = Utils.NO_DATA;
+ ((Gtk.CellRendererText)cell).text = Utils.NO_DATA;
else
- (cell as Gtk.CellRendererText).text = "%.1f %s".printf (memory_usage_double, units);
+ ((Gtk.CellRendererText)cell).text = "%.1f %s".printf (memory_usage_double, units);
}
private void pid_cell_layout (Gtk.CellLayout cell_layout, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) {
@@ -137,7 +137,7 @@ public class Monitor.CPUProcessTreeView : Gtk.TreeView {
int pid = pid_value.get_int ();
// format the double into a string
if (pid == 0) {
- (cell as Gtk.CellRendererText).text = Utils.NO_DATA;
+ ((Gtk.CellRendererText)cell).text = Utils.NO_DATA;
}
}
diff --git a/src/Views/SystemView/SystemCPUInfoPopover.vala b/src/Views/SystemView/SystemCPUInfoPopover.vala
new file mode 100644
index 00000000..3fa74028
--- /dev/null
+++ b/src/Views/SystemView/SystemCPUInfoPopover.vala
@@ -0,0 +1,54 @@
+public class Monitor.SystemCPUInfoPopover : Gtk.Popover {
+ private Gtk.Grid grid;
+
+ private CPU cpu;
+
+ construct {
+ grid = new Gtk.Grid ();
+ grid.margin = 12;
+ grid.column_spacing = 6;
+
+ grid.attach (label(_("Model")), 0, 0, 1, 1);
+ grid.attach (label(_("Family")), 0, 1, 1, 1);
+ grid.attach (label(_("Microcode ver.")), 0, 2, 1, 1);
+ grid.attach (label(_("Bogomips")), 0, 3, 1, 1);
+ grid.attach (label(_("Cache size")), 0, 4, 1, 1);
+ grid.attach (label(_("Address sizes")), 0, 5, 1, 1);
+ grid.attach (label(_("Flags")), 0, 6, 1, 1);
+ grid.attach (label(_("Bugs")), 0, 7, 1, 1);
+
+ for (int i; i <= 7; i++) {
+ grid.attach ( label (":"), 1, i, 1, 1);
+ }
+
+ add (grid);
+ }
+
+
+ public SystemCPUInfoPopover(Gtk.ToggleButton? relative_to, CPU _cpu) {
+ Object (relative_to : relative_to);
+
+ closed.connect (() => { relative_to.set_active(false); });
+
+ cpu = _cpu;
+
+ grid.attach (label(cpu.model), 2, 0, 1, 1);
+ grid.attach (label(cpu.family), 2, 1, 1, 1);
+ grid.attach (label(cpu.microcode), 2, 2, 1, 1);
+ grid.attach (label(cpu.bogomips), 2, 3, 1, 1);
+ grid.attach (label(cpu.cache_size), 2, 4, 1, 1);
+ grid.attach (label(cpu.address_sizes), 2, 5, 1, 1);
+ grid.attach (label(cpu.flags), 2, 6, 1, 1);
+ grid.attach (label(cpu.bugs), 2, 7, 1, 1);
+ }
+
+ private Gtk.Label label(string text) {
+ var label = new Gtk.Label (text);
+ label.halign = Gtk.Align.START;
+ label.valign = Gtk.Align.START;
+ label.wrap = true;
+ label.max_width_chars = 80;
+
+ return label;
+ }
+}
\ No newline at end of file
diff --git a/src/Views/SystemView/SystemCPUView.vala b/src/Views/SystemView/SystemCPUView.vala
index 7914ffad..4187c1f4 100644
--- a/src/Views/SystemView/SystemCPUView.vala
+++ b/src/Views/SystemView/SystemCPUView.vala
@@ -1,15 +1,25 @@
-public class Monitor.SystemCPUView : Gtk.Grid {
- private SystemCPUChart cpu_chart;
+public class Monitor.SystemCPUView : Gtk.Box {
+ private Chart cpu_utilization_chart;
+ private Chart cpu_frequency_chart;
+ private Chart cpu_temperature_chart;
private CPU cpu;
- private Gtk.Label cpu_percentage_label;
+ private LabelVertical cpu_percentage_label;
+ private LabelRoundy cpu_frequency_label;
+ private LabelRoundy cpu_temperature_label;
+ private LabelH4 processor_name_label;
+
+ private Gtk.Button view_threads_usage_button;
+
+ private Gtk.Revealer cpu_threads_revealer;
private Gee.ArrayList core_label_list;
construct {
margin = 12;
- column_spacing = 12;
+ margin_top = 6;
set_vexpand (false);
+ orientation = Gtk.Orientation.VERTICAL;
core_label_list = new Gee.ArrayList ();
}
@@ -19,52 +29,178 @@ public class Monitor.SystemCPUView : Gtk.Grid {
public SystemCPUView(CPU _cpu) {
cpu = _cpu;
- cpu_percentage_label = new Gtk.Label (_("CPU: ") + Utils.NO_DATA);
- cpu_percentage_label.get_style_context ().add_class ("h2");
- cpu_percentage_label.valign = Gtk.Align.START;
- cpu_percentage_label.halign = Gtk.Align.START;
- cpu_percentage_label.margin_start = 6;
+ cpu_percentage_label = new LabelVertical (_("UTILIZATION"));
+ cpu_percentage_label.has_tooltip = true;
+ cpu_percentage_label.tooltip_text = (_("Show detailed info"));
+
+ cpu_frequency_label = new LabelRoundy (_("FREQUENCY"));
+ cpu_frequency_label.margin = 6;
+ cpu_frequency_label.margin_top = 2;
+
+ cpu_temperature_label = new LabelRoundy (_("TEMPERATURE"));
+ cpu_temperature_label.margin = 6;
+ cpu_temperature_label.margin_top = 2;
+
+ processor_name_label = new LabelH4 (cpu.model_name);
+
+ var processor_info_button = new Gtk.ToggleButton ();
+ processor_info_button.get_style_context ().add_class ("circular");
+ // processor_info_button.get_style_context ().add_class ("popup");
+ processor_info_button.has_focus = false;
+ var icon = new Gtk.Image ();
+ icon.gicon = new ThemedIcon ("dialog-information");
+ icon.pixel_size = 16;
+ processor_info_button.set_image (icon);
+ processor_info_button.valign = Gtk.Align.START;
+ processor_info_button.halign = Gtk.Align.START;
+
+
+ var title_grid = new Gtk.Grid ();
+ title_grid.attach (processor_name_label, 0, 0, 1, 1);
+ title_grid.attach (processor_info_button, 1, 0, 1, 1);
+ title_grid.column_spacing = 6;
+
+ var popover = new SystemCPUInfoPopover (processor_info_button, cpu);
+
+ processor_info_button.clicked.connect(() => { popover.show_all(); });
+
+ cpu_utilization_chart = new Chart (cpu.core_list.size);
+
+ var grid_utilization_info = new Gtk.Grid ();
+ grid_utilization_info.attach (grid_usage_labels(), 0, 0, 1, 1);
+ grid_utilization_info.attach (cpu_utilization_chart, 0, 0, 1, 1);
- cpu_chart = new SystemCPUChart (cpu.core_list.size);
- attach (grid_core_labels (), 0, 0, 1);
- attach (cpu_percentage_label, 1, 0, 1, 1);
- attach (cpu_chart, 1, 0, 1, 2);
+ cpu_frequency_chart = new Chart (1);
+ cpu_frequency_chart.height_request = -1;
+ cpu_frequency_chart.config.y_axis.fixed_max = 5.0;
+ cpu_temperature_chart = new Chart (1);
+ cpu_temperature_chart.height_request = -1;
+
+ var grid_frequency_info = new Gtk.Grid ();
+ grid_frequency_info.attach (cpu_frequency_label, 0, 0, 1, 1);
+ grid_frequency_info.attach (cpu_frequency_chart, 0, 0, 1, 1);
+
+ var grid_temperature_info = new Gtk.Grid ();
+ grid_temperature_info.attach (cpu_temperature_label, 0, 0, 1, 1);
+ grid_temperature_info.attach (cpu_temperature_chart, 0, 0, 1, 1);
+
+
+ cpu_percentage_label.clicked.connect(() => {
+ cpu_threads_revealer.reveal_child = !(cpu_threads_revealer.child_revealed);
+
+ if (cpu_threads_revealer.child_revealed) {
+ cpu_percentage_label.tooltip_text = (_("Show detailed info"));
+ } else {
+ cpu_percentage_label.tooltip_text = (_("Hide detailed info"));
+ }
+ });
+
+ var smol_charts_container = new Gtk.Grid ();
+ smol_charts_container.width_request = 200;
+ smol_charts_container.hexpand = false;
+ smol_charts_container.halign = Gtk.Align.START;
+ smol_charts_container.attach (grid_frequency_info, 0, 0, 1, 1);
+ smol_charts_container.attach (grid_temperature_info, 0, 1, 1, 1);
+ smol_charts_container.row_spacing = 6;
+ smol_charts_container.margin_left = 6;
+
+ // Thanks Goncalo
+ var charts_container = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+ charts_container.pack_start (grid_utilization_info, true, true, 0);
+ charts_container.pack_start(smol_charts_container, false, false, 0);
+
+ add (title_grid);
+ add (charts_container);
}
public void update () {
+ cpu_frequency_chart.update (0, cpu.frequency);
+ cpu_temperature_chart.update (0, cpu.temperature);
+
for (int i = 0; i < cpu.core_list.size; i++) {
double core_percentage = cpu.core_list[i].percentage_used;
- cpu_chart.update(i, core_percentage);
+ cpu_utilization_chart.update(i, core_percentage);
string percentage_formatted = ("% 3d%%").printf ( (int)core_percentage);
- core_label_list[i].set_text (_("Thread %d: %s").printf (i, percentage_formatted));
+ core_label_list[i].set_text (percentage_formatted);
+
+ core_label_list[i].get_style_context ().remove_class ("core_badge-mild-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-strong-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-critical-warning");
+
+
+ if (core_percentage > 75.0) {
+ core_label_list[i].get_style_context ().add_class ("core_badge-mild-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-strong-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-critical-warning");
+ }
+ if (core_percentage > 85.0) {
+ core_label_list[i].get_style_context ().add_class ("core_badge-strong-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-mild-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-critical-warning");
+ }
+
+ if (core_percentage > 90.0) {
+ core_label_list[i].get_style_context ().add_class ("core_badge-critical-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-mild-warning");
+ core_label_list[i].get_style_context ().remove_class ("core_badge-strong-warning");
+ }
}
- cpu_percentage_label.set_text ((_("CPU: % 3d%%")).printf (cpu.percentage));
+ cpu_percentage_label.set_text ((_("%d%%")).printf (cpu.percentage));
+ cpu_frequency_label.set_text (("%.2f %s").printf (cpu.frequency, _ ("GHz")));
+ cpu_temperature_label.set_text (("%.2f %s").printf (cpu.temperature, _ ("℃")));
+ }
+
+ private Gtk.Grid grid_usage_labels () {
+
+ Gtk.Grid grid = new Gtk.Grid ();
+ grid.column_spacing = 6;
+ grid.margin = 6;
+ grid.valign = Gtk.Align.START;
+ grid.halign = Gtk.Align.START;
+ grid.get_style_context ().add_class ("usage-label-container");
+
+ grid.attach(cpu_percentage_label, 0, 0, 1, 1);
+ grid.attach(grid_core_labels(), 1, 0, 1, 1);
+
+ return grid;
}
- private Gtk.Grid grid_core_labels () {
+ private Gtk.Revealer grid_core_labels () {
+ cpu_threads_revealer = new Gtk.Revealer();
+ cpu_threads_revealer.margin = 6;
+ cpu_threads_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT;
+ cpu_threads_revealer.valign = Gtk.Align.CENTER;
+
Gtk.Grid grid = new Gtk.Grid ();
- grid.column_spacing = 12;
- grid.width_request = 300;
+ grid.column_spacing = 8;
+ grid.row_spacing = 4;
int column = 0;
int row = 0;
for (int i = 0; i < cpu.core_list.size; i++) {
- var core_label = new Gtk.Label(_("Thread %d: ").printf (i) + Utils.NO_DATA);
- core_label.halign = Gtk.Align.START;
+ var core_label = new Gtk.Label (Utils.NO_DATA);
+ core_label.set_width_chars (4);
+ core_label.get_style_context ().add_class ("core_badge");
+ // core_label.set_text (Utils.NO_DATA);
core_label_list.add (core_label);
grid.attach(core_label, column, row, 1, 1);
- column++;
- if (column > 1) {
- row++;
- column = 0;
+ row++;
+ if (row > 1) {
+ column++;
+ row = 0;
}
}
+ cpu_threads_revealer.add (grid);
- return grid;
+ var threads_label = new Gtk.Label ("THREADS");
+ threads_label.get_style_context ().add_class ("small-text");
+ grid.attach(threads_label, 0, -1, column, 1);
+
+ return cpu_threads_revealer;
}
}
\ No newline at end of file
diff --git a/src/Views/SystemView/SystemMemoryView.vala b/src/Views/SystemView/SystemMemoryView.vala
index 16cd0a72..8c08ad94 100644
--- a/src/Views/SystemView/SystemMemoryView.vala
+++ b/src/Views/SystemView/SystemMemoryView.vala
@@ -1,14 +1,16 @@
public class Monitor.SystemMemoryView : Gtk.Grid {
- private SystemCPUChart memory_chart;
+ private Chart memory_chart;
private Memory memory;
- private Gtk.Label memory_percentage_label;
+ private LabelH4 memory_name_label;
+ private LabelVertical memory_percentage_label;
private Gtk.Label memory_shared_label;
private Gtk.Label memory_buffered_label;
private Gtk.Label memory_cached_label;
private Gtk.Label memory_locked_label;
private Gtk.Label memory_total_label;
private Gtk.Label memory_used_label;
+ private Gtk.Revealer memory_usage_revealer;
construct {
margin = 12;
@@ -21,11 +23,20 @@ public class Monitor.SystemMemoryView : Gtk.Grid {
public SystemMemoryView(Memory _memory) {
memory = _memory;
- memory_percentage_label = new Gtk.Label (_("Memory: ") + Utils.NO_DATA);
- memory_percentage_label.get_style_context ().add_class ("h2");
- memory_percentage_label.halign = Gtk.Align.START;
- memory_percentage_label.valign = Gtk.Align.START;
- memory_percentage_label.margin_start = 6;
+ memory_name_label = new LabelH4 (_("Memory"));
+
+ memory_percentage_label = new LabelVertical (_("UTILIZATION"));
+ memory_percentage_label.has_tooltip = true;
+ memory_percentage_label.tooltip_text = (_("Show detailed info"));
+
+ memory_percentage_label.clicked.connect(() => {
+ memory_usage_revealer.reveal_child = !(memory_usage_revealer.child_revealed);
+ if (memory_usage_revealer.child_revealed) {
+ memory_percentage_label.tooltip_text = (_("Show detailed info"));
+ } else {
+ memory_percentage_label.tooltip_text = (_("Hide detailed info"));
+ }
+ });
memory_total_label = new Gtk.Label (_("Total: ") + Utils.NO_DATA);
memory_total_label.halign = Gtk.Align.START;
@@ -45,15 +56,29 @@ public class Monitor.SystemMemoryView : Gtk.Grid {
memory_locked_label = new Gtk.Label (_("Locked: ") + Utils.NO_DATA);
memory_locked_label.halign = Gtk.Align.START;
- memory_chart = new SystemCPUChart (1);
+ memory_chart = new Chart (1);
+
+ var lil_gridy = new Gtk.Grid ();
+ lil_gridy.margin = 6;
+ lil_gridy.column_spacing = 6;
+ lil_gridy.valign = Gtk.Align.START;
+ lil_gridy.halign = Gtk.Align.START;
+ lil_gridy.get_style_context ().add_class ("usage-label-container");
+ lil_gridy.attach (memory_percentage_label, 0, 0, 1, 1);
+ lil_gridy.attach (memory_usage_grid (), 1, 0, 1, 1);
- attach (memory_percentage_label, 1, 0, 1, 1);
- attach (memory_usage_grid (), 0, 0, 1);
- attach (memory_chart, 1, 0, 1, 2);
+ attach (memory_name_label, 0, 0, 1, 1);
+ attach (lil_gridy, 0, 1, 1, 1);
+ attach (memory_chart, 0, 1, 2, 2);
}
- private Gtk.Grid memory_usage_grid () {
+ private Gtk.Revealer memory_usage_grid () {
+ memory_usage_revealer = new Gtk.Revealer();
+ memory_usage_revealer.margin = 6;
+ memory_usage_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT;
+ memory_usage_revealer.valign = Gtk.Align.CENTER;
+
Gtk.Grid grid = new Gtk.Grid ();
grid.column_spacing = 12;
grid.width_request = 300;
@@ -65,12 +90,14 @@ public class Monitor.SystemMemoryView : Gtk.Grid {
grid.attach (memory_cached_label, 0, 2, 1, 1);
grid.attach (memory_locked_label, 1, 2, 1, 1);
- return grid;
+ memory_usage_revealer.add (grid);
+
+ return memory_usage_revealer;
}
public void update () {
- memory_percentage_label.set_text ((_("Memory: % 3d%%")).printf (memory.percentage));
+ memory_percentage_label.set_text ((_("%d%%")).printf (memory.percentage));
memory_chart.update (0, memory.percentage);
memory_total_label.set_text ((_("Total: %s")).printf (Utils.HumanUnitFormatter.double_bytes_to_human(memory.total)));
diff --git a/src/Views/SystemView/SystemNetworkView.vala b/src/Views/SystemView/SystemNetworkView.vala
new file mode 100644
index 00000000..a89a3f86
--- /dev/null
+++ b/src/Views/SystemView/SystemNetworkView.vala
@@ -0,0 +1,48 @@
+public class Monitor.SystemNetworkView : Gtk.Grid {
+ private NetworkChart network_chart;
+ private Network network;
+
+ private LabelH4 network_name_label;
+ private LabelRoundy network_upload_label;
+ private LabelRoundy network_download_label;
+
+ construct {
+ margin = 12;
+ column_spacing = 12;
+ set_vexpand (false);
+ }
+
+ public SystemNetworkView (Network _network) {
+ network = _network;
+
+ network_name_label = new LabelH4 (_ ("Network"));
+ network_download_label = new LabelRoundy (_ ("DOWN"));
+ network_download_label.val.set_width_chars (7);
+ network_upload_label = new LabelRoundy (_ ("UP"));
+ network_upload_label.val.set_width_chars (7);
+
+ network_chart = new NetworkChart (2);
+
+ var labels_grid = new Gtk.Grid ();
+ labels_grid.row_spacing = 6;
+ labels_grid.column_spacing = 6;
+ labels_grid.margin = 6;
+ labels_grid.attach (network_download_label, 0, 0, 1, 1);
+ labels_grid.attach (network_upload_label, 1, 0, 1, 1);
+
+ attach (network_name_label, 0, 0, 1, 1);
+ attach (labels_grid, 0, 1, 2, 2);
+ attach (network_chart, 0, 1, 2, 2);
+ }
+
+ public void update () {
+ double up_bytes = network.get_bytes ()[0] / 2;
+ double down_bytes = network.get_bytes ()[1] / 2;
+ if (up_bytes >= 0 && down_bytes >= 0) {
+ network_download_label.set_text (("%s/s").printf (Utils.HumanUnitFormatter.string_bytes_to_human (down_bytes.to_string ())));
+ network_upload_label.set_text (("%s/s").printf (Utils.HumanUnitFormatter.string_bytes_to_human (up_bytes.to_string ())));
+ network_chart.update (0, up_bytes);
+ network_chart.update (1, down_bytes);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Views/SystemView/SystemView.vala b/src/Views/SystemView/SystemView.vala
index 162d5467..c1dc8bee 100644
--- a/src/Views/SystemView/SystemView.vala
+++ b/src/Views/SystemView/SystemView.vala
@@ -3,6 +3,7 @@ public class Monitor.SystemView : Gtk.Box {
private SystemCPUView cpu_view;
private SystemMemoryView memory_view;
+ private SystemNetworkView network_view;
construct {
orientation = Gtk.Orientation.VERTICAL;
@@ -14,13 +15,16 @@ public class Monitor.SystemView : Gtk.Box {
cpu_view = new SystemCPUView (resources.cpu);
memory_view = new SystemMemoryView (resources.memory);
+ network_view = new SystemNetworkView (resources.network);
add (cpu_view);
add (memory_view);
+ add (network_view);
}
public void update () {
cpu_view.update();
memory_view.update();
+ network_view.update ();
}
}
\ No newline at end of file
diff --git a/src/Views/SystemView/SystemCPUChart.vala b/src/Widgets/Chart/Chart.vala
similarity index 50%
rename from src/Views/SystemView/SystemCPUChart.vala
rename to src/Widgets/Chart/Chart.vala
index 492112c6..dfd85ec8 100644
--- a/src/Views/SystemView/SystemCPUChart.vala
+++ b/src/Widgets/Chart/Chart.vala
@@ -1,13 +1,8 @@
-public class Monitor.SystemCPUChart : Gtk.Box {
- private LiveChart.Chart chart;
- private LiveChart.Config config;
-
- // private Gee.ArrayList serie_list;
-
+public class Monitor.Chart : Gtk.Box {
+ private LiveChart.Chart live_chart;
+ public LiveChart.Config config;
construct {
- // serie_list = new Gee.ArrayList ();
-
get_style_context ().add_class ("graph");
vexpand = true;
@@ -28,43 +23,43 @@ public class Monitor.SystemCPUChart : Gtk.Box {
left = -1
};
- chart = new LiveChart.Chart (config);
- chart.expand = true;
- chart.legend.visible = false;
- chart.grid.visible = true;
- chart.background.main_color = Gdk.RGBA () {
+ live_chart = new LiveChart.Chart (config);
+ live_chart.expand = true;
+ live_chart.legend.visible = false;
+ live_chart.grid.visible = true;
+ live_chart.background.main_color = Gdk.RGBA () {
red= 1, green= 1, blue= 1, alpha= 1
}; //White background
-
}
- public SystemCPUChart (int cores_quantity) {
- for (int i = 0; i < cores_quantity; i++) {
+ public Chart (int series_quantity) {
+ for (int i = 0; i < series_quantity; i++) {
var renderer = new LiveChart.SmoothLineArea (new LiveChart.Values(1000));
- var serie = new LiveChart.Serie ("Core x", renderer);
+ var serie = new LiveChart.Serie (("Serie %d").printf(i), renderer);
serie.set_main_color ({ 0.35 + i/20, 0.8, 0.1, 1.0});
- chart.add_serie (serie);
- // serie_list.add (serie);
- }
+ live_chart.add_serie (serie);
- add (chart);
+ // workaround for `gee_collection_get_size: assertion 'self != NULL' failed`
+ // https://github.com/lcallarec/live-chart/issues/16
+ live_chart.add_value (serie, 0);
+ }
+ add (live_chart);
}
public void update (int serie_number, double value) {
- // debug("%f", value);
- // chart.add_value (serie_list.get(serie_number), value);
- chart.add_value_by_index (serie_number, value);
+ live_chart.add_value_by_index (serie_number, value);
}
- // public void set_data (Gee.ArrayList history) {
+ // public void set_data (int serie_number, Gee.ArrayList history) {
// var refresh_rate_is_ms = 2000; //your own refresh rate in milliseconds
- // chart.add_unaware_timestamp_collection(serie_list[0], history, refresh_rate_is_ms);
+ // live_chart.add_unaware_timestamp_collection(live_chart.series[serie_number], history, refresh_rate_is_ms);
// }
+
public void clear () {
- // var series = chart.series;
- // foreach (var serie in serie_list) {
+ // var series = live_chart.series;
+ // foreach (var serie in series) {
// serie.clear();
// }
}
diff --git a/src/Widgets/Chart/NetworkChart.vala b/src/Widgets/Chart/NetworkChart.vala
new file mode 100644
index 00000000..ae8e8b1c
--- /dev/null
+++ b/src/Widgets/Chart/NetworkChart.vala
@@ -0,0 +1,67 @@
+public class Monitor.NetworkChart : Gtk.Box {
+ private LiveChart.Chart live_chart;
+ public LiveChart.Config config;
+
+ construct {
+ get_style_context ().add_class ("graph");
+
+ vexpand = true;
+ height_request = 120;
+
+ config = new LiveChart.Config ();
+ // config.y_axis.unit = "%";
+ // config.y_axis.tick_interval = 25;
+ // config.y_axis.fixed_max = 100.0;
+ config.y_axis.labels.visible = false;
+ config.x_axis.labels.visible = false;
+
+ config.padding = LiveChart.Padding () {
+ smart = LiveChart.AutoPadding.NONE,
+ top = 0,
+ right = 0,
+ bottom = 0,
+ left = -1
+ };
+
+ live_chart = new LiveChart.Chart (config);
+ live_chart.expand = true;
+ live_chart.legend.visible = false;
+ live_chart.grid.visible = true;
+ live_chart.background.main_color = Gdk.RGBA () {
+ red= 1, green= 1, blue= 1, alpha= 1
+ }; //White background
+
+ }
+
+ public NetworkChart (int series_quantity) {
+ for (int i = 0; i < series_quantity; i++) {
+ var renderer = new LiveChart.SmoothLineArea (new LiveChart.Values(1000));
+ var serie = new LiveChart.Serie (("Serie %d").printf(i), renderer);
+ serie.set_main_color ({ 0.35 + i/20, 0.8, 0.1, 1.0});
+ live_chart.add_serie (serie);
+
+ // workaround for `gee_collection_get_size: assertion 'self != NULL' failed`
+ // https://github.com/lcallarec/live-chart/issues/16
+ // why 3? I don't know.
+ live_chart.add_value (serie, 3);
+ }
+ add (live_chart);
+ }
+
+ public void update (int serie_number, double value) {
+ live_chart.add_value_by_index (serie_number, value);
+ }
+
+ // public void set_data (int serie_number, Gee.ArrayList history) {
+ // var refresh_rate_is_ms = 2000; //your own refresh rate in milliseconds
+ // live_chart.add_unaware_timestamp_collection(live_chart.series[serie_number], history, refresh_rate_is_ms);
+ // }
+
+
+ public void clear () {
+ // var series = live_chart.series;
+ // foreach (var serie in series) {
+ // serie.clear();
+ // }
+ }
+}
diff --git a/src/Views/ProcessView/ProcessInfoView/Chart.vala b/src/Widgets/Chart/ProcessChart.vala
similarity index 93%
rename from src/Views/ProcessView/ProcessInfoView/Chart.vala
rename to src/Widgets/Chart/ProcessChart.vala
index 3e320b5e..045c70b0 100644
--- a/src/Views/ProcessView/ProcessInfoView/Chart.vala
+++ b/src/Widgets/Chart/ProcessChart.vala
@@ -1,4 +1,4 @@
-public class Monitor.Chart : Gtk.Box {
+public class Monitor.ProcessChart : Gtk.Box {
private LiveChart.Serie serie;
private LiveChart.SmoothLineArea renderer;
private LiveChart.Chart chart;
@@ -46,7 +46,7 @@ public class Monitor.Chart : Gtk.Box {
chart.add_value (serie, value);
}
- public void set_data (Gee.ArrayList history) {
+ public new void set_data (Gee.ArrayList history) {
var refresh_rate_is_ms = 2000; //your own refresh rate in milliseconds
chart.add_unaware_timestamp_collection(serie, history, refresh_rate_is_ms);
}
@@ -54,4 +54,4 @@ public class Monitor.Chart : Gtk.Box {
public void clear () {
serie.clear();
}
-}
+}
\ No newline at end of file
diff --git a/src/Widgets/Labels/LabelH4.vala b/src/Widgets/Labels/LabelH4.vala
new file mode 100644
index 00000000..55f1560b
--- /dev/null
+++ b/src/Widgets/Labels/LabelH4.vala
@@ -0,0 +1,14 @@
+class LabelH4 : Gtk.Label {
+
+ construct {
+ get_style_context ().add_class ("h4");
+ valign = Gtk.Align.START;
+ halign = Gtk.Align.START;
+ margin_start = 6;
+ ellipsize = Pango.EllipsizeMode.END;
+ }
+
+ public LabelH4 (string label) {
+ Object (label: label);
+ }
+}
\ No newline at end of file
diff --git a/src/Views/ProcessView/ProcessInfoView/RoundyLabel.vala b/src/Widgets/Labels/LabelRoundy.vala
similarity index 69%
rename from src/Views/ProcessView/ProcessInfoView/RoundyLabel.vala
rename to src/Widgets/Labels/LabelRoundy.vala
index 7a8964d4..dd490cdd 100644
--- a/src/Views/ProcessView/ProcessInfoView/RoundyLabel.vala
+++ b/src/Widgets/Labels/LabelRoundy.vala
@@ -1,14 +1,14 @@
-public class Monitor.RoundyLabel : Gtk.Fixed {
+public class Monitor.LabelRoundy : Gtk.Fixed {
public Gtk.Label val;
public Gtk.Label desc;
- public RoundyLabel (string description) {
+ public LabelRoundy (string description) {
val = new Gtk.Label (Utils.NO_DATA);
val.get_style_context ().add_class ("roundy-label");
desc = new Gtk.Label (description);
- desc.get_style_context ().add_class ("pid");
+ desc.get_style_context ().add_class ("small-text");
put(val, 0, 12);
put(desc, 6, 0);
diff --git a/src/Widgets/Labels/LabelVertical.vala b/src/Widgets/Labels/LabelVertical.vala
new file mode 100644
index 00000000..f7fa2546
--- /dev/null
+++ b/src/Widgets/Labels/LabelVertical.vala
@@ -0,0 +1,43 @@
+public class Monitor.LabelVertical : Gtk.EventBox {
+
+ private Gtk.Grid grid;
+
+ public signal void clicked ();
+
+ public Gtk.Label val;
+ public Gtk.Label desc;
+
+ construct {
+ grid = new Gtk.Grid ();
+ margin_start = 12;
+ margin_top = 6;
+
+ get_style_context ().add_class ("label-vertical");
+ }
+
+ public LabelVertical (string description) {
+ val = new Gtk.Label (Utils.NO_DATA);
+
+ val.get_style_context ().add_class ("label-vertical-val");
+
+ desc = new Gtk.Label (description);
+ desc.get_style_context ().add_class ("small-text");
+
+ grid.attach(desc, 0, 0, 1, 1);
+ grid.attach(val, 0, 1, 1, 1);
+
+ add (grid);
+
+ events |= Gdk.EventMask.BUTTON_RELEASE_MASK;
+
+ button_release_event.connect ((event) => {
+ clicked ();
+ return false;
+ });
+
+ }
+
+ public void set_text (string text) {
+ val.set_text (text);
+ }
+}
\ No newline at end of file
diff --git a/src/Widgets/Statusbar/Statusbar.vala b/src/Widgets/Statusbar/Statusbar.vala
index d30193e6..26fa62bd 100644
--- a/src/Widgets/Statusbar/Statusbar.vala
+++ b/src/Widgets/Statusbar/Statusbar.vala
@@ -14,15 +14,21 @@ public class Monitor.Statusbar : Gtk.ActionBar {
swap_icon.tooltip_text = _ ("Swap");
cpu_usage_label = new Gtk.Label (_("Calculating…"));
+ cpu_usage_label.set_width_chars (4);
+ cpu_usage_label.xalign = 0;
pack_start (cpu_icon);
pack_start (cpu_usage_label);
memory_usage_label = new Gtk.Label (_("Calculating…"));
+ memory_usage_label.set_width_chars (4);
+ memory_usage_label.xalign = 0;
ram_icon.margin_start = 6;
pack_start (ram_icon);
pack_start (memory_usage_label);
swap_usage_label = new Gtk.Label (_("Calculating…"));
+ swap_usage_label.set_width_chars (4);
+ swap_usage_label.xalign = 0;
swap_icon.margin_start = 6;
pack_start (swap_icon);
pack_start (swap_usage_label);
diff --git a/vapi/libgtop-2.0.vapi b/vapi/libgtop-2.0.vapi
index e8db74b8..b69e634b 100644
--- a/vapi/libgtop-2.0.vapi
+++ b/vapi/libgtop-2.0.vapi
@@ -45,6 +45,7 @@ namespace GTop {
public void get_msg_limits_s (out GTop.MsgLimits buf);
public void get_netload_l (out GTop.NetLoad buf, string @interface);
public void get_netload_s (out GTop.NetLoad buf, string @interface);
+ public string[] get_netlist (out GTop.NetList buf);
public ulong get_parameter_l (uint parameter, void* data_ptr, ulong data_size);
public void get_ppp_l (out GTop.Ppp buf, ushort device);
public void get_ppp_s (out GTop.Ppp buf, ushort device);
@@ -127,9 +128,9 @@ namespace GTop {
[CCode (cheader_filename = "glibtop/sysinfo.h", cname = "glibtop_entry", has_type_id = false)]
public struct Entry {
- public weak GLib.GenericArray labels;
- public weak GLib.HashTable values;
- public weak GLib.HashTable descriptions;
+ public GLib.PtrArray labels;
+ public GLib.HashTable values;
+ public GLib.HashTable descriptions;
}
[CCode (cheader_filename = "glibtop/fsusage.h", cname = "glibtop_fsusage", has_type_id = false)]
@@ -521,7 +522,7 @@ namespace GTop {
public uint64 flags;
public uint64 ncpu;
[CCode (array_length = false, array_null_terminated = true)]
- public weak GTop.Entry[] cpuinfo;
+ public unowned Entry[] cpuinfo;
}
[CCode (cheader_filename = "glibtop/union.h", cname = "glibtop_union")]
@@ -1273,6 +1274,8 @@ namespace GTop {
public static void get_msg_limits (out GTop.MsgLimits buf);
[CCode (cheader_filename = "glibtop.h", cname = "glibtop_get_netload")]
public static void get_netload (out GTop.NetLoad buf, string @interface);
+ [CCode (cheader_filename = "glibtop/netlist.h", cname = "glibtop_get_netlist", array_length = false, array_null_terminated = true)]
+ public static string[] get_netlist (out GTop.NetList buf);
[CCode (cheader_filename = "glibtop.h", cname = "glibtop_get_ppp")]
public static void get_ppp (out GTop.Ppp buf, ushort device);
[CCode (cheader_filename = "glibtop.h", cname = "glibtop_get_proc_affinity")]