[Xfce4-commits] <xfce4-panel:devel> Add custom xfconf property bindings.
Nick Schermer
nick at xfce.org
Tue Aug 11 20:34:07 CEST 2009
Updating branch refs/heads/devel
to 7c4460246cb3676e5df860ba235817bc7a174c2c (commit)
from ee938abfd54bea1a9da4cb7f45e6ae04618f5e3e (commit)
commit 7c4460246cb3676e5df860ba235817bc7a174c2c
Author: Nick Schermer <nick at xfce.org>
Date: Sun May 31 16:04:31 2009 +0200
Add custom xfconf property bindings.
The goals of these bindings is speeding up the panel startup.
The bindings can optionally take a hash table for searching
properties, this way the panel only has to call dbus once
during startup for panel settings.
common/Makefile.am | 4 +-
common/panel-xfconf.c | 212 ++++++++++++++++++++
.../panel-xfconf.h | 34 ++--
3 files changed, 232 insertions(+), 18 deletions(-)
diff --git a/common/Makefile.am b/common/Makefile.am
index 909f29e..be8dd04 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -2,6 +2,8 @@
EXTRA_DIST = \
panel-dbus.h \
- panel-private.h
+ panel-private.h \
+ panel-xfconf.c \
+ panel-xfconf.h
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/common/panel-xfconf.c b/common/panel-xfconf.c
new file mode 100644
index 0000000..a5d1ad3
--- /dev/null
+++ b/common/panel-xfconf.c
@@ -0,0 +1,212 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <common/panel-xfconf.h>
+#include <libxfce4panel/libxfce4panel.h>
+
+
+typedef struct
+{
+ XfconfChannel *channel;
+ gchar *channel_prop;
+
+ GObject *object;
+ gchar *object_prop;
+} PropertyBinding;
+
+
+
+static void panel_properties_object_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
+static void panel_properties_object_destroyed (gpointer user_data,
+ GObject *where_the_object_was);
+static void panel_properties_channel_notify (XfconfChannel *channel,
+ const gchar *property,
+ const GValue *value,
+ gpointer user_data);
+static void panel_properties_channel_destroyed (gpointer user_data,
+ GObject *where_the_channel_was);
+
+
+
+static void
+panel_properties_object_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GValue value = { 0, };
+ PropertyBinding *binding = user_data;
+
+ panel_return_if_fail (G_IS_OBJECT (object));
+ panel_return_if_fail (binding->object == object);
+ panel_return_if_fail (XFCONF_IS_CHANNEL (binding->channel));
+
+ /* get the property from the object */
+ g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_object_get_property (object, g_param_spec_get_name (pspec), &value);
+
+ /* set the xfconf property */
+ xfconf_channel_set_property (binding->channel, binding->channel_prop,
+ &value);
+
+ /* cleanup */
+ g_value_unset (&value);
+}
+
+
+
+static void
+panel_properties_object_destroyed (gpointer user_data,
+ GObject *where_the_object_was)
+{
+ PropertyBinding *binding = user_data;
+
+ panel_return_if_fail (binding->object == where_the_object_was);
+ panel_return_if_fail (XFCONF_IS_CHANNEL (binding->channel));
+
+ /* disconnect from the object */
+ g_signal_handlers_disconnect_by_func (G_OBJECT (binding->channel),
+ panel_properties_channel_notify, binding);
+ g_object_weak_unref (G_OBJECT (binding->channel),
+ panel_properties_channel_destroyed, binding);
+
+ /* cleanup */
+ g_slice_free (PropertyBinding, binding);
+}
+
+
+
+static void
+panel_properties_channel_notify (XfconfChannel *channel,
+ const gchar *property,
+ const GValue *value,
+ gpointer user_data)
+{
+ PropertyBinding *binding = user_data;
+
+ panel_return_if_fail (XFCONF_IS_CHANNEL (channel));
+ panel_return_if_fail (binding->channel == channel);
+ panel_return_if_fail (G_IS_OBJECT (binding->object));
+
+ /* block property notify */
+ g_signal_handlers_block_by_func (G_OBJECT (binding->object),
+ G_CALLBACK (panel_properties_object_notify), binding);
+
+ /* set the property */
+ g_object_set_property (binding->object, binding->object_prop, value);
+
+ /* unblock property notify */
+ g_signal_handlers_unblock_by_func (G_OBJECT (binding->object),
+ G_CALLBACK (panel_properties_object_notify), binding);
+}
+
+
+
+static void
+panel_properties_channel_destroyed (gpointer user_data,
+ GObject *where_the_channel_was)
+{
+ PropertyBinding *binding = user_data;
+
+ panel_return_if_fail (binding->channel == (XfconfChannel *) where_the_channel_was);
+ panel_return_if_fail (G_IS_OBJECT (binding->object));
+
+ /* disconnect from the object */
+ g_signal_handlers_disconnect_by_func (G_OBJECT (binding->object),
+ panel_properties_object_notify, binding);
+ g_object_weak_unref (G_OBJECT (binding->object),
+ panel_properties_object_destroyed, binding);
+
+ /* cleanup */
+ g_slice_free (PropertyBinding, binding);
+}
+
+
+
+void
+panel_properties_bind (XfconfChannel *channel,
+ GObject *object,
+ const gchar *property_base,
+ const PanelProperty *properties,
+ GHashTable *hash_table)
+{
+ const PanelProperty *prop;
+ const GValue *value;
+ gchar buf[512];
+ PropertyBinding *binding;
+
+ panel_return_if_fail (XFCONF_IS_CHANNEL (channel));
+ panel_return_if_fail (G_IS_OBJECT (object));
+ panel_return_if_fail (property_base != NULL && *property_base == '/');
+ panel_return_if_fail (properties != NULL);
+
+ /* get or ref the hash table */
+ if (G_LIKELY (hash_table != NULL))
+ g_hash_table_ref (hash_table);
+ else
+ hash_table = xfconf_channel_get_properties (channel, property_base);
+
+ /* walk the properties array */
+ for (prop = properties; prop->property != NULL; prop++)
+ {
+ /* create a new binding */
+ binding = g_slice_new (PropertyBinding);
+ binding->channel = channel;
+ binding->channel_prop = g_strconcat (property_base, "/", prop->property, NULL);
+ binding->object = object;
+ binding->object_prop = g_strdup (prop->property);
+
+ /* lookup the property value */
+ if (hash_table != NULL)
+ {
+ value = g_hash_table_lookup (hash_table, binding->channel_prop);
+ if (value != NULL)
+ {
+ if (G_LIKELY (G_VALUE_TYPE (value) == prop->type))
+ g_object_set_property (object, prop->property, value);
+ else
+ g_message ("Value types of property \"%s\" do not "
+ "match: channel = %s, property = %s", buf,
+ G_VALUE_TYPE_NAME (value),
+ g_type_name (prop->type));
+ }
+ }
+
+ /* monitor object property changes */
+ g_snprintf (buf, sizeof (buf), "notify::%s", prop->property);
+ g_object_weak_ref (G_OBJECT (object), panel_properties_object_destroyed, binding);
+ g_signal_connect (G_OBJECT (object), buf,
+ G_CALLBACK (panel_properties_object_notify), binding);
+
+ /* monitor channel changes */
+ g_snprintf (buf, sizeof (buf), "property-changed::%s", binding->channel_prop);
+ g_object_weak_ref (G_OBJECT (channel), panel_properties_channel_destroyed, binding);
+ g_signal_connect (G_OBJECT (channel), buf,
+ G_CALLBACK (panel_properties_channel_notify), binding);
+ }
+
+ /* cleanup */
+ if (hash_table != NULL)
+ g_hash_table_unref (hash_table);
+}
diff --git a/libxfce4panel/xfce-panel-convenience.h b/common/panel-xfconf.h
similarity index 51%
copy from libxfce4panel/xfce-panel-convenience.h
copy to common/panel-xfconf.h
index 5c25f5b..7c12732 100644
--- a/libxfce4panel/xfce-panel-convenience.h
+++ b/common/panel-xfconf.h
@@ -1,7 +1,6 @@
/* $Id$ */
/*
- * Copyright (C) 2006-2007 Jasper Huijsmans <jasper at xfce.org>
- * Copyright (C) 2008-2009 Nick Schermer <nick at xfce.org>
+ * Copyright (C) 2009 Nick Schermer <nick at xfce.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,23 +17,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
-#error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
-#endif
+#ifndef __PANEL_XFCONF_H__
+#define __PANEL_XFCONF_H__
-#ifndef __XFCE_PANEL_CONVENIENCE_H__
-#define __XFCE_PANEL_CONVENIENCE_H__
+#include <xfconf/xfconf.h>
-#include <gtk/gtk.h>
+typedef struct _PanelProperty PanelProperty;
+struct _PanelProperty
+{
+ const gchar *property;
+ GType type;
+};
-G_BEGIN_DECLS
+void panel_properties_bind (XfconfChannel *channel,
+ GObject *object,
+ const gchar *property_base,
+ const PanelProperty *properties,
+ GHashTable *hash_table);
-GtkWidget *xfce_panel_create_button (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void panel_properties_unbind (GObject *object);
-GtkWidget *xfce_panel_create_toggle_button (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-gboolean xfce_panel_allow_customization (void);
-
-G_END_DECLS
-
-#endif /* !__XFCE_PANEL_CONVENIENCE_H__ */
+#endif /* !__PANEL_XFCONF_H__ */
More information about the Xfce4-commits
mailing list