From 1367a8c083c2b3fa0db848fe6ae0cba3b9b7c25f Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 28 Mar 2018 16:39:13 -0300 Subject: [PATCH 01/14] window: Profile panel creation times --- shell/cc-window.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/shell/cc-window.c b/shell/cc-window.c index f7593dc55a..09f5721b11 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -20,6 +20,8 @@ * Author: Thomas Wood */ +#define G_LOG_DOMAIN "cc-window" + #include #include "cc-window.h" @@ -31,6 +33,7 @@ #include #include #include +#include #include "cc-panel.h" #include "cc-shell.h" @@ -117,14 +120,21 @@ activate_panel (CcWindow *self, const gchar *name, GIcon *gicon) { + g_autoptr (GTimer) timer = NULL; GtkWidget *box, *title_widget; const gchar *icon_name; + gdouble ellapsed_time; if (!id) return FALSE; + timer = g_timer_new (); + g_settings_set_string (self->settings, "last-panel", id); + /* Begin the profile */ + g_timer_start (timer); + self->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, parameters)); cc_shell_set_active_panel (CC_SHELL (self), CC_PANEL (self->current_panel)); gtk_widget_show (self->current_panel); @@ -156,6 +166,13 @@ activate_panel (CcWindow *self, self->current_panel_box = box; + /* Finish profiling */ + g_timer_stop (timer); + + ellapsed_time = g_timer_elapsed (timer, NULL); + + g_debug ("Time to open panel '%s': %lfs", name, ellapsed_time); + return TRUE; } @@ -779,4 +796,4 @@ cc_window_set_search_item (CcWindow *center, gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (center->search_bar), TRUE); gtk_entry_set_text (GTK_ENTRY (center->search_entry), search); gtk_editable_set_position (GTK_EDITABLE (center->search_entry), -1); -} \ No newline at end of file +} -- GitLab From 083e7bdae65e41ecc6f41f112af5fab7505295c4 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 17:48:08 -0300 Subject: [PATCH 02/14] object-storage: Introduce CcObjectStorage CcObjectStorage is a cache for GObjects. It is meant to store objects that are too expensive to be often created, such as NMClient, GoaClient or D-Bus proxies. CcObjectStorage has a very strict usage pattern. It is a programming error to add an object that is already stored, and so it is to retrieve an object that was not stored. Stored objects are meant to be kept alive during the whole lifetime of GNOME Settings, and CcObjectStorage takes a reference on every stored object to achieve that. If objects are destroyed while they are cached, it means we have a reference mismanagement somewhere. In this sense, CcObjectStorage will act Sam Sheepdog taking care of sneaky wolves trying to steal their sheep-references. Next patches will make various panels and objects around GNOME Settings adopt this new API, and make sure they always disconnect when destroyed. --- shell/cc-application.c | 13 ++ shell/cc-object-storage.c | 438 ++++++++++++++++++++++++++++++++++++++ shell/cc-object-storage.h | 65 ++++++ shell/meson.build | 1 + 4 files changed, 517 insertions(+) create mode 100644 shell/cc-object-storage.c create mode 100644 shell/cc-object-storage.h diff --git a/shell/cc-application.c b/shell/cc-application.c index 8beb617144..144cbeeb67 100644 --- a/shell/cc-application.c +++ b/shell/cc-application.c @@ -26,6 +26,7 @@ #include #include "cc-application.h" +#include "cc-object-storage.h" #include "cc-panel-loader.h" #include "cc-shell-log.h" #include "cc-window.h" @@ -264,6 +265,15 @@ cc_application_startup (GApplication *application) self->window = cc_window_new (GTK_APPLICATION (application)); } +static void +cc_application_finalize (GObject *object) +{ + /* Destroy the object storage cache when finalizing */ + cc_object_storage_destroy (); + + G_OBJECT_CLASS (cc_application_parent_class)->finalize (object); +} + static GObject * cc_application_constructor (GType type, guint n_construct_params, @@ -289,6 +299,7 @@ cc_application_class_init (CcApplicationClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GApplicationClass *application_class = G_APPLICATION_CLASS (klass); + object_class->finalize = cc_application_finalize; object_class->constructor = cc_application_constructor; application_class->activate = cc_application_activate; application_class->startup = cc_application_startup; @@ -299,6 +310,8 @@ cc_application_class_init (CcApplicationClass *klass) static void cc_application_init (CcApplication *self) { + cc_object_storage_initialize (); + g_application_add_main_option_entries (G_APPLICATION (self), all_options); } diff --git a/shell/cc-object-storage.c b/shell/cc-object-storage.c new file mode 100644 index 0000000000..0e708dc3b1 --- /dev/null +++ b/shell/cc-object-storage.c @@ -0,0 +1,438 @@ +/* cc-object-storage.h + * + * Copyright 2018 Georges Basile Stavracas Neto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define G_LOG_DOMAIN "cc-object-storage" + +#include "cc-object-storage.h" + +struct _CcObjectStorage +{ + GObject parent_instance; + + GHashTable *id_to_object; +}; + +G_DEFINE_TYPE (CcObjectStorage, cc_object_storage, G_TYPE_OBJECT) + +/* Singleton instance */ +CcObjectStorage *_instance = NULL; + +/* GTask API to create a new D-Bus proxy */ +typedef struct +{ + GBusType bus_type; + GDBusProxyFlags flags; + gchar *name; + gchar *path; + gchar *interface; + gboolean cached; +} TaskData; + +static TaskData* +task_data_new (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface) +{ + TaskData *data = g_slice_new (TaskData); + data->bus_type = bus_type; + data->flags =flags; + data->name = g_strdup (name); + data->path = g_strdup (path); + data->interface = g_strdup (interface); + data->cached = FALSE; + + return data; +} + +static void +task_data_free (TaskData *data) +{ + g_free (data->name); + g_free (data->path); + g_free (data->interface); + g_slice_free (TaskData, data); +} + +static void +create_dbus_proxy_in_thread_cb (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) local_error = NULL; + TaskData *data = task_data; + + proxy = g_dbus_proxy_new_for_bus_sync (data->bus_type, + data->flags, + NULL, + data->name, + data->path, + data->interface, + cancellable, + &local_error); + + if (local_error) + { + g_task_return_error (task, local_error); + return; + } + + g_task_return_pointer (task, g_object_ref (g_steal_pointer (&proxy)), g_object_unref); +} + +static void +cc_object_storage_finalize (GObject *object) +{ + CcObjectStorage *self = (CcObjectStorage *)object; + + g_debug ("Destroying cached objects"); + + g_clear_pointer (&self->id_to_object, g_hash_table_destroy); + + G_OBJECT_CLASS (cc_object_storage_parent_class)->finalize (object); +} + +static void +cc_object_storage_class_init (CcObjectStorageClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = cc_object_storage_finalize; +} + +static void +cc_object_storage_init (CcObjectStorage *self) +{ + self->id_to_object = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +} + +/** + * cc_object_storage_has_object: + * @key: the unique string identifier of the object + * + * Checks whether there is an object associated with @key. + * + * Returns: %TRUE if the object is stored, %FALSE otherwise. + */ +gboolean +cc_object_storage_has_object (const gchar *key) +{ + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (key != NULL); + + return g_hash_table_contains (_instance->id_to_object, key); +} + +/** + * cc_object_storage_add_object: + * @key: the unique string identifier of the object + * @object: (type GObject): the object to be stored + * + * Adds @object to the object storage. It is a programming error to try to + * add an object that was already added. + * + * @object must be a GObject. + * + * Always check if the object is stored with cc_object_storage_has_object() + * before calling this function. + */ +void +cc_object_storage_add_object (const gchar *key, + gpointer object) +{ + /* Trying to add an object that was already added is a hard error. Each + * object must be added once, and only once, over the entire lifetime + * of the application. + */ + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (key != NULL); + g_assert (G_IS_OBJECT (object)); + g_assert (!g_hash_table_contains (_instance->id_to_object, key)); + + g_debug ("Adding object %s (%s → %p) to the storage", + g_type_name (G_OBJECT_TYPE (object)), + key, + object); + + g_hash_table_insert (_instance->id_to_object, g_strdup (key), g_object_ref (object)); +} + +/** + * cc_object_storage_get_object: + * @key: the unique string identifier of the object + * + * Retrieves the object associated with @key. It is a programming error to + * try to retrieve an object before adding it. + * + * Always check if the object is stored with cc_object_storage_has_object() + * before calling this function. + * + * Returns: (transfer full): the GObject associated with @key. + */ +gpointer +cc_object_storage_get_object (const gchar *key) +{ + /* Trying to peek an object that was not yet added is a hard error. Users + * of this API need to first check if the object is available with + * cc_object_storage_has_object(). + */ + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (key != NULL); + g_assert (g_hash_table_contains (_instance->id_to_object, key)); + + return g_object_ref (g_hash_table_lookup (_instance->id_to_object, key)); +} + +/** + * cc_object_storage_create_dbus_proxy_sync: + * @name: the D-Bus name + * @flags: the D-Bus proxy flags + * @path: the D-Bus object path + * @interface: the D-Bus interface name + * @cancellable: (nullable): #GCancellable to cancel the operation + * @error: (nullable): return location for a #GError + * + * Synchronously create a #GDBusProxy with @name, @path and @interface, + * stores it in the cache, and returns the newly created proxy. + * + * If a proxy with that signature is already created, it will be used + * instead of creating a new one. + * + * Returns: (transfer full)(nullable): the new #GDBusProxy. + */ +gpointer +cc_object_storage_create_dbus_proxy_sync (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) local_error = NULL; + g_autofree gchar *key = NULL; + + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (name && *name); + g_assert (path && *path); + g_assert (interface && *interface); + g_assert (!error || !*error); + + key = g_strdup_printf ("CcObjectStorage::dbus-proxy(%s,%s,%s)", name, path, interface); + + /* Check if a DBus proxy with that signature is already available; if it is, + * return that instead of a new one. + */ + if (g_hash_table_contains (_instance->id_to_object, key)) + return cc_object_storage_get_object (key); + + proxy = g_dbus_proxy_new_for_bus_sync (bus_type, + flags, + NULL, + name, + path, + interface, + cancellable, + &local_error); + + if (local_error) + { + g_propagate_error (error, local_error); + return NULL; + } + + /* Store the newly created D-Bus proxy */ + cc_object_storage_add_object (key, proxy); + + return g_steal_pointer (&proxy); +} + + +/** + * cc_object_storage_create_dbus_proxy: + * @name: the D-Bus name + * @flags: the D-Bus proxy flags + * @path: the D-Bus object path + * @interface: the D-Bus interface name + * @cancellable: (nullable): #GCancellable to cancel the operation + * @callback: callback for when the async operation is finished + * @user_data: user data for @callback + * + * Asynchronously create a #GDBusProxy with @name, @path and @interface. + * + * If a proxy with that signature is already created, it will be used instead of + * creating a new one. + * + * It is a programming error to create the an identical proxy while asynchronously + * creating one. Not cancelling this operation will result in an assertion failure + * when calling cc_object_storage_create_dbus_proxy_finish(). + */ +void +cc_object_storage_create_dbus_proxy (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autoptr(GTask) task = NULL; + g_autofree gchar *key = NULL; + TaskData *data = NULL; + + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (name && *name); + g_assert (path && *path); + g_assert (interface && *interface); + g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); + + data = task_data_new (bus_type, flags, name, path, interface); + + task = g_task_new (_instance, cancellable, callback, user_data); + g_task_set_source_tag (task, cc_object_storage_create_dbus_proxy); + g_task_set_task_data (task, data, (GDestroyNotify) task_data_free); + + /* Check if the D-Bus proxy is already created */ + key = g_strdup_printf ("CcObjectStorage::dbus-proxy(%s,%s,%s)", name, path, interface); + + if (g_hash_table_contains (_instance->id_to_object, key)) + { + /* Mark this GTask as already cached, so we can call the right assertions + * on the callback + * */ + data->cached = TRUE; + + g_debug ("Found in cache the D-Bus proxy %s", key); + + g_task_return_pointer (task, cc_object_storage_get_object (key), g_object_unref); + return; + } + + g_task_run_in_thread (task, create_dbus_proxy_in_thread_cb); +} + +/** + * cc_object_storage_create_dbus_proxy_finish: + * @result: + * @error: (nullable): return location for a #GError + * + * Finishes a D-Bus proxy creation started by cc_object_storage_create_dbus_proxy(). + * + * Synchronously create a #GDBusProxy with @name, @path and @interface, + * stores it in the cache, and returns the newly created proxy. + * + * If a proxy with that signature is already created, it will be used + * instead of creating a new one. + * + * Returns: (transfer full)(nullable): the new #GDBusProxy. + */ +gpointer +cc_object_storage_create_dbus_proxy_finish (GAsyncResult *result, + GError **error) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) local_error = NULL; + g_autofree gchar *key = NULL; + TaskData *task_data; + GTask *task; + + task = G_TASK (result); + + g_assert (task && G_TASK (result)); + g_assert (!error || !*error); + + task_data = g_task_get_task_data (task); + + key = g_strdup_printf ("CcObjectStorage::dbus-proxy(%s,%s,%s)", + task_data->name, + task_data->path, + task_data->interface); + + /* Either we have the object stored right when trying to create it - in which case, + * task_data->cached == TRUE and cc_object_storage_has_object (key) == TRUE - or we + * didn't have a cached proxy before, and we shouldn't have it now. + * + * This is to force consumers of this code to *never* try to create the same D-Bus + * proxy asynchronously multiple times. Trying to do so is considered a programming + * error. + */ + g_assert (task_data != NULL); + g_assert (task_data->cached == cc_object_storage_has_object (key)); + + /* Retrieve the newly created proxy */ + proxy = g_task_propagate_pointer (task, &local_error); + + /* If the proxy is not cached, do the normal caching routine */ + if (local_error) + { + g_propagate_error (error, local_error); + return NULL; + } + + /* If the proxy is already cached, destroy the newly created and used the cached proxy + * instead. + */ + if (cc_object_storage_has_object (key)) + return cc_object_storage_get_object (key); + + /* Store the newly created D-Bus proxy */ + cc_object_storage_add_object (key, proxy); + + return g_steal_pointer (&proxy); +} + +/** + * cc_object_storage_init: + * + * Initializes the single CcObjectStorage. This must be called only once, + * and before every other method of this object. + */ +void +cc_object_storage_initialize (void) +{ + g_assert (_instance == NULL); + + if (g_once_init_enter (&_instance)) + { + CcObjectStorage *instance = g_object_new (CC_TYPE_OBJECT_STORAGE, NULL); + + g_debug ("Initializing object storage"); + + g_once_init_leave (&_instance, instance); + } +} + +/** + * cc_object_storage_destroy: + * + * Destroys the instance of #CcObjectStorage. This must be called only + * once during the application lifetime. It is a programming error to + * call this function multiple times + */ +void +cc_object_storage_destroy (void) +{ + g_assert (_instance != NULL); + + g_clear_object (&_instance); +} diff --git a/shell/cc-object-storage.h b/shell/cc-object-storage.h new file mode 100644 index 0000000000..efea0e294e --- /dev/null +++ b/shell/cc-object-storage.h @@ -0,0 +1,65 @@ +/* cc-object-storage.h + * + * Copyright 2018 Georges Basile Stavracas Neto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +/* Default storage keys */ +#define CC_OBJECT_NMCLIENT "CcObjectStorage::nm-client" + + +#define CC_TYPE_OBJECT_STORAGE (cc_object_storage_get_type()) + +G_DECLARE_FINAL_TYPE (CcObjectStorage, cc_object_storage, CC, OBJECT_STORAGE, GObject) + +gboolean cc_object_storage_has_object (const gchar *key); + +void cc_object_storage_add_object (const gchar *key, + gpointer object); + +gpointer cc_object_storage_get_object (const gchar *key); + +gpointer cc_object_storage_create_dbus_proxy_sync (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GError **error); + +void cc_object_storage_create_dbus_proxy (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gpointer cc_object_storage_create_dbus_proxy_finish (GAsyncResult *result, + GError **error); + +void cc_object_storage_initialize (void); + +void cc_object_storage_destroy (void); + +G_END_DECLS diff --git a/shell/meson.build b/shell/meson.build index d9364521b6..0946ada744 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -46,6 +46,7 @@ common_sources = files( 'cc-application.c', 'cc-editable-entry.c', 'cc-hostname-entry.c', + 'cc-object-storage.c', 'cc-panel-loader.c', 'cc-panel.c', 'cc-shell-category-view.c', -- GitLab From d6535f82f03894b15d13bbaf6b2a0a027e7209f8 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 17:59:12 -0300 Subject: [PATCH 03/14] bluetooth: Cache the D-Bus proxy --- panels/bluetooth/cc-bluetooth-panel.c | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/panels/bluetooth/cc-bluetooth-panel.c b/panels/bluetooth/cc-bluetooth-panel.c index 36c58bf4d9..5a60d70c8e 100644 --- a/panels/bluetooth/cc-bluetooth-panel.c +++ b/panels/bluetooth/cc-bluetooth-panel.c @@ -24,6 +24,7 @@ #include #include +#include #include #include "cc-bluetooth-panel.h" @@ -310,20 +311,18 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self) self->cancellable = g_cancellable_new (); /* RFKill */ - self->rfkill = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.gnome.SettingsDaemon.Rfkill", - NULL, NULL); - self->properties = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.freedesktop.DBus.Properties", - NULL, NULL); + self->rfkill = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + NULL, NULL); + self->properties = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.freedesktop.DBus.Properties", + NULL, NULL); self->stack = gtk_stack_new (); gtk_stack_set_homogeneous (GTK_STACK (self->stack), TRUE); @@ -343,10 +342,10 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self) gtk_container_add (GTK_CONTAINER (self), self->stack); airplane_mode_changed (NULL, NULL, NULL, self); - g_signal_connect (self->rfkill, "g-properties-changed", - G_CALLBACK (airplane_mode_changed), self); - g_signal_connect_swapped (G_OBJECT (self->widget), "adapter-status-changed", - G_CALLBACK (cc_bluetooth_panel_update_power), self); + g_signal_connect_object (self->rfkill, "g-properties-changed", + G_CALLBACK (airplane_mode_changed), self, 0); + g_signal_connect_object (G_OBJECT (self->widget), "adapter-status-changed", + G_CALLBACK (cc_bluetooth_panel_update_power), self, G_CONNECT_SWAPPED); g_signal_connect (G_OBJECT (WID ("switch_bluetooth")), "notify::active", G_CALLBACK (power_callback), self); -- GitLab From 8e56ea35f38898deb3b5858211c64ba2ce0e0e93 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 17:59:41 -0300 Subject: [PATCH 04/14] color: Cache D-Bus proxies --- panels/color/cc-color-calibrate.c | 48 +++++++++++++++---------------- panels/color/cc-color-panel.c | 1 - 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/panels/color/cc-color-calibrate.c b/panels/color/cc-color-calibrate.c index d21ad058fb..9357eee72d 100644 --- a/panels/color/cc-color-calibrate.c +++ b/panels/color/cc-color-calibrate.c @@ -28,6 +28,8 @@ #include #include +#include "shell/cc-object-storage.h" + #define GNOME_DESKTOP_USE_UNSTABLE_API #include @@ -884,14 +886,13 @@ cc_color_calibrate_setup (CcColorCalibrate *calibrate, g_return_val_if_fail (calibrate->priv->device_kind != CD_SENSOR_CAP_UNKNOWN, FALSE); /* use logind to disable system state idle */ - priv->proxy_inhibit = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - NULL, - error); + priv->proxy_inhibit = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + NULL, + error); if (priv->proxy_inhibit == NULL) { ret = FALSE; @@ -899,27 +900,26 @@ cc_color_calibrate_setup (CcColorCalibrate *calibrate, } /* start the calibration session daemon */ - priv->proxy_helper = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - CD_SESSION_DBUS_SERVICE, - CD_SESSION_DBUS_PATH, - CD_SESSION_DBUS_INTERFACE_DISPLAY, - NULL, - error); + priv->proxy_helper = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + CD_SESSION_DBUS_SERVICE, + CD_SESSION_DBUS_PATH, + CD_SESSION_DBUS_INTERFACE_DISPLAY, + NULL, + error); if (priv->proxy_helper == NULL) { ret = FALSE; goto out; } - g_signal_connect (priv->proxy_helper, - "g-properties-changed", - G_CALLBACK (cc_color_calibrate_property_changed_cb), - calibrate); - g_signal_connect (priv->proxy_helper, - "g-signal", - G_CALLBACK (cc_color_calibrate_signal_cb), - calibrate); + g_signal_connect_object (priv->proxy_helper, + "g-properties-changed", + G_CALLBACK (cc_color_calibrate_property_changed_cb), + calibrate, 0); + g_signal_connect_object (priv->proxy_helper, + "g-signal", + G_CALLBACK (cc_color_calibrate_signal_cb), + calibrate, 0); out: return ret; } diff --git a/panels/color/cc-color-panel.c b/panels/color/cc-color-panel.c index d901b623ea..e7957debae 100644 --- a/panels/color/cc-color-panel.c +++ b/panels/color/cc-color-panel.c @@ -49,7 +49,6 @@ struct _CcColorPanelPrivate GPtrArray *devices; GPtrArray *sensors; GCancellable *cancellable; - GDBusProxy *proxy; GSettings *settings; GSettings *settings_colord; GtkBuilder *builder; -- GitLab From cbf0dc99daf59af5111bc449ecaec64d0c0e204b Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:00:11 -0300 Subject: [PATCH 05/14] display: Cache the D-Bus proxy --- panels/display/cc-display-panel.c | 24 +++++++------- panels/display/cc-night-light-dialog.c | 46 +++++++++++++------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c index 13f5332e9f..550376776a 100644 --- a/panels/display/cc-display-panel.c +++ b/panels/display/cc-display-panel.c @@ -29,6 +29,7 @@ #include #include +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include @@ -3117,7 +3118,7 @@ shell_proxy_ready (GObject *source, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (!proxy) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -3336,17 +3337,16 @@ cc_display_panel_init (CcDisplayPanel *self) g_signal_connect (self, "map", G_CALLBACK (mapped_cb), NULL); self->priv->shell_cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - "org.gnome.Shell", - "/org/gnome/Shell", - "org.gnome.Shell", - self->priv->shell_cancellable, - (GAsyncReadyCallback) shell_proxy_ready, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "org.gnome.Shell", + "/org/gnome/Shell", + "org.gnome.Shell", + self->priv->shell_cancellable, + (GAsyncReadyCallback) shell_proxy_ready, + self); g_bus_get (G_BUS_TYPE_SESSION, self->priv->shell_cancellable, diff --git a/panels/display/cc-night-light-dialog.c b/panels/display/cc-night-light-dialog.c index a2bbc683e1..1d03ba3934 100644 --- a/panels/display/cc-night-light-dialog.c +++ b/panels/display/cc-night-light-dialog.c @@ -27,6 +27,8 @@ #include "cc-night-light-dialog.h" #include "cc-night-light-widget.h" +#include "shell/cc-object-storage.h" + struct _CcNightLightDialog { GObject parent; GtkBuilder *builder; @@ -385,14 +387,14 @@ dialog_got_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da { CcNightLightDialog *self = (CcNightLightDialog *) user_data; g_autoptr(GError) error = NULL; - self->proxy_color = g_dbus_proxy_new_for_bus_finish (res, &error); + self->proxy_color = cc_object_storage_create_dbus_proxy_finish (res, &error); if (self->proxy_color == NULL) { g_warning ("failed to connect to g-s-d: %s", error->message); return; } - g_signal_connect (self->proxy_color, "g-properties-changed", - G_CALLBACK (dialog_color_properties_changed_cb), self); + g_signal_connect_object (self->proxy_color, "g-properties-changed", + G_CALLBACK (dialog_color_properties_changed_cb), self, 0); dialog_update_state (self); self->timer_id = g_timeout_add_seconds (10, dialog_tick_cb, self); } @@ -402,7 +404,7 @@ dialog_got_proxy_props_cb (GObject *source_object, GAsyncResult *res, gpointer u { CcNightLightDialog *self = (CcNightLightDialog *) user_data; g_autoptr(GError) error = NULL; - self->proxy_color_props = g_dbus_proxy_new_for_bus_finish (res, &error); + self->proxy_color_props = cc_object_storage_create_dbus_proxy_finish (res, &error); if (self->proxy_color_props == NULL) { g_warning ("failed to connect to g-s-d: %s", error->message); @@ -669,25 +671,23 @@ cc_night_light_dialog_init (CcNightLightDialog *self) gtk_box_pack_start (box, self->night_light_widget, FALSE, FALSE, 0); gtk_widget_show (self->night_light_widget); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Color", - "/org/gnome/SettingsDaemon/Color", - "org.gnome.SettingsDaemon.Color", - self->cancellable, - dialog_got_proxy_cb, - self); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Color", - "/org/gnome/SettingsDaemon/Color", - "org.freedesktop.DBus.Properties", - self->cancellable, - dialog_got_proxy_props_cb, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Color", + "/org/gnome/SettingsDaemon/Color", + "org.gnome.SettingsDaemon.Color", + self->cancellable, + dialog_got_proxy_cb, + self); + + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Color", + "/org/gnome/SettingsDaemon/Color", + "org.freedesktop.DBus.Properties", + self->cancellable, + dialog_got_proxy_props_cb, + self); /* clock settings_display */ self->settings_clock = g_settings_new (CLOCK_SCHEMA); -- GitLab From 250eb01931e5ebb6196c2ee57b3cf12a0dfe9b4b Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:00:43 -0300 Subject: [PATCH 06/14] network: Cache D-Bus proxies and objects --- panels/network/cc-network-panel.c | 32 ++++++++++------ panels/network/cc-wifi-panel.c | 63 ++++++++++++++++++------------- 2 files changed, 58 insertions(+), 37 deletions(-) diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c index 51ea823f78..405b538cf5 100644 --- a/panels/network/cc-network-panel.c +++ b/panels/network/cc-network-panel.c @@ -23,6 +23,8 @@ #include #include +#include "shell/cc-object-storage.h" + #include "cc-network-panel.h" #include "cc-network-resources.h" @@ -876,16 +878,24 @@ cc_network_panel_init (CcNetworkPanel *panel) /* add the virtual proxy device */ panel_add_proxy_device (panel); + /* Create and store a NMClient instance if it doesn't exist yet */ + if (!cc_object_storage_has_object (CC_OBJECT_NMCLIENT)) { + NMClient *client = nm_client_new (NULL, NULL); + cc_object_storage_add_object (CC_OBJECT_NMCLIENT, client); + g_object_unref (client); + } + /* use NetworkManager client */ - panel->client = nm_client_new (NULL, NULL); - g_signal_connect (panel->client, "notify::nm-running" , - G_CALLBACK (manager_running), panel); - g_signal_connect (panel->client, "notify::active-connections", - G_CALLBACK (active_connections_changed), panel); - g_signal_connect (panel->client, "device-added", - G_CALLBACK (device_added_cb), panel); - g_signal_connect (panel->client, "device-removed", - G_CALLBACK (device_removed_cb), panel); + panel->client = cc_object_storage_get_object (CC_OBJECT_NMCLIENT); + + g_signal_connect_object (panel->client, "notify::nm-running" , + G_CALLBACK (manager_running), panel, 0); + g_signal_connect_object (panel->client, "notify::active-connections", + G_CALLBACK (active_connections_changed), panel, 0); + g_signal_connect_object (panel->client, "device-added", + G_CALLBACK (device_added_cb), panel, 0); + g_signal_connect_object (panel->client, "device-removed", + G_CALLBACK (device_removed_cb), panel, 0); /* Setup ModemManager client */ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); @@ -907,8 +917,8 @@ cc_network_panel_init (CcNetworkPanel *panel) } /* add remote settings such as VPN settings as virtual devices */ - g_signal_connect (panel->client, NM_CLIENT_CONNECTION_ADDED, - G_CALLBACK (notify_connection_added_cb), panel); + g_signal_connect_object (panel->client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (notify_connection_added_cb), panel, 0); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel)); g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel); diff --git a/panels/network/cc-wifi-panel.c b/panels/network/cc-wifi-panel.c index 2c1cd17b7f..64321752cd 100644 --- a/panels/network/cc-wifi-panel.c +++ b/panels/network/cc-wifi-panel.c @@ -23,6 +23,7 @@ #include "net-device-wifi.h" #include "network-dialogs.h" +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include @@ -421,7 +422,7 @@ rfkill_proxy_acquired_cb (GObject *source_object, GError *error; error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (error) { @@ -618,37 +619,47 @@ cc_wifi_panel_init (CcWifiPanel *self) self->cancellable = g_cancellable_new (); self->devices = g_ptr_array_new_with_free_func (g_object_unref); - /* Load NetworkManager */ - self->client = nm_client_new (NULL, NULL); - - g_signal_connect (self->client, - "device-added", - G_CALLBACK (device_added_cb), - self); - - g_signal_connect (self->client, - "device-removed", - G_CALLBACK (device_removed_cb), - self); + /* Create and store a NMClient instance if it doesn't exist yet */ + if (!cc_object_storage_has_object (CC_OBJECT_NMCLIENT)) + { + NMClient *client = nm_client_new (NULL, NULL); + cc_object_storage_add_object (CC_OBJECT_NMCLIENT, client); + g_object_unref (client); + } - g_signal_connect (self->client, - "notify::wireless-enabled", - G_CALLBACK (wireless_enabled_cb), - self); + /* Load NetworkManager */ + self->client = cc_object_storage_get_object (CC_OBJECT_NMCLIENT); + + g_signal_connect_object (self->client, + "device-added", + G_CALLBACK (device_added_cb), + self, + 0); + + g_signal_connect_object (self->client, + "device-removed", + G_CALLBACK (device_removed_cb), + self, + 0); + + g_signal_connect_object (self->client, + "notify::wireless-enabled", + G_CALLBACK (wireless_enabled_cb), + self, + 0); /* Load Wi-Fi devices */ load_wifi_devices (self); /* Acquire Airplane Mode proxy */ - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.gnome.SettingsDaemon.Rfkill", - self->cancellable, - rfkill_proxy_acquired_cb, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + self->cancellable, + rfkill_proxy_acquired_cb, + self); /* Handle comment-line arguments after loading devices */ handle_argv (self); -- GitLab From 35f948f5fbdf784ff20a4b0cc4775c7fc1fbe413 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:01:15 -0300 Subject: [PATCH 07/14] common: Cache D-Bus proxy --- panels/common/cc-common-language.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/panels/common/cc-common-language.c b/panels/common/cc-common-language.c index 028213acbc..4ea4f06ad5 100644 --- a/panels/common/cc-common-language.c +++ b/panels/common/cc-common-language.c @@ -33,6 +33,7 @@ #include #include "cc-common-language.h" +#include "shell/cc-object-storage.h" static char *get_lang_for_user_object_path (const char *path); @@ -175,14 +176,13 @@ get_lang_for_user_object_path (const char *path) GVariant *props; char *lang; - user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.Accounts", - path, - "org.freedesktop.Accounts.User", - NULL, - &error); + user = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.Accounts", + path, + "org.freedesktop.Accounts.User", + NULL, + &error); if (user == NULL) { g_warning ("Failed to get proxy for user '%s': %s", path, error->message); -- GitLab From e46d505182c087858ecf52609c3802be5d285dfe Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:01:44 -0300 Subject: [PATCH 08/14] info: Cache D-Bus proxies --- panels/info/cc-info-overview-panel.c | 42 +++++++++++++--------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c index 411c1c9054..4301090f9c 100644 --- a/panels/info/cc-info-overview-panel.c +++ b/panels/info/cc-info-overview-panel.c @@ -22,6 +22,7 @@ #include #include "shell/cc-hostname-entry.h" +#include "shell/cc-object-storage.h" #include "cc-info-resources.h" #include "info-cleanup.h" @@ -235,13 +236,12 @@ get_renderer_from_session (void) char *renderer; g_autoptr(GError) error = NULL; - session_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SessionManager", - "/org/gnome/SessionManager", - "org.gnome.SessionManager", - NULL, &error); + session_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + NULL, &error); if (error != NULL) { g_warning ("Unable to connect to create a proxy for org.gnome.SessionManager: %s", @@ -302,13 +302,12 @@ has_dual_gpu (void) gboolean ret; g_autoptr(GError) error = NULL; - switcheroo_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "net.hadess.SwitcherooControl", - "/net/hadess/SwitcherooControl", - "net.hadess.SwitcherooControl", - NULL, &error); + switcheroo_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "net.hadess.SwitcherooControl", + "/net/hadess/SwitcherooControl", + "net.hadess.SwitcherooControl", + NULL, &error); if (switcheroo_proxy == NULL) { g_debug ("Unable to connect to create a proxy for net.hadess.SwitcherooControl: %s", @@ -720,14 +719,13 @@ info_overview_panel_setup_virt (CcInfoOverviewPanel *self) g_autoptr(GVariant) variant = NULL; GVariant *inner; - systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1", - NULL, - &error); + systemd_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1", + NULL, + &error); if (systemd_proxy == NULL) { -- GitLab From 77ac09aa04c26a88b3c75466ab3c8432b3682b0c Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:02:44 -0300 Subject: [PATCH 09/14] notification: Cache D-Bus proxy --- panels/notifications/cc-notifications-panel.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/panels/notifications/cc-notifications-panel.c b/panels/notifications/cc-notifications-panel.c index 1265b5b6fd..0b1b834ca1 100644 --- a/panels/notifications/cc-notifications-panel.c +++ b/panels/notifications/cc-notifications-panel.c @@ -25,6 +25,7 @@ #include #include +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-notifications-panel.h" #include "cc-notifications-resources.h" @@ -150,7 +151,7 @@ on_perm_store_ready (GObject *source_object, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -241,15 +242,14 @@ cc_notifications_panel_init (CcNotificationsPanel *panel) gtk_widget_show (w); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.impl.portal.PermissionStore", - "/org/freedesktop/impl/portal/PermissionStore", - "org.freedesktop.impl.portal.PermissionStore", - panel->apps_load_cancellable, - on_perm_store_ready, - panel); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.impl.portal.PermissionStore", + "/org/freedesktop/impl/portal/PermissionStore", + "org.freedesktop.impl.portal.PermissionStore", + panel->apps_load_cancellable, + on_perm_store_ready, + panel); } static const char * -- GitLab From eb62419b4bd989b5a39f9fe8f37209edf9f8c606 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:03:13 -0300 Subject: [PATCH 10/14] power: Cache D-Bus proxies and NMClient --- panels/power/cc-power-panel.c | 134 +++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 59 deletions(-) diff --git a/panels/power/cc-power-panel.c b/panels/power/cc-power-panel.c index f9b67a4583..b78c17a499 100644 --- a/panels/power/cc-power-panel.c +++ b/panels/power/cc-power-panel.c @@ -29,6 +29,7 @@ #include #endif +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-power-panel.h" #include "cc-power-resources.h" @@ -1083,7 +1084,7 @@ got_screen_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da CcPowerPanel *self; GDBusProxy *screen_proxy; - screen_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + screen_proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (screen_proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1096,8 +1097,8 @@ got_screen_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da self->priv->screen_proxy = screen_proxy; /* we want to change the bar if the user presses brightness buttons */ - g_signal_connect (screen_proxy, "g-properties-changed", - G_CALLBACK (on_screen_property_change), self); + g_signal_connect_object (screen_proxy, "g-properties-changed", + G_CALLBACK (on_screen_property_change), self, 0); sync_screen_brightness (self); als_enabled_state_changed (self); @@ -1120,7 +1121,7 @@ got_kbd_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) CcPowerPanel *self; GDBusProxy *kbd_proxy; - kbd_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + kbd_proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (kbd_proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1133,8 +1134,8 @@ got_kbd_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) self->priv->kbd_proxy = kbd_proxy; /* we want to change the bar if the user presses brightness buttons */ - g_signal_connect (kbd_proxy, "g-properties-changed", - G_CALLBACK (on_kbd_property_change), self); + g_signal_connect_object (kbd_proxy, "g-properties-changed", + G_CALLBACK (on_kbd_property_change), self, 0); sync_kbd_brightness (self); } @@ -1440,13 +1441,31 @@ nm_device_changed (NMClient *client, gtk_widget_set_visible (priv->mobile_row, has_mobile_devices (priv->nm_client)); } +static void +setup_nm_client (CcPowerPanel *self, + NMClient *client) +{ + CcPowerPanelPrivate *priv = self->priv; + + priv->nm_client = client; + + g_signal_connect_object (priv->nm_client, "notify", + G_CALLBACK (nm_client_state_changed), self, 0); + g_signal_connect_object (priv->nm_client, "device-added", + G_CALLBACK (nm_device_changed), self, 0); + g_signal_connect_object (priv->nm_client, "device-removed", + G_CALLBACK (nm_device_changed), self, 0); + + nm_client_state_changed (priv->nm_client, NULL, self); + nm_device_changed (priv->nm_client, NULL, self); +} + static void nm_client_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { CcPowerPanel *self; - CcPowerPanelPrivate *priv; NMClient *client; GError *error = NULL; @@ -1467,18 +1486,12 @@ nm_client_ready_cb (GObject *source_object, } self = user_data; - priv = self->priv; - priv->nm_client = client; - g_signal_connect (priv->nm_client, "notify", - G_CALLBACK (nm_client_state_changed), self); - g_signal_connect (priv->nm_client, "device-added", - G_CALLBACK (nm_device_changed), self); - g_signal_connect (priv->nm_client, "device-removed", - G_CALLBACK (nm_device_changed), self); + /* Setup the client */ + setup_nm_client (self, client); - nm_client_state_changed (priv->nm_client, NULL, self); - nm_device_changed (priv->nm_client, NULL, self); + /* Store the object in the cache too */ + cc_object_storage_add_object (CC_OBJECT_NMCLIENT, client); } #endif @@ -1648,13 +1661,12 @@ iio_proxy_appeared_cb (GDBusConnection *connection, GError *error = NULL; self->priv->iio_proxy = - g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "net.hadess.SensorProxy", - "/net/hadess/SensorProxy", - "net.hadess.SensorProxy", - NULL, &error); + cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "net.hadess.SensorProxy", + "/net/hadess/SensorProxy", + "net.hadess.SensorProxy", + NULL, &error); if (error != NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1887,29 +1899,35 @@ add_power_saving_section (CcPowerPanel *self) g_signal_connect (G_OBJECT (priv->mobile_switch), "notify::active", G_CALLBACK (mobile_switch_changed), self); - nm_client_new_async (priv->cancellable, nm_client_ready_cb, self); + /* Create and store a NMClient instance if it doesn't exist yet */ + if (cc_object_storage_has_object (CC_OBJECT_NMCLIENT)) + setup_nm_client (self, cc_object_storage_get_object (CC_OBJECT_NMCLIENT)); + else + nm_client_new_async (priv->cancellable, nm_client_ready_cb, self); g_signal_connect (G_OBJECT (priv->wifi_switch), "notify::active", G_CALLBACK (wifi_switch_changed), self); #endif #ifdef HAVE_BLUETOOTH - priv->bt_rfkill = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.gnome.SettingsDaemon.Rfkill", - NULL, NULL); + + priv->bt_rfkill = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + NULL, + NULL); + if (priv->bt_rfkill) { - priv->bt_properties = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.freedesktop.DBus.Properties", - NULL, NULL); + priv->bt_properties = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.freedesktop.DBus.Properties", + NULL, + NULL); } row = no_prelight_row_new (); @@ -1944,8 +1962,8 @@ add_power_saving_section (CcPowerPanel *self) gtk_widget_show_all (box); gtk_widget_set_no_show_all (row, TRUE); priv->bt_row = row; - g_signal_connect_swapped (G_OBJECT (priv->bt_rfkill), "g-properties-changed", - G_CALLBACK (bt_powered_state_changed), self); + g_signal_connect_object (priv->bt_rfkill, "g-properties-changed", + G_CALLBACK (bt_powered_state_changed), self, G_CONNECT_SWAPPED); g_signal_connect (G_OBJECT (priv->bt_switch), "notify::active", G_CALLBACK (bt_switch_changed), self); @@ -2509,24 +2527,22 @@ cc_power_panel_init (CcPowerPanel *self) priv->cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Power", - "/org/gnome/SettingsDaemon/Power", - "org.gnome.SettingsDaemon.Power.Screen", - priv->cancellable, - got_screen_proxy_cb, - self); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Power", - "/org/gnome/SettingsDaemon/Power", - "org.gnome.SettingsDaemon.Power.Keyboard", - priv->cancellable, - got_kbd_proxy_cb, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Power", + "/org/gnome/SettingsDaemon/Power", + "org.gnome.SettingsDaemon.Power.Screen", + priv->cancellable, + got_screen_proxy_cb, + self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Power", + "/org/gnome/SettingsDaemon/Power", + "org.gnome.SettingsDaemon.Power.Keyboard", + priv->cancellable, + got_kbd_proxy_cb, + self); priv->chassis_type = get_chassis_type (priv->cancellable); -- GitLab From 28ad1d1602d50bccd915cd44b114ca4ef6bba6c0 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:03:57 -0300 Subject: [PATCH 11/14] printers: Cache CUPS D-Bus proxy --- panels/printers/cc-printers-panel.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c index 55a1682b47..4815c45205 100644 --- a/panels/printers/cc-printers-panel.c +++ b/panels/printers/cc-printers-panel.c @@ -18,6 +18,8 @@ #include +#include "shell/cc-object-storage.h" + #include "cc-printers-panel.h" #include "cc-printers-resources.h" #include "pp-printer.h" @@ -608,14 +610,13 @@ attach_to_cups_notifier_cb (GObject *source_object, priv->subscription_renewal_id = g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription, self); - priv->cups_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - 0, - NULL, - CUPS_DBUS_NAME, - CUPS_DBUS_PATH, - CUPS_DBUS_INTERFACE, - NULL, - &error); + priv->cups_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + CUPS_DBUS_NAME, + CUPS_DBUS_PATH, + CUPS_DBUS_INTERFACE, + NULL, + &error); if (!priv->cups_proxy) { -- GitLab From 754434fa0dab020046ff4a198ba259c3b6d6d7d5 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:04:28 -0300 Subject: [PATCH 12/14] privacy: Cache D-Bus proxies --- panels/privacy/cc-privacy-panel.c | 50 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/panels/privacy/cc-privacy-panel.c b/panels/privacy/cc-privacy-panel.c index 428dafef7c..daa050a414 100644 --- a/panels/privacy/cc-privacy-panel.c +++ b/panels/privacy/cc-privacy-panel.c @@ -18,6 +18,7 @@ * Author: Matthias Clasen */ +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-privacy-panel.h" #include "cc-privacy-resources.h" @@ -463,7 +464,7 @@ on_gclue_manager_ready (GObject *source_object, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -475,10 +476,11 @@ on_gclue_manager_ready (GObject *source_object, self = user_data; self->priv->gclue_manager = proxy; - g_signal_connect (self->priv->gclue_manager, - "g-properties-changed", - G_CALLBACK (on_gclue_manager_props_changed), - self); + g_signal_connect_object (self->priv->gclue_manager, + "g-properties-changed", + G_CALLBACK (on_gclue_manager_props_changed), + self, + 0); update_location_label (self); } @@ -783,7 +785,7 @@ on_perm_store_ready (GObject *source_object, GVariant *params; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -842,25 +844,23 @@ add_location (CcPrivacyPanel *self) g_free, g_object_unref); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.GeoClue2", - "/org/freedesktop/GeoClue2/Manager", - "org.freedesktop.GeoClue2.Manager", - priv->cancellable, - on_gclue_manager_ready, - self); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.impl.portal.PermissionStore", - "/org/freedesktop/impl/portal/PermissionStore", - "org.freedesktop.impl.portal.PermissionStore", - priv->cancellable, - on_perm_store_ready, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.GeoClue2", + "/org/freedesktop/GeoClue2/Manager", + "org.freedesktop.GeoClue2.Manager", + priv->cancellable, + on_gclue_manager_ready, + self); + + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.impl.portal.PermissionStore", + "/org/freedesktop/impl/portal/PermissionStore", + "org.freedesktop.impl.portal.PermissionStore", + priv->cancellable, + on_perm_store_ready, + self); } static void -- GitLab From 10dfbb526e102676016fb9af3d252f8559b7e125 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:04:48 -0300 Subject: [PATCH 13/14] region: Cache D-Bus proxy --- panels/region/cc-region-panel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c index 48c0d7ac04..232c3faad1 100644 --- a/panels/region/cc-region-panel.c +++ b/panels/region/cc-region-panel.c @@ -26,6 +26,7 @@ #include #include +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-region-panel.h" #include "cc-region-resources.h" @@ -1796,7 +1797,7 @@ session_proxy_ready (GObject *source, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (!proxy) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1832,15 +1833,14 @@ cc_region_panel_init (CcRegionPanel *self) priv->cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SessionManager", - "/org/gnome/SessionManager", - "org.gnome.SessionManager", - priv->cancellable, - session_proxy_ready, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + priv->cancellable, + session_proxy_ready, + self); setup_login_button (self); setup_language_section (self); -- GitLab From 85296f1ebada9670702be7c4de5f6160b90a9470 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 28 Mar 2018 10:44:46 -0300 Subject: [PATCH 14/14] trivial: Code style improvements --- shell/cc-window.c | 51 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/shell/cc-window.c b/shell/cc-window.c index 09f5721b11..fea3cf567b 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -305,12 +305,15 @@ set_active_panel_from_id (CcShell *shell, GVariant *parameters, GError **error) { + g_autoptr(GIcon) gicon = NULL; + g_autofree gchar *name = NULL; GtkTreeIter iter; - gboolean iter_valid; - gchar *name = NULL; - GIcon *gicon = NULL; - CcWindow *self = CC_WINDOW (shell); GtkWidget *old_panel; + CcWindow *self; + gboolean iter_valid; + gboolean activated; + + self = CC_WINDOW (shell); /* When loading the same panel again, just set its parameters */ if (g_strcmp0 (self->current_panel_id, start_id) == 0) @@ -349,26 +352,25 @@ set_active_panel_from_id (CcShell *shell, if (!name) { g_warning ("Could not find settings panel \"%s\"", start_id); + return TRUE; } - else if (!activate_panel (CC_WINDOW (shell), start_id, parameters, name, gicon)) - { - /* Failed to activate the panel for some reason, - * let's keep the old panel around instead */ - } - else - { - /* Successful activation */ - g_free (self->current_panel_id); - self->current_panel_id = g_strdup (start_id); - if (old_panel) - gtk_container_remove (GTK_CONTAINER (self->stack), old_panel); + /* Activate the panel */ + activated = activate_panel (CC_WINDOW (shell), start_id, parameters, name, gicon); - cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), start_id); - } + /* Failed to activate the panel for some reason, let's keep the old + * panel around instead */ + if (!activated) + return TRUE; + + /* Successful activation */ + g_free (self->current_panel_id); + self->current_panel_id = g_strdup (start_id); - g_clear_pointer (&name, g_free); - g_clear_object (&gicon); + if (old_panel) + gtk_container_remove (GTK_CONTAINER (self->stack), old_panel); + + cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), start_id); return TRUE; } @@ -387,13 +389,10 @@ set_active_panel (CcWindow *shell, /* set the new panel */ if (panel) - { - shell->active_panel = g_object_ref (panel); - } + shell->active_panel = g_object_ref (panel); else - { - shell_show_overview_page (shell); - } + shell_show_overview_page (shell); + g_object_notify (G_OBJECT (shell), "active-panel"); } } -- GitLab