[gnome-system-monitor] Add data points config option
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-system-monitor] Add data points config option
- Date: Wed, 4 Nov 2020 17:37:33 +0000 (UTC)
commit 753fb7a4a90734f37aef98b240d8732707985056
Author: ToMe25 <tome25 gmx de>
Date: Wed Nov 4 17:37:32 2020 +0000
Add data points config option
This allows the user to set the number of data points shown in the
resources view to anything between 30 and 600.
data/preferences.ui | 50 +++++++-
src/application.cpp | 14 +++
src/application.h | 2 +
src/legacy/gsm_color_button.c | 1 +
src/load-graph.cpp | 146 ++++++++++++++++++----
src/load-graph.h | 13 +-
src/org.gnome.gnome-system-monitor.gschema.xml.in | 6 +
src/prefsdialog.cpp | 40 +++++-
src/settings-keys.h | 1 +
9 files changed, 239 insertions(+), 34 deletions(-)
---
diff --git a/data/preferences.ui b/data/preferences.ui
index 6f4b7b0b..54c18df2 100644
--- a/data/preferences.ui
+++ b/data/preferences.ui
@@ -379,6 +379,50 @@
<property name="height">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkGrid" id="graph_data_points">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="graph_data_points_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_Chart data points:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">graph_data_points_scale</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScale" id="graph_data_points_scale">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="draw-value">True</property>
+ <property name="value-pos">right</property>
+ <property name="digits">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">18</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
<child>
<object class="GtkCheckButton" id="draw_stacked_button">
<property name="label" translatable="yes">_Draw CPU chart as stacked area
chart</property>
@@ -392,7 +436,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">1</property>
+ <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@@ -410,7 +454,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">2</property>
+ <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@@ -428,7 +472,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">3</property>
+ <property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
diff --git a/src/application.cpp b/src/application.cpp
index b08305c7..9af91110 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -83,6 +83,15 @@ cb_timeouts_changed (Gio::Settings& settings, Glib::ustring key, GsmApplication*
}
}
+static void
+cb_data_points_changed(Gio::Settings& settings, Glib::ustring key, GsmApplication* app) {
+ app->config.graph_data_points = settings.get_int (key);
+ unsigned points = app->config.graph_data_points + 2;
+ load_graph_change_num_points(app->cpu_graph, points);
+ load_graph_change_num_points(app->mem_graph, points);
+ load_graph_change_num_points(app->net_graph, points);
+}
+
static void
apply_cpu_color_settings(Gio::Settings& settings, GsmApplication* app)
{
@@ -189,6 +198,11 @@ GsmApplication::load_settings()
config.disks_update_interval = this->settings->get_int (GSM_SETTING_DISKS_UPDATE_INTERVAL);
this->settings->signal_changed (GSM_SETTING_DISKS_UPDATE_INTERVAL).connect (cbtc);
+ config.graph_data_points = this->settings->get_int (GSM_SETTING_GRAPH_DATA_POINTS);
+ this->settings->signal_changed (GSM_SETTING_GRAPH_DATA_POINTS).connect ([this](const Glib::ustring& key)
{
+ cb_data_points_changed (*this->settings.operator->(), key, this);
+ });
+
glibtop_get_cpu (&cpu);
frequency = cpu.frequency;
diff --git a/src/application.h b/src/application.h
index 57385f6a..dbaf8d29 100644
--- a/src/application.h
+++ b/src/application.h
@@ -33,6 +33,7 @@ struct ProcConfig
: update_interval(0),
graph_update_interval(0),
disks_update_interval(0),
+ graph_data_points(0),
mem_color(),
swap_color(),
net_in_color(),
@@ -51,6 +52,7 @@ struct ProcConfig
int update_interval;
int graph_update_interval;
int disks_update_interval;
+ int graph_data_points;
GdkRGBA cpu_color[GLIBTOP_NCPU];
GdkRGBA mem_color;
GdkRGBA swap_color;
diff --git a/src/legacy/gsm_color_button.c b/src/legacy/gsm_color_button.c
index e23e9b6e..81aebb7e 100644
--- a/src/legacy/gsm_color_button.c
+++ b/src/legacy/gsm_color_button.c
@@ -852,6 +852,7 @@ gsm_color_button_get_property (GObject * object,
break;
case PROP_TYPE:
g_value_set_uint (value, gsm_color_button_get_cbtype (color_button));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
diff --git a/src/load-graph.cpp b/src/load-graph.cpp
index 6656746c..715be931 100644
--- a/src/load-graph.cpp
+++ b/src/load-graph.cpp
@@ -72,8 +72,8 @@ static void draw_background(LoadGraph *graph) {
num_bars = graph->num_bars();
graph->graph_dely = (graph->draw_height - 15) / num_bars; /* round to int to avoid AA blur */
graph->real_draw_height = graph->graph_dely * num_bars;
- graph->graph_delx = (graph->draw_width - 2.0 - graph->indent) / (LoadGraph::NUM_POINTS - 3);
- graph->graph_buffer_offset = (int) (1.5 * graph->graph_delx) + FRAME_WIDTH ;
+ graph->graph_delx = (graph->draw_width - 2.0 - graph->indent) / (graph->num_points - 3);
+ graph->graph_buffer_offset = (int) (1.5 * graph->graph_delx) + FRAME_WIDTH;
gtk_widget_get_allocation (GTK_WIDGET (graph->disp), &allocation);
surface = gdk_window_create_similar_surface (gtk_widget_get_window (GTK_WIDGET (graph->disp)),
@@ -172,7 +172,7 @@ static void draw_background(LoadGraph *graph) {
}
- const unsigned total_seconds = graph->speed * (LoadGraph::NUM_POINTS - 2) / 1000;
+ const unsigned total_seconds = graph->speed * (graph->num_points - 2) / 1000;
for (unsigned int i = 0; i < 7; i++) {
double x = (i) * (graph->draw_width - graph->rmargin - graph->indent) / 6;
@@ -187,16 +187,57 @@ static void draw_background(LoadGraph *graph) {
cairo_line_to (cr, (ceil(x) + 0.5) + graph->indent, graph->real_draw_height + 4.5);
cairo_stroke(cr);
unsigned seconds = total_seconds - i * total_seconds / 6;
- const char* format;
- if (i == 0)
- format = dngettext(GETTEXT_PACKAGE, "%u second", "%u seconds", seconds);
- else
- format = "%u";
- caption = g_strdup_printf(format, seconds);
+ unsigned minutes = seconds / 60;
+ unsigned hours = seconds / 3600;
+ caption = NULL;
+
+ if (hours != 0) {
+ if (minutes % 60 == 0) {
+ // If minutes mod 60 is 0 set it to 0, to prevent it from showing full hours in
+ // minutes in addition to hours.
+ minutes = 0;
+ } else {
+ // Round minutes as seconds wont get shown if neither hours nor minutes are 0.
+ minutes = int(rint(seconds / 60.0)) % 60;
+ if (minutes == 0) {
+ // Increase hours if rounding minutes results in 0, because that would be
+ // what it would be rounded to.
+ hours++;
+ // Set seconds to hours * 3600 to prevent seconds from being drawn.
+ seconds = hours * 3600;
+ }
+ }
+
+ caption = g_strdup_printf(dngettext(GETTEXT_PACKAGE, "%u hr ", "%u hrs ", hours), hours);
+ }
+ if (minutes != 0) {
+ char* captionM = g_strdup_printf(dngettext(GETTEXT_PACKAGE, "%u min", "%u mins", minutes),
+ minutes);
+ if (caption == NULL) {
+ caption = captionM;
+ } else {
+ caption = strcat(caption, captionM);
+ }
+
+ // Add a whitespace if minutes and seconds are shown
+ if (hours == 0 && seconds % 60 != 0) {
+ caption = strcat(caption, " ");
+ }
+ }
+ if (caption == NULL || (seconds % 60 != 0 && (minutes == 0 || hours == 0))) {
+ char* captionS = g_strdup_printf(dngettext(GETTEXT_PACKAGE, "%u sec", "%u secs", seconds % 60),
+ seconds % 60);
+ if (caption == NULL) {
+ caption = captionS;
+ } else {
+ caption = strcat(caption, captionS);
+ }
+ }
+
pango_layout_set_text (layout, caption, -1);
pango_layout_get_extents (layout, NULL, &extents);
cairo_move_to (cr,
- (ceil(x) + 0.5 + graph->indent) - (1.0 * extents.width / PANGO_SCALE / 2),
+ (ceil(x) + 0.5 + graph->indent) - (1.0 * extents.width / PANGO_SCALE / 2) + 1.0,
graph->draw_height - 1.0 * extents.height / PANGO_SCALE);
gdk_cairo_set_source_rgba (cr, &fg);
pango_cairo_show_layout (cr, layout);
@@ -274,7 +315,7 @@ load_graph_draw (GtkWidget *widget,
gdouble sample_width, x_offset;
/* Number of pixels wide for one sample point */
- sample_width = (double)(graph->draw_width - graph->rmargin - graph->indent) /
(double)LoadGraph::NUM_POINTS;
+ sample_width = (double)(graph->draw_width - graph->rmargin - graph->indent) / (double)graph->num_points;
/* Lines start at the right edge of the drawing,
* a bit outside the clip rectangle. */
x_offset = graph->draw_width - graph->rmargin + sample_width + 2;
@@ -305,7 +346,7 @@ load_graph_draw (GtkWidget *widget,
cairo_move_to (cr, x_offset, (1.0f - graph->data[0][j]) * graph->real_draw_height + 3);
// then draw the path of the line.
// Loop starts at 1 because the curve accesses the 0th data point.
- for (i = 1; i < LoadGraph::NUM_POINTS; ++i) {
+ for (i = 1; i < graph->num_points; ++i) {
if (graph->data[i][j] == -1.0f)
continue;
if (drawSmooth) {
@@ -477,12 +518,12 @@ get_memory (LoadGraph *graph)
static double
nicenum (double x, int round)
{
- int expv; /* exponent of x */
- double f; /* fractional part of x */
- double nf; /* nice, rounded fraction */
+ int expv; /* exponent of x */
+ double f; /* fractional part of x */
+ double nf; /* nice, rounded fraction */
expv = floor(log10(x));
- f = x/pow(10.0, expv); /* between 1 and 10 */
+ f = x/pow(10.0, expv); /* between 1 and 10 */
if (round) {
if (f < 1.5)
nf = 1.0;
@@ -512,8 +553,11 @@ net_scale (LoadGraph *graph, guint64 din, guint64 dout)
graph->data[0][1] = 1.0f * dout / graph->net.max;
guint64 dmax = std::max(din, dout);
- graph->net.values[graph->net.cur] = dmax;
- graph->net.cur = (graph->net.cur + 1) % LoadGraph::NUM_POINTS;
+ if (graph->latest == 0) {
+ graph->net.values[graph->num_points - 1] = dmax;
+ } else {
+ graph->net.values[graph->latest - 1] = dmax;
+ }
guint64 new_max;
// both way, new_max is the greatest value
@@ -521,7 +565,7 @@ net_scale (LoadGraph *graph, guint64 din, guint64 dout)
new_max = dmax;
else
new_max = *std::max_element(&graph->net.values[0],
- &graph->net.values[LoadGraph::NUM_POINTS]);
+ &graph->net.values[graph->num_points]);
//
// Round network maximum
@@ -590,7 +634,7 @@ net_scale (LoadGraph *graph, guint64 din, guint64 dout)
const double scale = 1.0f * graph->net.max / new_max;
- for (size_t i = 0; i < LoadGraph::NUM_POINTS; i++) {
+ for (size_t i = 0; i < graph->num_points; i++) {
if (graph->data[i][0] >= 0.0f) {
graph->data[i][0] *= scale;
graph->data[i][1] *= scale;
@@ -685,8 +729,11 @@ load_graph_update_data (LoadGraph *graph)
{
// Rotate data one element down.
std::rotate(&graph->data[0],
- &graph->data[LoadGraph::NUM_POINTS - 1],
- &graph->data[LoadGraph::NUM_POINTS]);
+ &graph->data[graph->num_points - 1],
+ &graph->data[graph->num_points]);
+
+ // Update rotation counter.
+ graph->latest = (graph->latest + 1) % graph->num_points;
// Replace the 0th element
switch (graph->type) {
@@ -758,6 +805,8 @@ LoadGraph::LoadGraph(guint type)
n(0),
type(type),
speed(0),
+ num_points(0),
+ latest(0),
draw_width(0),
draw_height(0),
render_counter(0),
@@ -768,6 +817,7 @@ LoadGraph::LoadGraph(guint type)
graph_buffer_offset(0),
colors(),
data_block(),
+ data(),
main_widget(NULL),
disp(NULL),
background(NULL),
@@ -838,7 +888,9 @@ LoadGraph::LoadGraph(guint type)
break;
}
- speed = GsmApplication::get()->config.graph_update_interval;
+ speed = GsmApplication::get()->config.graph_update_interval;
+
+ num_points = GsmApplication::get()->config.graph_data_points + 2;
colors.resize(n);
@@ -856,6 +908,7 @@ LoadGraph::LoadGraph(guint type)
GSMCP_TYPE_PIE);
break;
case LOAD_GRAPH_NET:
+ net.values = std::vector<unsigned>(num_points);
colors[0] = GsmApplication::get()->config.net_in_color;
colors[1] = GsmApplication::get()->config.net_out_color;
break;
@@ -886,11 +939,11 @@ LoadGraph::LoadGraph(guint type)
gtk_box_pack_start (main_widget, GTK_WIDGET (disp), TRUE, TRUE, 0);
-
+ data = std::vector<double*>(num_points);
/* Allocate data in a contiguous block */
- data_block = std::vector<double>(n * LoadGraph::NUM_POINTS, -1.0);
+ data_block = std::vector<double>(n * num_points, -1.0);
- for (guint i = 0; i < LoadGraph::NUM_POINTS; ++i)
+ for (guint i = 0; i < num_points; ++i)
data[i] = &data_block[0] + i * n;
gtk_widget_show_all (GTK_WIDGET (main_widget));
@@ -939,6 +992,47 @@ load_graph_change_speed (LoadGraph *graph,
graph->clear_background();
}
+void
+load_graph_change_num_points(LoadGraph *graph,
+ guint new_num_points)
+{
+ //Don't do anything if the value didn't change.
+ if (graph->num_points == new_num_points)
+ return;
+
+ // Sort the values in the data_block vector in the order they were accessed in by the pointers in data.
+ std::rotate(&graph->data_block[0],
+ &graph->data_block[(graph->num_points - graph->latest) * graph->n],
+ &graph->data_block[graph->num_points * graph->n]);
+
+ // Reset rotation counter.
+ graph->latest = 0;
+
+ // Resize the vectors to the new amount of data points.
+ graph->data.resize(new_num_points);
+ graph->data_block.resize(graph->n * new_num_points);
+ if (graph->type == LOAD_GRAPH_NET) {
+ graph->net.values.resize(new_num_points);
+ }
+
+ // Fill the new values with -1 instead of 0 if the vectors got bigger.
+ if (new_num_points > graph->num_points) {
+ std::fill(&graph->data_block[graph->n * graph->num_points],
+ &graph->data_block[graph->n * new_num_points], -1.0);
+ }
+
+ // Replace the pointers in data, to match the new data_block values.
+ for (guint i = 0; i < new_num_points; ++i) {
+ graph->data[i] = &graph->data_block[0] + i * graph->n;
+ }
+
+ // Set the actual number of data points to be used by the graph.
+ graph->num_points = new_num_points;
+
+ // Force the scale to be redrawn.
+ graph->clear_background();
+}
+
LoadGraphLabels*
load_graph_get_labels (LoadGraph *graph)
diff --git a/src/load-graph.h b/src/load-graph.h
index 1be59ad1..a49736de 100644
--- a/src/load-graph.h
+++ b/src/load-graph.h
@@ -36,7 +36,6 @@ struct LoadGraphLabels
struct LoadGraph
: private procman::NonCopyable
{
- static const unsigned NUM_POINTS = 60 + 2;
static const unsigned GRAPH_MIN_HEIGHT = 40;
LoadGraph(guint type);
@@ -53,6 +52,8 @@ struct LoadGraph
guint n;
gint type;
guint speed;
+ guint num_points;
+ guint latest;
guint draw_width, draw_height;
guint render_counter;
guint frames_per_unit;
@@ -64,7 +65,7 @@ struct LoadGraph
std::vector<GdkRGBA> colors;
std::vector<double> data_block;
- double* data[NUM_POINTS];
+ std::vector<double*> data;
GtkBox *main_widget;
GtkDrawingArea *disp;
@@ -93,8 +94,7 @@ struct LoadGraph
guint64 last_in, last_out;
guint64 time;
guint64 max;
- unsigned values[NUM_POINTS];
- size_t cur;
+ std::vector<unsigned> values;
} net;
/* }; */
};
@@ -116,6 +116,11 @@ void
load_graph_change_speed (LoadGraph *g,
guint new_speed);
+/* Change load graph data points and restart it if it has been previously started */
+void
+load_graph_change_num_points(LoadGraph *g,
+ guint new_num_points);
+
/* Clear the history data. */
void
load_graph_reset (LoadGraph *g);
diff --git a/src/org.gnome.gnome-system-monitor.gschema.xml.in
b/src/org.gnome.gnome-system-monitor.gschema.xml.in
index 0c7a03d1..e66a91f7 100644
--- a/src/org.gnome.gnome-system-monitor.gschema.xml.in
+++ b/src/org.gnome.gnome-system-monitor.gschema.xml.in
@@ -69,6 +69,12 @@
<summary>Time in milliseconds between updates of the devices list</summary>
</key>
+ <key name="graph-data-points" type="i">
+ <range min="30" max="600"/>
+ <default>60</default>
+ <summary>Time amount of data points in the resource graphs</summary>
+ </key>
+
<key name="show-whose-processes" type="s">
<default>'user'</default>
<choices>
diff --git a/src/prefsdialog.cpp b/src/prefsdialog.cpp
index 9f18fd72..d433265b 100644
--- a/src/prefsdialog.cpp
+++ b/src/prefsdialog.cpp
@@ -43,7 +43,7 @@ private:
void update(GtkSpinButton* spin)
{
- int new_value = int(1000 * gtk_spin_button_get_value(spin));
+ int new_value = 1000 * gtk_spin_button_get_value(spin);
GsmApplication::get()->settings->set_int(this->key, new_value);
@@ -53,6 +53,34 @@ private:
const string key;
};
+class ScaleUpdater
+{
+public:
+ ScaleUpdater(const string& key)
+ : key(key)
+ { }
+
+ static gboolean callback(GtkRange *range, gpointer data)
+ {
+ ScaleUpdater* updater = static_cast<ScaleUpdater*>(data);
+ updater->update(range);
+ return FALSE;
+ }
+
+private:
+
+ void update(GtkRange* range)
+ {
+ int new_value = gtk_range_get_value(range);
+
+ GsmApplication::get()->settings->set_int(this->key, new_value);
+
+ procman_debug("set %s to %d", this->key.c_str(), new_value);
+ }
+
+ const string key;
+};
+
static void
field_toggled (const gchar *gsettings_parent, gchar *path_str, gpointer data)
{
@@ -199,6 +227,7 @@ create_preferences_dialog (GsmApplication *app)
static SBU interval_updater("update-interval");
static SBU graph_interval_updater("graph-update-interval");
static SBU disks_interval_updater("disks-interval");
+ static ScaleUpdater graph_points_updater("graph-data-points");
GtkNotebook *notebook;
GtkAdjustment *adjustment;
@@ -266,6 +295,15 @@ create_preferences_dialog (GsmApplication *app)
G_CALLBACK(SBU::callback),
&graph_interval_updater);
+ update = (gfloat) app->config.graph_data_points;
+ GtkRange* range = GTK_RANGE (gtk_builder_get_object (builder, "graph_data_points_scale"));
+ adjustment = gtk_range_get_adjustment (range);
+ gtk_adjustment_configure (adjustment, update, 30,
+ 600, 10, 50, 0);
+ g_signal_connect (G_OBJECT (range), "value-changed",
+ G_CALLBACK(ScaleUpdater::callback),
+ &graph_points_updater);
+
GtkCheckButton *bits_button = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "bits_button"));
g_settings_bind(app->settings->gobj (), GSM_SETTING_NETWORK_IN_BITS,
bits_button, "active",
diff --git a/src/settings-keys.h b/src/settings-keys.h
index 87fbb9f7..52bdc812 100644
--- a/src/settings-keys.h
+++ b/src/settings-keys.h
@@ -26,6 +26,7 @@
#define GSM_SETTING_DRAW_STACKED "cpu-stacked-area-chart"
#define GSM_SETTING_DRAW_SMOOTH "cpu-smooth-graph"
#define GSM_SETTING_NETWORK_IN_BITS "network-in-bits"
+#define GSM_SETTING_GRAPH_DATA_POINTS "graph-data-points"
#define GSM_SETTING_SHOW_CPU "show-cpu"
#define GSM_SETTING_SHOW_MEM "show-mem"
#define GSM_SETTING_SHOW_NETWORK "show-network"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]