Commit f7b466e8 authored by Robert Ancell's avatar Robert Ancell

search: Remove global variable that could get leaked

Tracker GSettings were previously stored in a global variable. This
seems to have been done to avoid difficulty passing the settings via
callbacks. Global variables are easy to leak and make mistakes with.

Update the code to have better callback handling so the variable can
be stored inside the object.
parent 90af5b87
Pipeline #95344 passed with stages
in 13 minutes and 16 seconds
......@@ -27,8 +27,6 @@
#define TRACKER_KEY_RECURSIVE_DIRECTORIES "index-recursive-directories"
#define TRACKER_KEY_SINGLE_DIRECTORIES "index-single-directories"
static GSettings *tracker_preferences = NULL;
typedef enum {
PLACE_XDG,
PLACE_BOOKMARKS,
......@@ -36,6 +34,7 @@ typedef enum {
} PlaceType;
typedef struct {
CcSearchLocationsDialog *dialog;
GFile *location;
gchar *display_name;
PlaceType place_type;
......@@ -46,6 +45,8 @@ typedef struct {
struct _CcSearchLocationsDialog {
GtkDialog parent;
GSettings *tracker_preferences;
GtkWidget *places_list;
GtkWidget *bookmarks_list;
GtkWidget *others_list;
......@@ -61,7 +62,9 @@ G_DEFINE_TYPE (CcSearchLocationsDialog, cc_search_locations_dialog, GTK_TYPE_DIA
static void
cc_search_locations_dialog_finalize (GObject *object)
{
g_clear_object (&tracker_preferences);
CcSearchLocationsDialog *self = CC_SEARCH_LOCATIONS_DIALOG (object);
g_clear_object (&self->tracker_preferences);
G_OBJECT_CLASS (cc_search_locations_dialog_parent_class)->finalize (object);
}
......@@ -87,7 +90,7 @@ place_free (Place * p)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Place, place_free)
static GList *
get_bookmarks (void)
get_bookmarks (CcSearchLocationsDialog *self)
{
g_autoptr(GFile) file = NULL;
g_autofree gchar *contents = NULL;
......@@ -123,6 +126,7 @@ get_bookmarks (void)
}
bookmark = g_slice_new0 (Place);
bookmark->dialog = self;
bookmark->location = g_file_new_for_uri (lines[idx]);
if (label != NULL)
......@@ -152,7 +156,7 @@ get_user_special_dir_if_not_home (GUserDirectory idx)
}
static GList *
get_xdg_dirs (void)
get_xdg_dirs (CcSearchLocationsDialog *self)
{
GList *xdg_dirs = NULL;
gint idx;
......@@ -171,6 +175,7 @@ get_xdg_dirs (void)
continue;
xdg_dir = g_slice_new0 (Place);
xdg_dir->dialog = self;
xdg_dir->location = g_file_new_for_path (path);
xdg_dir->display_name = g_file_get_basename (xdg_dir->location);
xdg_dir->place_type = PLACE_XDG;
......@@ -240,7 +245,7 @@ path_from_tracker_dir (const gchar *value)
}
static GList *
get_tracker_locations (void)
get_tracker_locations (CcSearchLocationsDialog *self)
{
g_auto(GStrv) locations = NULL;
GList *list;
......@@ -248,7 +253,7 @@ get_tracker_locations (void)
Place *location;
const gchar *path;
locations = g_settings_get_strv (tracker_preferences, TRACKER_KEY_RECURSIVE_DIRECTORIES);
locations = g_settings_get_strv (self->tracker_preferences, TRACKER_KEY_RECURSIVE_DIRECTORIES);
list = NULL;
for (idx = 0; locations[idx] != NULL; idx++)
......@@ -267,7 +272,7 @@ get_tracker_locations (void)
}
static GList *
get_places_list (void)
get_places_list (CcSearchLocationsDialog *self)
{
g_autoptr(GList) xdg_list = NULL;
g_autoptr(GList) tracker_list = NULL;
......@@ -281,13 +286,14 @@ get_places_list (void)
/* add home */
place = g_slice_new0 (Place);
place->dialog = self;
place->location = g_file_new_for_path (g_get_home_dir ());
place->place_type = PLACE_XDG;
place->display_name = g_strdup (_("Home"));
g_hash_table_insert (places, place->location, place);
/* first, load the XDG dirs */
xdg_list = get_xdg_dirs ();
xdg_list = get_xdg_dirs (self);
for (l = xdg_list; l != NULL; l = l->next)
{
place = l->data;
......@@ -295,7 +301,7 @@ get_places_list (void)
}
/* then, insert all the tracker locations that are not XDG dirs */
tracker_list = get_tracker_locations ();
tracker_list = get_tracker_locations (self);
for (l = tracker_list; l != NULL; l = l->next)
{
g_autoptr(Place) p = l->data;
......@@ -308,7 +314,7 @@ get_places_list (void)
}
/* finally, load bookmarks, and possibly update attributes */
bookmark_list = get_bookmarks ();
bookmark_list = get_bookmarks (self);
for (l = bookmark_list; l != NULL; l = l->next)
{
g_autoptr(Place) p = l->data;
......@@ -362,7 +368,8 @@ switch_tracker_get_mapping (GValue *value,
}
static GPtrArray *
place_get_new_settings_values (Place *place,
place_get_new_settings_values (CcSearchLocationsDialog *self,
Place *place,
gboolean remove)
{
g_auto(GStrv) values = NULL;
......@@ -373,7 +380,7 @@ place_get_new_settings_values (Place *place,
gint idx;
new_values = g_ptr_array_new_with_free_func (g_free);
values = g_settings_get_strv (tracker_preferences, place->settings_key);
values = g_settings_get_strv (self->tracker_preferences, place->settings_key);
path = g_file_get_path (place->location);
tracker_dir = path_to_tracker_dir (path);
......@@ -410,7 +417,7 @@ switch_tracker_set_mapping (const GValue *value,
gboolean remove;
remove = !g_value_get_boolean (value);
new_values = place_get_new_settings_values (place, remove);
new_values = place_get_new_settings_values (place->dialog, place, remove);
return g_variant_new_strv ((const gchar **) new_values->pdata, -1);
}
......@@ -449,7 +456,7 @@ place_query_info_ready (GObject *source,
gtk_widget_show (w);
gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 0);
g_settings_bind_with_mapping (tracker_preferences, place->settings_key,
g_settings_bind_with_mapping (place->dialog->tracker_preferences, place->settings_key,
w, "active",
G_SETTINGS_BIND_DEFAULT,
switch_tracker_get_mapping,
......@@ -458,16 +465,15 @@ place_query_info_ready (GObject *source,
}
static void
remove_button_clicked (GtkWidget *widget,
gpointer user_data)
remove_button_clicked (CcSearchLocationsDialog *self,
GtkWidget *button)
{
GtkWidget *row = user_data;
g_autoptr(GPtrArray) new_values = NULL;
Place *place;
place = g_object_get_data (G_OBJECT (row), "place");
new_values = place_get_new_settings_values (place, TRUE);
g_settings_set_strv (tracker_preferences, place->settings_key, (const gchar **) new_values->pdata);
place = g_object_get_data (G_OBJECT (button), "place");
new_values = place_get_new_settings_values (self, place, TRUE);
g_settings_set_strv (self->tracker_preferences, place->settings_key, (const gchar **) new_values->pdata);
}
static gint
......@@ -505,7 +511,7 @@ place_compare_func (gconstpointer a,
}
static GtkWidget *
create_row_for_place (Place *place)
create_row_for_place (CcSearchLocationsDialog *self, Place *place)
{
GtkWidget *child, *row, *remove_button;
......@@ -523,11 +529,12 @@ create_row_for_place (Place *place)
{
remove_button = gtk_button_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_MENU);
gtk_widget_show (remove_button);
g_object_set_data (G_OBJECT (remove_button), "place", place);
gtk_style_context_add_class (gtk_widget_get_style_context (remove_button), "flat");
gtk_box_pack_end (GTK_BOX (child), remove_button, FALSE, FALSE, 2);
g_signal_connect (remove_button, "clicked",
G_CALLBACK (remove_button_clicked), row);
g_signal_connect_swapped (remove_button, "clicked",
G_CALLBACK (remove_button_clicked), self);
}
place->cancellable = g_cancellable_new ();
......@@ -546,11 +553,11 @@ populate_list_boxes (CcSearchLocationsDialog *self)
Place *place;
GtkWidget *row;
places = get_places_list ();
places = get_places_list (self);
for (l = places; l != NULL; l = l->next)
{
place = l->data;
row = create_row_for_place (place);
row = create_row_for_place (self, place);
switch (place->place_type)
{
......@@ -570,9 +577,9 @@ populate_list_boxes (CcSearchLocationsDialog *self)
}
static void
add_file_chooser_response (GtkDialog *widget,
add_file_chooser_response (CcSearchLocationsDialog *self,
GtkResponseType response,
gpointer user_data)
GtkWidget *widget)
{
g_autoptr(Place) place = NULL;
g_autoptr(GPtrArray) new_values = NULL;
......@@ -584,32 +591,31 @@ add_file_chooser_response (GtkDialog *widget,
}
place = g_slice_new0 (Place);
place->dialog = self;
place->location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (widget));
place->settings_key = TRACKER_KEY_RECURSIVE_DIRECTORIES;
place->display_name = g_file_get_basename (place->location);
new_values = place_get_new_settings_values (place, FALSE);
g_settings_set_strv (tracker_preferences, place->settings_key, (const gchar **) new_values->pdata);
new_values = place_get_new_settings_values (self, place, FALSE);
g_settings_set_strv (self->tracker_preferences, place->settings_key, (const gchar **) new_values->pdata);
gtk_widget_destroy (GTK_WIDGET (widget));
}
static void
add_button_clicked (GtkWidget *widget,
gpointer user_data)
add_button_clicked (CcSearchLocationsDialog *self)
{
GtkWidget *list_box = user_data;
GtkWidget *file_chooser;
file_chooser = gtk_file_chooser_dialog_new (_("Select Location"),
GTK_WINDOW (gtk_widget_get_toplevel (widget)),
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_OK"), GTK_RESPONSE_OK,
NULL);
gtk_window_set_modal (GTK_WINDOW (file_chooser), TRUE);
g_signal_connect (file_chooser, "response",
G_CALLBACK (add_file_chooser_response), list_box);
g_signal_connect_swapped (file_chooser, "response",
G_CALLBACK (add_file_chooser_response), self);
gtk_widget_show (file_chooser);
}
......@@ -623,14 +629,14 @@ other_places_refresh (CcSearchLocationsDialog *self)
gtk_container_foreach (GTK_CONTAINER (self->others_list), (GtkCallback) gtk_widget_destroy, NULL);
places = get_places_list ();
places = get_places_list (self);
for (l = places; l != NULL; l = l->next)
{
place = l->data;
if (place->place_type != PLACE_OTHER)
continue;
row = create_row_for_place (place);
row = create_row_for_place (self, place);
gtk_container_add (GTK_CONTAINER (self->others_list), row);
}
}
......@@ -644,7 +650,7 @@ cc_search_locations_dialog_new (CcSearchPanel *panel)
"use-header-bar", TRUE,
NULL);
tracker_preferences = g_settings_new (TRACKER_SCHEMA);
self->tracker_preferences = g_settings_new (TRACKER_SCHEMA);
populate_list_boxes (self);
gtk_list_box_set_sort_func (GTK_LIST_BOX (self->others_list),
......@@ -652,7 +658,7 @@ cc_search_locations_dialog_new (CcSearchPanel *panel)
gtk_list_box_set_header_func (GTK_LIST_BOX (self->others_list), cc_list_box_update_header_func, NULL, NULL);
g_signal_connect_swapped (tracker_preferences, "changed::" TRACKER_KEY_RECURSIVE_DIRECTORIES,
g_signal_connect_swapped (self->tracker_preferences, "changed::" TRACKER_KEY_RECURSIVE_DIRECTORIES,
G_CALLBACK (other_places_refresh), self);
gtk_window_set_transient_for (GTK_WINDOW (self),
......
......@@ -99,7 +99,7 @@
<property name="visible">True</property>
<property name="halign">center</property>
<property name="margin">5</property>
<signal name="clicked" handler="add_button_clicked" swapped="no"/>
<signal name="clicked" handler="add_button_clicked" object="CcSearchLocationsDialog" swapped="yes"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment