shell: replace GMenu loading code with an hardcoded list of panels

Now that we don't allow or load external panels, using libgnome-menu is just
overengineering. We can get the same results with less code by keeping a static
list of function pointers.
This reduces the number of places one needs to patch to add a new panel.
Also, this way we avoid registering all types at startup, and if we want
we can switch to load panel desktop files in a separate thread.

https://bugzilla.gnome.org/show_bug.cgi?id=690165
This commit is contained in:
Giovanni Campagna 2012-12-13 17:16:57 +01:00
parent 0e7192e676
commit 0139f68416
8 changed files with 266 additions and 246 deletions

View file

@ -120,7 +120,7 @@ PKG_CHECK_MODULES(LIBLANGUAGE, $COMMON_MODULES gnome-desktop-3.0 fontconfig)
PKG_CHECK_MODULES(LIBSHORTCUTS, $COMMON_MODULES x11)
# egg-list-box is a static library, so it must be shared among all panels
# or it breaks GType registration
PKG_CHECK_MODULES(SHELL, $COMMON_MODULES libgnome-menu-3.0 x11 egg-list-box)
PKG_CHECK_MODULES(SHELL, $COMMON_MODULES x11 egg-list-box)
PKG_CHECK_MODULES(BACKGROUND_PANEL, $COMMON_MODULES libxml-2.0 gnome-desktop-3.0
gdk-pixbuf-2.0 >= $GDKPIXBUF_REQUIRED_VERSION)
PKG_CHECK_MODULES(DATETIME_PANEL, $COMMON_MODULES

View file

@ -19,6 +19,8 @@ gnome_control_center_SOURCES = \
cc-shell-model.h \
cc-editable-entry.c \
cc-editable-entry.h \
cc-panel-loader.c \
cc-panel-loader.h \
cc-panel.c \
cc-panel.h \
cc-shell.c \

188
shell/cc-panel-loader.c Normal file
View file

@ -0,0 +1,188 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* The Control Center 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.
*
* The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author: Thomas Wood <thos@gnome.org>
*/
#include <config.h>
#include <string.h>
#include <gio/gdesktopappinfo.h>
#include "cc-panel-loader.h"
/* Extension points */
extern GType cc_background_panel_get_type (void);
#ifdef BUILD_BLUETOOTH
extern GType cc_bluetooth_panel_get_type (void);
#endif /* BUILD_BLUETOOTH */
extern GType cc_color_panel_get_type (void);
extern GType cc_date_time_panel_get_type (void);
extern GType cc_display_panel_get_type (void);
extern GType cc_info_panel_get_type (void);
extern GType cc_keyboard_panel_get_type (void);
extern GType cc_mouse_panel_get_type (void);
#ifdef BUILD_NETWORK
extern GType cc_network_panel_get_type (void);
#endif /* BUILD_NETWORK */
extern GType cc_goa_panel_get_type (void);
extern GType cc_power_panel_get_type (void);
#ifdef BUILD_PRINTERS
extern GType cc_printers_panel_get_type (void);
#endif /* BUILD_PRINTERS */
extern GType cc_privacy_panel_get_type (void);
extern GType cc_region_panel_get_type (void);
extern GType cc_screen_panel_get_type (void);
extern GType cc_search_panel_get_type (void);
extern GType cc_sound_panel_get_type (void);
extern GType cc_ua_panel_get_type (void);
extern GType cc_user_panel_get_type (void);
#ifdef BUILD_WACOM
extern GType cc_wacom_panel_get_type (void);
#endif /* BUILD_WACOM */
static struct {
const char *name;
GType (*get_type)(void);
} all_panels[] = {
{ "background", cc_background_panel_get_type },
#ifdef BUILD_BLUETOOTH
{ "bluetooth", cc_bluetooth_panel_get_type },
#endif
{ "color", cc_color_panel_get_type },
{ "datetime", cc_date_time_panel_get_type },
{ "display", cc_display_panel_get_type },
{ "info", cc_info_panel_get_type },
{ "keyboard", cc_keyboard_panel_get_type },
{ "mouse", cc_mouse_panel_get_type },
#ifdef BUILD_NETWORK
{ "network", cc_network_panel_get_type },
#endif
{ "online-accounts", cc_goa_panel_get_type },
{ "power", cc_power_panel_get_type },
#ifdef BUILD_PRINTERS
{ "printers", cc_printers_panel_get_type },
#endif
{ "privacy", cc_privacy_panel_get_type },
{ "region", cc_region_panel_get_type },
{ "screen", cc_screen_panel_get_type },
{ "search", cc_search_panel_get_type },
{ "sound", cc_sound_panel_get_type },
{ "universal-access", cc_ua_panel_get_type },
{ "user-accounts", cc_user_panel_get_type },
#ifdef BUILD_WACOM
{ "wacom", cc_wacom_panel_get_type },
#endif
};
static GHashTable *panel_types;
static int
parse_categories (GDesktopAppInfo *app)
{
const char *categories;
char **split;
int retval;
int i;
categories = g_desktop_app_info_get_categories (app);
split = g_strsplit (categories, ";", -1);
retval = -1;
for (i = 0; split[i]; i++)
{
if (strcmp (split[i], "HardwareSettings") == 0)
retval = CC_CATEGORY_HARDWARE;
else if (strcmp (split[i], "X-GNOME-PersonalSettings") == 0)
retval = CC_CATEGORY_PERSONAL;
else if (strcmp (split[i], "X-GNOME-SystemSettings") == 0)
retval = CC_CATEGORY_SYSTEM;
}
if (retval < 0)
{
g_warning ("Invalid categories %s for panel %s",
categories, g_app_info_get_id (G_APP_INFO (app)));
}
g_strfreev (split);
return retval;
}
void
cc_panel_loader_fill_model (CcShellModel *model)
{
int i;
for (i = 0; i < G_N_ELEMENTS (all_panels); i++)
{
GDesktopAppInfo *app;
char *desktop_name;
int category;
desktop_name = g_strconcat ("gnome-", all_panels[i].name,
"-panel.desktop", NULL);
app = g_desktop_app_info_new (desktop_name);
if (app == NULL)
{
g_warning ("Ignoring broken panel %s (missing desktop file)",
all_panels[i].name);
continue;
}
category = parse_categories (app);
if (G_UNLIKELY (category < 0))
continue;
cc_shell_model_add_item (model, category, G_APP_INFO (app), all_panels[i].name);
g_object_unref (app);
}
}
static void
ensure_panel_types (void)
{
int i;
if (G_LIKELY (panel_types != NULL))
return;
panel_types = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < G_N_ELEMENTS (all_panels); i++)
g_hash_table_insert (panel_types, (char*)all_panels[i].name, all_panels[i].get_type);
}
CcPanel *
cc_panel_loader_load_by_name (CcShell *shell,
const char *name,
const char **argv)
{
GType (*get_type) (void);
ensure_panel_types ();
get_type = g_hash_table_lookup (panel_types, name);
g_return_val_if_fail (get_type != NULL, NULL);
return g_object_new (get_type (),
"shell", shell,
"argv", argv,
NULL);
}

38
shell/cc-panel-loader.h Normal file
View file

@ -0,0 +1,38 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* The Control Center 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.
*
* The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _CC_PANEL_LOADER_H
#define _CC_PANEL_LOADER_H
#include <glib.h>
#include <glib-object.h>
#include <shell/cc-panel.h>
#include <shell/cc-shell-model.h>
G_BEGIN_DECLS
void cc_panel_loader_fill_model (CcShellModel *model);
CcPanel *cc_panel_loader_load_by_name (CcShell *shell,
const char *name,
const char **argv);
G_END_DECLS
#endif

View file

@ -43,13 +43,8 @@ G_BEGIN_DECLS
*
* use: CC_PANEL_REGISTER (PluginName, plugin_name)
*/
#define CC_PANEL_REGISTER(PluginName, plugin_name) \
G_DEFINE_TYPE_WITH_CODE (PluginName, plugin_name, CC_TYPE_PANEL, \
GIOExtensionPoint *ep; \
ep = g_io_extension_point_register ("CcPanel"); \
g_io_extension_point_set_required_type (ep, CC_TYPE_PANEL); \
g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, \
g_define_type_id, PANEL_ID, 0))
#define CC_PANEL_REGISTER(PluginName, plugin_name) \
G_DEFINE_TYPE (PluginName, plugin_name, CC_TYPE_PANEL)
typedef struct CcPanelPrivate CcPanelPrivate;

View file

@ -22,6 +22,8 @@
#include "cc-shell-model.h"
#include <string.h>
#include <gio/gdesktopappinfo.h>
#define GNOME_SETTINGS_PANEL_ID_KEY "X-GNOME-Settings-Panel"
#define GNOME_SETTINGS_PANEL_CATEGORY GNOME_SETTINGS_PANEL_ID_KEY
#define GNOME_SETTINGS_PANEL_ID_KEYWORDS "Keywords"
@ -105,7 +107,7 @@ static void
cc_shell_model_init (CcShellModel *self)
{
GType types[] = {G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ICON, G_TYPE_STRV};
GDK_TYPE_PIXBUF, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_ICON, G_TYPE_STRV};
gtk_list_store_set_column_types (GTK_LIST_STORE (self),
N_COLS, types);
@ -124,15 +126,14 @@ cc_shell_model_new (void)
}
void
cc_shell_model_add_item (CcShellModel *model,
const gchar *category_name,
GMenuTreeEntry *item,
const char *id)
cc_shell_model_add_item (CcShellModel *model,
CcPanelCategory category,
GAppInfo *appinfo,
const char *id)
{
GAppInfo *appinfo = G_APP_INFO (gmenu_tree_entry_get_app_info (item));
GIcon *icon = g_app_info_get_icon (appinfo);
const gchar *name = g_app_info_get_name (appinfo);
const gchar *desktop = gmenu_tree_entry_get_desktop_file_path (item);
const gchar *desktop = g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (appinfo));
const gchar *comment = g_app_info_get_description (appinfo);
GdkPixbuf *pixbuf = NULL;
const char * const * keywords;
@ -146,7 +147,7 @@ cc_shell_model_add_item (CcShellModel *model,
COL_DESKTOP_FILE, desktop,
COL_ID, id,
COL_PIXBUF, pixbuf,
COL_CATEGORY, category_name,
COL_CATEGORY, category,
COL_DESCRIPTION, comment,
COL_GICON, icon,
COL_KEYWORDS, keywords,

View file

@ -23,8 +23,6 @@
#define _CC_SHELL_MODEL_H
#include <gtk/gtk.h>
#define GMENU_I_KNOW_THIS_IS_UNSTABLE
#include <gmenu-tree.h>
G_BEGIN_DECLS
@ -53,6 +51,13 @@ G_BEGIN_DECLS
typedef struct _CcShellModel CcShellModel;
typedef struct _CcShellModelClass CcShellModelClass;
typedef enum {
CC_CATEGORY_PERSONAL,
CC_CATEGORY_HARDWARE,
CC_CATEGORY_SYSTEM,
CC_CATEGORY_LAST
} CcPanelCategory;
enum
{
COL_NAME,
@ -82,8 +87,8 @@ GType cc_shell_model_get_type (void) G_GNUC_CONST;
CcShellModel *cc_shell_model_new (void);
void cc_shell_model_add_item (CcShellModel *model,
const gchar *category_name,
GMenuTreeEntry *item,
CcPanelCategory category,
GAppInfo *appinfo,
const char *id);
G_END_DECLS

View file

@ -32,13 +32,12 @@
#ifdef HAVE_CHEESE
#include <clutter-gtk/clutter-gtk.h>
#endif /* HAVE_CHEESE */
#define GMENU_I_KNOW_THIS_IS_UNSTABLE
#include <gmenu-tree.h>
#include "cc-panel.h"
#include "cc-shell.h"
#include "cc-shell-category-view.h"
#include "cc-shell-model.h"
#include "cc-panel-loader.h"
G_DEFINE_TYPE (GnomeControlCenter, gnome_control_center, CC_TYPE_SHELL)
@ -56,36 +55,6 @@ G_DEFINE_TYPE (GnomeControlCenter, gnome_control_center, CC_TYPE_SHELL)
#define MIN_ICON_VIEW_HEIGHT 300
/* Extension points */
extern GType cc_background_panel_get_type (void);
#ifdef BUILD_BLUETOOTH
extern GType cc_bluetooth_panel_get_type (void);
#endif /* BUILD_BLUETOOTH */
extern GType cc_color_panel_get_type (void);
extern GType cc_date_time_panel_get_type (void);
extern GType cc_display_panel_get_type (void);
extern GType cc_info_panel_get_type (void);
extern GType cc_keyboard_panel_get_type (void);
extern GType cc_mouse_panel_get_type (void);
#ifdef BUILD_NETWORK
extern GType cc_network_panel_get_type (void);
#endif /* BUILD_NETWORK */
extern GType cc_goa_panel_get_type (void);
extern GType cc_power_panel_get_type (void);
#ifdef BUILD_PRINTERS
extern GType cc_printers_panel_get_type (void);
#endif /* BUILD_PRINTERS */
extern GType cc_privacy_panel_get_type (void);
extern GType cc_region_panel_get_type (void);
extern GType cc_screen_panel_get_type (void);
extern GType cc_search_panel_get_type (void);
extern GType cc_sound_panel_get_type (void);
extern GType cc_ua_panel_get_type (void);
extern GType cc_user_panel_get_type (void);
#ifdef BUILD_WACOM
extern GType cc_wacom_panel_get_type (void);
#endif /* BUILD_WACOM */
typedef enum {
SMALL_SCREEN_UNSET,
SMALL_SCREEN_TRUE,
@ -107,9 +76,7 @@ struct _GnomeControlCenterPrivate
GtkWidget *lock_button;
GPtrArray *custom_widgets;
GMenuTree *menu_tree;
GtkListStore *store;
GHashTable *category_views;
GtkTreeModel *search_filter;
GtkWidget *search_view;
@ -117,8 +84,6 @@ struct _GnomeControlCenterPrivate
guint32 last_time;
GIOExtensionPoint *extension_point;
gchar *default_window_title;
gchar *default_window_icon;
@ -214,28 +179,15 @@ activate_panel (GnomeControlCenter *shell,
GIcon *gicon)
{
GnomeControlCenterPrivate *priv = shell->priv;
GType panel_type = G_TYPE_INVALID;
GtkWidget *box;
const gchar *icon_name;
GIOExtension *extension;
if (!desktop_file)
return FALSE;
if (!id)
return FALSE;
/* check if there is an extension point that implements this panel */
extension = g_io_extension_point_get_extension_by_name (priv->extension_point, id);
if (extension == NULL)
{
g_warning ("Could not find the loadable module for panel '%s'", id);
return FALSE;
}
panel_type = g_io_extension_get_type (extension);
/* create the panel */
priv->current_panel = g_object_new (panel_type, "shell", shell, "argv", argv, NULL);
priv->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (shell), id, argv));
cc_shell_set_active_panel (CC_SHELL (shell), CC_PANEL (priv->current_panel));
gtk_widget_show (priv->current_panel);
@ -545,20 +497,15 @@ model_filter_func (GtkTreeModel *model,
}
static gboolean
category_filter_func (GtkTreeModel *model,
GtkTreeIter *iter,
gchar *filter)
category_filter_func (GtkTreeModel *model,
GtkTreeIter *iter,
CcPanelCategory filter)
{
gchar *category;
gboolean result;
guint category;
gtk_tree_model_get (model, iter, COL_CATEGORY, &category, -1);
result = (g_strcmp0 (category, filter) == 0);
g_free (category);
return result;
return (category == filter);
}
static void
@ -734,16 +681,14 @@ setup_lock (GnomeControlCenter *shell)
}
static void
maybe_add_category_view (GnomeControlCenter *shell,
const char *name)
add_category_view (GnomeControlCenter *shell,
CcPanelCategory category,
const char *name)
{
GtkTreeModel *filter;
GtkWidget *categoryview;
if (g_hash_table_lookup (shell->priv->category_views, name) != NULL)
return;
if (g_hash_table_size (shell->priv->category_views) > 0)
if (category > 0)
{
GtkWidget *separator;
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
@ -758,7 +703,7 @@ maybe_add_category_view (GnomeControlCenter *shell,
NULL);
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
(GtkTreeModelFilterVisibleFunc) category_filter_func,
g_strdup (name), g_free);
GINT_TO_POINTER (category), NULL);
categoryview = cc_shell_category_view_new (name, filter);
gtk_box_pack_start (GTK_BOX (shell->priv->main_vbox), categoryview, FALSE, TRUE, 0);
@ -778,101 +723,6 @@ maybe_add_category_view (GnomeControlCenter *shell,
g_signal_connect (cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (categoryview)),
"keynav-failed",
G_CALLBACK (keynav_failed), shell);
g_hash_table_insert (shell->priv->category_views, g_strdup (name), categoryview);
}
static char *
get_id_for_menu_entry (GMenuTreeEntry *item)
{
const char *desktop_name;
desktop_name = gmenu_tree_entry_get_desktop_file_id (item);
if (!g_str_has_prefix (desktop_name, "gnome-") ||
!g_str_has_suffix (desktop_name, "-panel.desktop"))
return NULL;
return g_strndup (desktop_name + strlen ("gnome-"),
strlen (desktop_name) - strlen ("-panel.desktop") - strlen ("gnome-"));
}
static void
reload_menu (GnomeControlCenter *shell)
{
GError *error;
GMenuTreeDirectory *d;
GMenuTreeIter *iter;
GMenuTreeItemType next_type;
error = NULL;
if (!gmenu_tree_load_sync (shell->priv->menu_tree, &error))
{
g_warning ("Could not load control center menu: %s", error->message);
g_clear_error (&error);
return;
}
d = gmenu_tree_get_root_directory (shell->priv->menu_tree);
iter = gmenu_tree_directory_iter (d);
while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID)
{
if (next_type == GMENU_TREE_ITEM_DIRECTORY)
{
GMenuTreeDirectory *subdir;
const gchar *dir_name;
GMenuTreeIter *sub_iter;
GMenuTreeItemType sub_next_type;
subdir = gmenu_tree_iter_get_directory (iter);
dir_name = gmenu_tree_directory_get_name (subdir);
maybe_add_category_view (shell, dir_name);
/* add the items from this category to the model */
sub_iter = gmenu_tree_directory_iter (subdir);
while ((sub_next_type = gmenu_tree_iter_next (sub_iter)) != GMENU_TREE_ITEM_INVALID)
{
if (sub_next_type == GMENU_TREE_ITEM_ENTRY)
{
GMenuTreeEntry *item;
char *id;
item = gmenu_tree_iter_get_entry (sub_iter);
id = get_id_for_menu_entry (item);
if (id != NULL &&
g_io_extension_point_get_extension_by_name (shell->priv->extension_point, id))
{
cc_shell_model_add_item (CC_SHELL_MODEL (shell->priv->store),
dir_name, item, id);
}
else
{
g_warning ("Not adding broken desktop file %s",
gmenu_tree_entry_get_desktop_file_id (item));
}
g_free (id);
gmenu_tree_item_unref (item);
}
}
gmenu_tree_iter_unref (sub_iter);
gmenu_tree_item_unref (subdir);
}
}
gmenu_tree_iter_unref (iter);
gmenu_tree_item_unref (d);
}
static void
on_menu_changed (GMenuTree *monitor,
GnomeControlCenter *shell)
{
gtk_list_store_clear (shell->priv->store);
reload_menu (shell);
}
static void
@ -888,57 +738,13 @@ setup_model (GnomeControlCenter *shell)
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (shell->priv->scrolled_window)));
priv->store = (GtkListStore *) cc_shell_model_new ();
priv->category_views = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
priv->menu_tree = gmenu_tree_new_for_path (MENUDIR "/gnomecc.menu", 0);
reload_menu (shell);
/* Add categories */
add_category_view (shell, CC_CATEGORY_PERSONAL, C_("category", "Personal"));
add_category_view (shell, CC_CATEGORY_HARDWARE, C_("category", "Hardware"));
add_category_view (shell, CC_CATEGORY_SYSTEM, C_("category", "System"));
g_signal_connect (priv->menu_tree, "changed", G_CALLBACK (on_menu_changed), shell);
}
static void
load_panel_modules (GnomeControlCenter *shell)
{
/* only allow this function to be run once to prevent modules being loaded
* twice
*/
if (shell->priv->extension_point)
return;
/* make sure the base type is registered */
g_type_from_name ("CcPanel");
shell->priv->extension_point
= g_io_extension_point_register (CC_SHELL_PANEL_EXTENSION_POINT);
g_type_ensure (cc_background_panel_get_type ());
#ifdef BUILD_BLUETOOTH
g_type_ensure (cc_bluetooth_panel_get_type ());
#endif /* BUILD_BLUETOOTH */
g_type_ensure (cc_color_panel_get_type ());
g_type_ensure (cc_date_time_panel_get_type ());
g_type_ensure (cc_display_panel_get_type ());
g_type_ensure (cc_info_panel_get_type ());
g_type_ensure (cc_keyboard_panel_get_type ());
g_type_ensure (cc_mouse_panel_get_type ());
#ifdef BUILD_NETWORK
g_type_ensure (cc_network_panel_get_type ());
#endif /* BUILD_NETWORK */
g_type_ensure (cc_goa_panel_get_type ());
g_type_ensure (cc_power_panel_get_type ());
#ifdef BUILD_PRINTERS
g_type_ensure (cc_printers_panel_get_type ());
#endif /* BUILD_PRINTERS */
g_type_ensure (cc_privacy_panel_get_type ());
g_type_ensure (cc_region_panel_get_type ());
g_type_ensure (cc_screen_panel_get_type ());
g_type_ensure (cc_search_panel_get_type ());
g_type_ensure (cc_sound_panel_get_type ());
g_type_ensure (cc_ua_panel_get_type ());
g_type_ensure (cc_user_panel_get_type ());
#ifdef BUILD_WACOM
g_type_ensure (cc_wacom_panel_get_type ());
#endif /* BUILD_WACOM */
cc_panel_loader_fill_model (CC_SHELL_MODEL (shell->priv->store));
}
static void
@ -1194,18 +1000,6 @@ gnome_control_center_finalize (GObject *object)
priv->default_window_icon = NULL;
}
if (priv->menu_tree)
{
g_signal_handlers_disconnect_by_func (priv->menu_tree,
G_CALLBACK (on_menu_changed), object);
g_object_unref (priv->menu_tree);
}
if (priv->category_views)
{
g_hash_table_destroy (priv->category_views);
}
G_OBJECT_CLASS (gnome_control_center_parent_class)->finalize (object);
}
@ -1447,9 +1241,6 @@ gnome_control_center_init (GnomeControlCenter *self)
/* keep a list of custom widgets to unload on panel change */
priv->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
/* load the panels that are implemented as builtin modules */
load_panel_modules (self);
/* load the available settings panels */
setup_model (self);