Browse Source

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.
upstream/xfce4-panel-4.10.1
Nick Schermer 13 years ago
parent
commit
074efb989d
  1. 4
      common/Makefile.am
  2. 212
      common/panel-xfconf.c
  3. 40
      common/panel-xfconf.h

4
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:

212
common/panel-xfconf.c

@ -0,0 +1,212 @@
/* $Id$ */
/*
* Copyright (C) 2009 Nick Schermer <nick@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);
}

40
common/panel-xfconf.h

@ -0,0 +1,40 @@
/* $Id$ */
/*
* Copyright (C) 2009 Nick Schermer <nick@xfce.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __PANEL_XFCONF_H__
#define __PANEL_XFCONF_H__
#include <xfconf/xfconf.h>
typedef struct _PanelProperty PanelProperty;
struct _PanelProperty
{
const gchar *property;
GType type;
};
void panel_properties_bind (XfconfChannel *channel,
GObject *object,
const gchar *property_base,
const PanelProperty *properties,
GHashTable *hash_table);
void panel_properties_unbind (GObject *object);
#endif /* !__PANEL_XFCONF_H__ */
Loading…
Cancel
Save