From 39a1a8c9554f3d027942784159b3a55662afb55e Mon Sep 17 00:00:00 2001 From: info-cppsp Date: Tue, 13 Feb 2018 23:20:57 +0100 Subject: fix save order of sensors v2 --- sensors-applet/sensors-applet-settings.c | 554 ++++++++++++++++++++++++++----- sensors-applet/sensors-applet-settings.h | 3 +- sensors-applet/sensors-applet.c | 27 +- sensors-applet/sensors-applet.h | 1 + 4 files changed, 496 insertions(+), 89 deletions(-) diff --git a/sensors-applet/sensors-applet-settings.c b/sensors-applet/sensors-applet-settings.c index f6e1864..70dda3d 100644 --- a/sensors-applet/sensors-applet-settings.c +++ b/sensors-applet/sensors-applet-settings.c @@ -26,16 +26,22 @@ #include "sensors-applet.h" #include "sensors-applet-settings.h" -// these must be as the gsettings schema in file org.mate.sensors-applet.gschema.xml.in -// gsettings gvariant type string +/* #define SORT_DEBUG */ +#ifdef SORT_DEBUG +#include +#endif + +/* these must be as the gsettings schema in file org.mate.sensors-applet.gschema.xml.in + * gsettings gvariant type string */ #define GSGVTS "s" -// gsettings gvariant type string for the array +/* gsettings gvariant type string for the array */ #define GSGVTSA "as" + gchar* sensors_applet_settings_get_unique_id (const gchar *interface, const gchar *id, const gchar *path) { - gchar *unique_id; - gchar *unique_id_hash; - GChecksum *checksum; + gchar *unique_id = NULL; + gchar *unique_id_hash = NULL; + GChecksum *checksum = NULL; guint8 digest[16]; gsize digest_len = sizeof (digest); @@ -54,55 +60,53 @@ gchar* sensors_applet_settings_get_unique_id (const gchar *interface, const gcha return unique_id_hash; } - -/* gets called if are already setup so we don't have to manually go - through and find sensors etc again */ -gboolean sensors_applet_conf_setup_sensors(SensorsApplet *sensors_applet) { +/* load sensors from gsettings with sorting */ +gboolean sensors_applet_settings_load_sensors (SensorsApplet *sensors_applet) { /* everything gets stored except alarm timeout indexes, which we set to -1, and visible which we set to false for all parent nodes and true for all child nodes */ - gchar *applet_path; - // not sure about pointer, it is unclear if it is freed by loop, probably yes - GVariantIter *iter; - gchar *gsuid; - - // string variables, to help free up memory in loop - gchar *current_path, - *current_id, - *current_label, - *current_interface, - *current_low_alarm_command, - *current_high_alarm_command, - *current_graph_color; - - // get gsettings path for applet + gchar *applet_path = NULL; + /* not sure about pointer, it is unclear if it is freed by loop, probably yes */ + GVariantIter *iter = NULL; + gchar *gsuid = NULL; + + /* string variables, to help free up memory in loop */ + gchar *current_path = NULL; + gchar *current_id = NULL; + gchar *current_label = NULL; + gchar *current_interface = NULL; + gchar *current_low_alarm_command = NULL; + gchar *current_high_alarm_command = NULL; + gchar *current_graph_color = NULL; + + /* get gsettings path for applet */ applet_path = mate_panel_applet_get_preferences_path (sensors_applet->applet); - // get sensors-list array from gsettings + /* get sensors-list array from gsettings */ g_settings_get (sensors_applet->settings, "sensors-list", GSGVTSA, &iter); - // load sensor data into applet one by one - // first get unique id for the sensor - // then load sensor data from gsettings - // then add sensor - // gsuid is freed by g_variant_iter_loop() + /* load sensor data into applet one by one + * first get unique id for the sensor + * then load sensor data from gsettings + * then add sensor + * gsuid is freed by g_variant_iter_loop() */ while (g_variant_iter_loop (iter, GSGVTS, &gsuid)) { - // load sensor data from gsettings individually - // g_strdup_printf doesn't free args! - // applet_path is freed at the end + /* load sensor data from gsettings individually + * g_strdup_printf doesn't free args! + * applet_path is freed at the end */ gchar *path = g_strdup_printf ("%s%s/", applet_path, gsuid); - //g_free (gsuid); // freed by loop + /*g_free (gsuid); // freed by loop */ - // make a schema which points to one sensor data + /* make a schema which points to one sensor data */ GSettings *settings; settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", path); g_free (path); - // laod sensor data to temp variables - // g_settings_get_string allocates memory! - // sensors_applet_add_sensor() gtk_tree_store_set() copies strings, so free them + /* laod sensor data to temp variables + * g_settings_get_string allocates memory! + * sensors_applet_add_sensor() gtk_tree_store_set() copies strings, so free them */ sensors_applet_add_sensor(sensors_applet, current_path = g_settings_get_string (settings, PATH), current_id = g_settings_get_string (settings, ID), @@ -138,23 +142,417 @@ gboolean sensors_applet_conf_setup_sensors(SensorsApplet *sensors_applet) { return TRUE; } -// save sensor data under a unique hash -// save sensor sort in an array, with above hash +#ifdef SORT_DEBUG +/* print a gtk_tree_store (for debug) */ +static void sensors_applet_settings_print_sensors_tree (SensorsApplet *sensors_applet) { + + g_assert(sensors_applet); + g_assert(sensors_applet->sensors); + + GtkTreeIter interfaces_iter; + GtkTreeIter sensors_iter; + gboolean not_end_of_interfaces = TRUE; + gboolean not_end_of_sensors = TRUE; + gint interfaces_counter = 0; + gint sensors_counter = 0; + + gchar *interface_name = NULL; + gchar *sensor_id = NULL; + gchar *sensor_path = NULL; + gchar *sensor_hash = NULL; + + /* iterate through the sensor tree + * code from sensors-applet.c sensors_applet_add_sensor() + * first go through the interfaces */ + for (not_end_of_interfaces = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); + not_end_of_interfaces; + not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter), interfaces_counter++) { + + /* get interface name */ + gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter, INTERFACE_COLUMN, &interface_name, -1); + + /* print interface name */ + syslog(LOG_ERR, "#%d interface name: %s\n", interfaces_counter, interface_name); + + /* then go through the individual sensors under one interface */ + for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); + not_end_of_sensors; + not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter), sensors_counter++) { + + gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, + PATH_COLUMN, &sensor_path, + ID_COLUMN, &sensor_id, + -1); + + sensor_hash = sensors_applet_settings_get_unique_id (interface_name, sensor_id, sensor_path); + + /* print sensor data */ + syslog(LOG_ERR, "\t#%d sensor id: %s\n", sensors_counter, sensor_id); + syslog(LOG_ERR, "\t#%d sensor path: %s\n", sensors_counter, sensor_path); + syslog(LOG_ERR, "\t#%d sensor hash: %s\n\n", sensors_counter, sensor_hash); + + g_free(sensor_id); + g_free(sensor_path); + g_free(sensor_hash); + + } + + g_free(interface_name); + + } + +} +#endif + +/* compare two iters using their paths + * kinda same as active_sensor_compare () */ +static gint sensors_applet_settings_sort_sensors_iter_compare (SensorsApplet *sensors_applet, GtkTreeIter ti_a, GtkTreeIter ti_b) { + + GtkTreePath *tp_a; + GtkTreePath *tp_b; + gint ret_val; + + tp_a = gtk_tree_model_get_path (GTK_TREE_MODEL(sensors_applet->sensors), &ti_a); + tp_b = gtk_tree_model_get_path (GTK_TREE_MODEL(sensors_applet->sensors), &ti_b); + + ret_val = gtk_tree_path_compare(tp_a, tp_b); + + gtk_tree_path_free(tp_a); + gtk_tree_path_free(tp_b); + + return ret_val; +} + +/* find two sensors in the sensors tree based on their hash and sort them + * Return codes: + * 0: something went very wrong... + * 1: normal run, a and b are in place + * 2: hash_b has already been removed from the system + * 3: hash_a is not found */ +static gint sensors_applet_settings_sort_sensors_sort (SensorsApplet *sensors_applet, + const gchar *hash_a, + const gchar *hash_b, + gboolean a_is_first) { + + g_assert(sensors_applet); + g_assert(sensors_applet->sensors); + + GtkTreeIter interfaces_iter; + GtkTreeIter sensors_iter; + gboolean not_end_of_interfaces = TRUE; + gboolean not_end_of_sensors = TRUE; + + gchar *interface_name = NULL; + gchar *sensor_id = NULL; + gchar *sensor_path = NULL; + gchar *sensor_hash = NULL; + + GtkTreeIter interface_iter_a; + GtkTreeIter interface_iter_b; + GtkTreeIter sensor_iter_a; + GtkTreeIter sensor_iter_b; + gboolean found_a = FALSE; + gboolean found_b = FALSE; + + /* iterate through the sensor tree + * code from sensors-applet.c sensors_applet_add_sensor() + * first go through the interfaces */ + for (not_end_of_interfaces = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); + not_end_of_interfaces; + not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter)) { + + /* get interface name */ + gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter, INTERFACE_COLUMN, &interface_name, -1); + + /* then go through the individual sensors under one interface */ + for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); + not_end_of_sensors; + not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter)) { + + gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, + PATH_COLUMN, &sensor_path, + ID_COLUMN, &sensor_id, + -1); + + sensor_hash = sensors_applet_settings_get_unique_id (interface_name, sensor_id, sensor_path); + + /* save interface_name and iters for swap */ + if (g_ascii_strcasecmp(sensor_hash, hash_a) == 0) { + /* can copy by value, don't free */ + interface_iter_a = interfaces_iter; + sensor_iter_a = sensors_iter; + found_a = TRUE; + } + + if (g_ascii_strcasecmp(sensor_hash, hash_b) == 0) { + interface_iter_b = interfaces_iter; + sensor_iter_b = sensors_iter; + found_b = TRUE; + } + + g_free(sensor_id); + g_free(sensor_path); + g_free(sensor_hash); + + /* break after freeing loop variables */ + if (found_a && found_b) { + break; + } + } + + g_free(interface_name); + + /* break after freeing loop variables */ + if (found_a && found_b) { + break; + } + } + + /* make the switch */ + if (found_a && found_b) { + + GtkTreeIter first_iter; + GtkTreeIter iter_next; + + gint ret_val; + + /* set a's interface to be the first interface in the sensors tree */ + if (a_is_first) { + + /* this 'fails' if the tree is empty, but this is already checked with the first loop */ + gtk_tree_model_get_iter_first (GTK_TREE_MODEL(sensors_applet->sensors), &first_iter); + + /* we are only interested in the case, where the two are not equal + * that means the a's interface is not the first interface */ + if ( 0 != sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, first_iter, interface_iter_a)) { + + /* it should be, so it needs to be moved to the first position */ + gtk_tree_store_move_after (GTK_TREE_STORE(sensors_applet->sensors), &interface_iter_a, NULL); + } + + } + + /* check b's interface position + * (1) if it is before a's if. - not possible, bc I have just set a's if. as first + * afterwards every new if. will be set right after (one) a's if. + * (0) if it is the same as a's, noop + * (-1) if it is after a, check if it is right after a, if not move it there */ + ret_val = sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, interface_iter_a, interface_iter_b); + if (-1 == ret_val) { + + /* set iter_next to the iter after a's if. iter, can copy like this */ + iter_next = interface_iter_a; + /* this 'fails' if there is no node after a's if. iter, but we already know, that at least b's if. iter is */ + gtk_tree_model_iter_next (GTK_TREE_MODEL(sensors_applet->sensors), &iter_next); + + /* the node right after a's if. iter is not b's if. iter, so move b's if. iter */ + if (0 != sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, iter_next, interface_iter_b)) { + + gtk_tree_store_move_after (GTK_TREE_STORE(sensors_applet->sensors), &interface_iter_b, &interface_iter_a); + } + } + + + /* at this point the interfaces are sorted, the sensors are next */ + /* set a to be the first sensor in the sensors tree, under the first if. iter */ + if (a_is_first) { + + /* this 'fails' if the tree is empty, but at least a is in it */ + gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &first_iter, &interface_iter_a); + + /* we are only interested in the case, where the two are not equal + * that means the a is not the first sensor */ + if ( 0 != sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, first_iter, sensor_iter_a)) { + + /* it should be, so it needs to be moved to the first position */ + gtk_tree_store_move_after (GTK_TREE_STORE(sensors_applet->sensors), &sensor_iter_a, NULL); + } + + } + + /* check b's position + * if a's if. and b's if is the same + * (1) if it is before a's if. - not possible, bc I have just set a as first + * afterwards every new sensor will be set right after (one) a + * (0) if it is the same as a's, not possible, a and b would be equal + * (-1) if it is after a, check if it is right after a, if not move it there */ + if (0 == ret_val && -1 == sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, sensor_iter_a, sensor_iter_b)) { + + /* set iter_next to the iter after a's iter, can copy like this */ + iter_next = sensor_iter_a; + /* this 'fails' if there is no node after a's iter, but we already know, that at least b's iter is */ + gtk_tree_model_iter_next (GTK_TREE_MODEL(sensors_applet->sensors), &iter_next); + + /* the node right after a's iter is not b's iter, so move b's iter */ + if (0 != sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, iter_next, sensor_iter_b)) { + + gtk_tree_store_move_after (GTK_TREE_STORE(sensors_applet->sensors), &sensor_iter_b, &sensor_iter_a); + } + } + + /* if a's if. and b's if is not the same + * as b comes after a, b must be under a new if. + * and so b must be the first node under that if. */ + /* set b to be the first sensor in the sensors tree, under the b's if. iter */ + if (-1 == ret_val) { + + /* this 'fails' if the tree is empty, but at least b is in it */ + gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &first_iter, &interface_iter_b); + + /* we are only interested in the case, where the two are not equal + * that means the b is not the first sensor */ + if ( 0 != sensors_applet_settings_sort_sensors_iter_compare (sensors_applet, first_iter, sensor_iter_b)) { + + /* it should be, so it needs to be moved to the first position */ + gtk_tree_store_move_after (GTK_TREE_STORE(sensors_applet->sensors), &sensor_iter_b, NULL); + } + + } + + return 1; + + } + + /* hash_b has already been removed from the system */ + if (found_a && !found_b) { + return 2; + } + + /* this is the least likely case + * if hash_a is not found, then the sensors-list starts with a sensor + * that has already been removed from the system */ + if (!found_a) { + return 3; + } + + /* we should never get here */ + return 0; +} + +/* sort sensors based on sensors-list array in gsettings */ +gboolean sensors_applet_settings_sort_sensors (SensorsApplet *sensors_applet) { + + gchar **sensors_list = NULL; + + gchar *hash_a = NULL; + gchar *hash_b = NULL; + + gint ret_val = -1; + /* marks the first iteration */ + gint first_counter = 1; + + /* get sensors-list array from gsettings + * newly allocated, has to be freed fully + * for an empty array a pointer to a NULL pointer will be returned (g_variant_dup_strv ()) */ + sensors_list = g_settings_get_strv (sensors_applet->settings, "sensors-list"); + + /* list is empty (on the first run) */ + if (NULL == *sensors_list) { + /* still need to free the array, even if it is empty */ + g_strfreev (sensors_list); + return FALSE; + } + + gint i; + /* hash lists are equal */ + gboolean hle = TRUE; + /* compare saved sorted list to newly loaded sensors' list */ + for (i = 0; (NULL != sensors_applet->sensors_hash_array[i]) && (NULL != sensors_list[i]); i++) { + + if (g_ascii_strcasecmp(sensors_applet->sensors_hash_array[i], sensors_list[i]) != 0) { + hle = FALSE; + break; + } + } + + /* lists are the same -> nothing to do */ + if (hle) { +#ifdef SORT_DEBUG + syslog(LOG_ERR, "sensor sort: saved list is the same as the new one, returning"); +#endif + + /* still need to free the array */ + g_strfreev (sensors_list); + return TRUE; + } + +#ifdef SORT_DEBUG + sensors_applet_settings_print_sensors_tree (sensors_applet); +#endif + + + for (i = 0; NULL != sensors_list[i]; i++) { + + /* first pass */ + if (i == 0) { + /* make a copy */ + hash_a = g_strdup (sensors_list[i]); + continue; + } + + hash_b = g_strdup (sensors_list[i]); + + /* now that we have two hashes, find the two corresponding sensors and sort them + * if i == 1, we have both a and b set, this is the first time calling this function */ + ret_val = sensors_applet_settings_sort_sensors_sort (sensors_applet, hash_a, hash_b, (i == first_counter)); + + /* hash_b has already been removed from the system + * don't free hash_a, don't reassign hash_b + * as we already know that b is no longer in the system */ + if (2 == ret_val) { + continue; + } + + /* after sorting free hash_a (it should be in place) and reassign hash_b to hash_a */ + g_free (hash_a); + hash_a = hash_b; + + /* hash_a not found + * set hash_b as hash_a and set the first element counter + * (essentially skip the first element in the sensors-list array) */ + if (3 == ret_val) { + first_counter++; + } + } + +#ifdef SORT_DEBUG + sensors_applet_settings_print_sensors_tree (sensors_applet); +#endif + + /* hash_a already freed + * only in the following case do we need to free it */ + if (2 == ret_val) { + g_free (hash_a); + } + g_free (hash_b); + + g_strfreev (sensors_list); + + /* reorder active sensors based on reordered sensors tree */ + sensors_applet_reorder_sensors (sensors_applet); + + return TRUE; +} + +/* save sensor data under a unique hash + * save sensor sort in an array, with above hash */ gboolean sensors_applet_settings_save_sensors (SensorsApplet *sensors_applet) { - /* write everything to GSettings except VISIBLE and ALARM_TIMEOUT_INDEX */ - /* for stepping through GtkTreeStore data structure */ - GtkTreeIter interfaces_iter, sensors_iter; - gboolean not_end_of_interfaces = TRUE, not_end_of_sensors = TRUE; - gchar *applet_path; - - int i; - gchar *current_path, - *current_id, - *current_label, - *current_interface, - *current_low_alarm_command, - *current_high_alarm_command, - *current_graph_color; + + /* write everything to GSettings except VISIBLE and ALARM_TIMEOUT_INDEX + * for stepping through GtkTreeStore data structure */ + GtkTreeIter interfaces_iter; + GtkTreeIter sensors_iter; + gboolean not_end_of_interfaces = TRUE; + gboolean not_end_of_sensors = TRUE; + gchar *applet_path = NULL; + + gchar *current_path = NULL; + gchar *current_id = NULL; + gchar *current_label = NULL; + gchar *current_interface = NULL; + gchar *current_low_alarm_command = NULL; + gchar *current_high_alarm_command = NULL; + gchar *current_graph_color = NULL; gboolean current_enable, current_alarm_enable; gdouble current_low_value, @@ -165,28 +563,19 @@ gboolean sensors_applet_settings_save_sensors (SensorsApplet *sensors_applet) { current_sensor_type, current_icon_type; - // data structure (array) to be able to save sensors list to gsettings + /* data structure (array) to be able to save sensors list to gsettings */ GVariantBuilder builder; g_variant_builder_init (&builder, G_VARIANT_TYPE (GSGVTSA)); applet_path = mate_panel_applet_get_preferences_path (sensors_applet->applet); - /* now step through the GtkTreeStore sensors to find which sensors are enabled */ - for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); + /* now step through the GtkTreeStore sensors to find which sensors are available / loaded */ + for (not_end_of_interfaces = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); not_end_of_interfaces; not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter)) { - gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), - &interfaces_iter, - ID_COLUMN, ¤t_id, - -1); - - g_free(current_id); - /* reset sensors sentinel */ - not_end_of_sensors = TRUE; - - for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); + for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); not_end_of_sensors; not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter)) { @@ -210,17 +599,17 @@ gboolean sensors_applet_settings_save_sensors (SensorsApplet *sensors_applet) { GRAPH_COLOR_COLUMN, ¤t_graph_color, -1); - // GSettings unique id for one sensor data + /* GSettings unique id for one sensor data */ gchar *gsuid = sensors_applet_settings_get_unique_id (current_interface, current_id, current_path); - // save sensor uid to gvariant array + /* save sensor uid to gvariant array */ g_variant_builder_add(&builder, - GSGVTS, // must be related to the G_VARIANT_TYPE in init and gsettings schema - g_strdup(gsuid)); + GSGVTS, /* must be related to the G_VARIANT_TYPE in init and gsettings schema */ + gsuid); - // save sensor data to gsettings individually - // g_strdup_printf doesn't free args! - // applet_path is freed at the end + /* save sensor data to gsettings individually + * g_strdup_printf doesn't free args! + * applet_path is freed at the end */ gchar *path = g_strdup_printf ("%s%s/", applet_path, gsuid); g_free (gsuid); @@ -228,7 +617,7 @@ gboolean sensors_applet_settings_save_sensors (SensorsApplet *sensors_applet) { settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", path); g_free (path); - // wait until g_settings_apply() is called to save all changes at once to gsettings + /* wait until g_settings_apply() is called to save all changes at once to gsettings */ g_settings_delay (settings); g_settings_set_string (settings, PATH, current_path); g_settings_set_string (settings, ID, current_id); @@ -252,15 +641,10 @@ gboolean sensors_applet_settings_save_sensors (SensorsApplet *sensors_applet) { } } - // save the sensor-list array to gsettings - GSettings *settings; - settings = g_settings_new_with_path ("org.mate.sensors-applet", applet_path); - - // builder is freed by g_variant_builder_end() - // the gvariant returned from g_variant_builder_end() is floating, so it is freed by g_settings_set_value() - g_settings_set_value (settings, "sensors-list", g_variant_builder_end (&builder)); - - g_object_unref (settings); + /* save the sensor-list array to gsettings + * builder is freed by g_variant_builder_end() + * the gvariant returned from g_variant_builder_end() is floating, so it is freed by g_settings_set_value() */ + g_settings_set_value (sensors_applet->settings, "sensors-list", g_variant_builder_end (&builder)); g_free (applet_path); diff --git a/sensors-applet/sensors-applet-settings.h b/sensors-applet/sensors-applet-settings.h index e1bcfb6..6bf3f7b 100644 --- a/sensors-applet/sensors-applet-settings.h +++ b/sensors-applet/sensors-applet-settings.h @@ -52,7 +52,8 @@ #define GRAPH_COLOR "graph-color" gchar* sensors_applet_settings_get_unique_id (const gchar *interface, const gchar *id, const gchar *path); -gboolean sensors_applet_conf_setup_sensors (SensorsApplet *sensors_applet); +gboolean sensors_applet_settings_load_sensors (SensorsApplet *sensors_applet); +gboolean sensors_applet_settings_sort_sensors (SensorsApplet *sensors_applet); gboolean sensors_applet_settings_save_sensors (SensorsApplet *sensors_applet); #endif /* SENSORS_APPLET_SETTINGS_H*/ diff --git a/sensors-applet/sensors-applet.c b/sensors-applet/sensors-applet.c index b85d1bf..e67a82d 100644 --- a/sensors-applet/sensors-applet.c +++ b/sensors-applet/sensors-applet.c @@ -51,6 +51,10 @@ #define ROW_SPACING 1 +/* builder for sensor sorting verification */ +static GVariantBuilder gvb_sensors_hash_list; + + /* callbacks for panel menu */ static void prefs_cb(GtkAction *action, gpointer *data) { @@ -962,6 +966,10 @@ gboolean sensors_applet_add_sensor(SensorsApplet *sensors_applet, gchar *gsuid = sensors_applet_settings_get_unique_id (interface, id, path); gchar *settings_path = g_strdup_printf ("%s%s/", applet_path, gsuid); GSettings *settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", settings_path); + + /* add hash to temp sorting list */ + g_variant_builder_add (&gvb_sensors_hash_list, "s", gsuid); + g_free (applet_path); g_free (gsuid); g_free (settings_path); @@ -1255,12 +1263,25 @@ void sensors_applet_init(SensorsApplet *sensors_applet) { /* init gsettings */ sensors_applet->settings = mate_panel_applet_settings_new (sensors_applet->applet, "org.mate.sensors-applet"); - // load sensors from array saved in gsettings - sensors_applet_conf_setup_sensors(sensors_applet); - /* now do any setup needed manually */ + /* set up builder for sorting verification */ + g_variant_builder_init (&gvb_sensors_hash_list, G_VARIANT_TYPE ("as")); + + /* set up / load sensors from the plugins */ sensors_applet_plugins_load_all(sensors_applet); + /* set sorting hash array */ + GVariant *gv_temp = g_variant_builder_end (&gvb_sensors_hash_list); + sensors_applet->sensors_hash_array = g_variant_dup_strv (gv_temp, NULL); + g_variant_unref (gv_temp); + + /* sort sensors based on saved sorting */ + sensors_applet_settings_sort_sensors(sensors_applet); + + /* free hash array */ + g_strfreev (sensors_applet->sensors_hash_array); + + /* should have created sensors tree above, but if have not was because we couldn't find any sensors */ if (NULL == sensors_applet->sensors) { GtkWidget *label; diff --git a/sensors-applet/sensors-applet.h b/sensors-applet/sensors-applet.h index 4f44af1..7b3fb34 100644 --- a/sensors-applet/sensors-applet.h +++ b/sensors-applet/sensors-applet.h @@ -120,6 +120,7 @@ struct _SensorsApplet { gint size; GtkTreeStore *sensors; + gchar **sensors_hash_array; GtkTreeSelection *selection; GHashTable *required_plugins; -- cgit v1.2.1