[Xfce4-commits] r26786 - in xfconf/trunk: docs/reference/tmpl tests xfconfd

Brian Tarricone kelnos at xfce.org
Mon Apr 7 10:49:10 CEST 2008


Author: kelnos
Date: 2008-04-07 08:49:10 +0000 (Mon, 07 Apr 2008)
New Revision: 26786

Added:
   xfconf/trunk/tests/t-property-changed-signal.c
Modified:
   xfconf/trunk/docs/reference/tmpl/xfconf-backend.sgml
   xfconf/trunk/tests/Makefile.am
   xfconf/trunk/xfconfd/xfconf-backend-perchannel-xml.c
   xfconf/trunk/xfconfd/xfconf-backend.c
   xfconf/trunk/xfconfd/xfconf-backend.h
   xfconf/trunk/xfconfd/xfconf-daemon.c
Log:
make the PropertyChanged signal work


Modified: xfconf/trunk/docs/reference/tmpl/xfconf-backend.sgml
===================================================================
--- xfconf/trunk/docs/reference/tmpl/xfconf-backend.sgml	2008-04-07 08:48:58 UTC (rev 26785)
+++ xfconf/trunk/docs/reference/tmpl/xfconf-backend.sgml	2008-04-07 08:49:10 UTC (rev 26786)
@@ -34,6 +34,7 @@
 @remove: See xfconf_backend_remove().
 @remove_channel: See xfconf_backend_remove_channel().
 @flush: See xfconf_backend_flush().
+ at register_property_changed_func: See xfconf_backend_register_property_changed_func().
 @_xb_reserved0: Reserved for future expansion.
 @_xb_reserved1: Reserved for future expansion.
 @_xb_reserved2: Reserved for future expansion.

Modified: xfconf/trunk/tests/Makefile.am
===================================================================
--- xfconf/trunk/tests/Makefile.am	2008-04-07 08:48:58 UTC (rev 26785)
+++ xfconf/trunk/tests/Makefile.am	2008-04-07 08:49:10 UTC (rev 26786)
@@ -2,13 +2,15 @@
 	t-set-properties.sh \
 	t-has-properties.sh \
 	t-get-properties.sh \
-	t-remove-properties.sh
+	t-remove-properties.sh \
+	t-property-changed-signal.sh
 
 check_PROGRAMS = \
 	t-set-properties \
 	t-has-properties \
 	t-get-properties \
-	t-remove-properties
+	t-remove-properties \
+	t-property-changed-signal
 
 check_SCRIPTS = $(test_scripts)
 
@@ -26,6 +28,7 @@
 t_has_properties_SOURCES = t-has-properties.c tests-common.h
 t_get_properties_SOURCES = t-get-properties.c tests-common.h
 t_remove_properties_SOURCES = t-remove-properties.c tests-common.h
+t_property_changed_signal_SOURCES = t-property-changed-signal.c tests-common.h
 
 %.sh: test-template.sh.in Makefile
 	sed -e 's/@TEST_NAME@/$@/; s/\.sh//;' <$(srcdir)/test-template.sh.in >$@

Added: xfconf/trunk/tests/t-property-changed-signal.c
===================================================================
--- xfconf/trunk/tests/t-property-changed-signal.c	                        (rev 0)
+++ xfconf/trunk/tests/t-property-changed-signal.c	2008-04-07 08:49:10 UTC (rev 26786)
@@ -0,0 +1,73 @@
+/*
+ *  xfconf
+ *
+ *  Copyright (c) 2007 Brian Tarricone <bjt23 at cornell.edu>
+ *
+ *  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; version 2 of the License ONLY.
+ *
+ *  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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "tests-common.h"
+
+typedef struct
+{
+    GMainLoop *mloop;
+    gboolean got_signal;
+} SignalTestData;
+
+static void
+test_signal_changed(XfconfChannel *channel,
+                    const gchar *property,
+                    gpointer user_data)
+{
+    SignalTestData *std = user_data;
+    std->got_signal = TRUE;
+    g_main_loop_quit(std->mloop);
+}
+
+static gboolean
+test_watchdog(gpointer data)
+{
+    SignalTestData *std = data;
+    g_main_loop_quit(std->mloop);
+    return FALSE;
+}
+
+int
+main(int argc,
+     char **argv)
+{
+    XfconfChannel *channel;
+    SignalTestData std = { NULL, FALSE };
+    
+    std.mloop = g_main_loop_new(NULL, FALSE);
+
+    if(!xfconf_tests_start())
+        return 1;
+    
+    channel = xfconf_channel_new(TEST_CHANNEL_NAME);
+    g_signal_connect(G_OBJECT(channel), "property-changed",
+                     G_CALLBACK(test_signal_changed), &std);
+    
+    TEST_OPERATION(xfconf_channel_set_string(channel, test_string_property, test_string));
+    
+    g_timeout_add(1500, test_watchdog, &std);
+    g_main_loop_run(std.mloop);
+
+    g_main_loop_unref(std.mloop);
+    g_object_unref(G_OBJECT(channel));
+    
+    xfconf_tests_end();
+    
+    return std.got_signal ? 0 : 1;
+}

Modified: xfconf/trunk/xfconfd/xfconf-backend-perchannel-xml.c
===================================================================
--- xfconf/trunk/xfconfd/xfconf-backend-perchannel-xml.c	2008-04-07 08:48:58 UTC (rev 26785)
+++ xfconf/trunk/xfconfd/xfconf-backend-perchannel-xml.c	2008-04-07 08:49:10 UTC (rev 26786)
@@ -99,6 +99,9 @@
     
     guint save_id;
     GList *dirty_channels;
+
+    XfconfPropertyChangedFunc prop_changed_func;
+    gpointer prop_changed_data;
 };
 
 typedef struct _XfconfBackendPerchannelXmlClass
@@ -176,6 +179,9 @@
                                                              GError **error);
 static gboolean xfconf_backend_perchannel_xml_flush(XfconfBackend *backend,
                                                     GError **error);
+static void xfconf_backend_perchannel_xml_register_property_changed_func(XfconfBackend *backend,
+                                                                         XfconfPropertyChangedFunc func,
+                                                                         gpointer user_data);
 
 static void xfconf_backend_perchannel_xml_schedule_save(XfconfBackendPerchannelXml *xbpx,
                                                         const gchar *channel);
@@ -255,6 +261,7 @@
     iface->remove = xfconf_backend_perchannel_xml_remove;
     iface->remove_channel = xfconf_backend_perchannel_xml_remove_channel;
     iface->flush = xfconf_backend_perchannel_xml_flush;
+    iface->register_property_changed_func = xfconf_backend_perchannel_xml_register_property_changed_func;
 }
 
 static gboolean
@@ -327,8 +334,16 @@
             g_value_unset(&cur_prop->value);
         g_value_copy(value, g_value_init(&cur_prop->value,
                                          G_VALUE_TYPE(value)));
-    } else
+
+        /* FIXME: this will trigger if the value is replaced by the same
+         * value */
+        if(xbpx->prop_changed_func)
+            xbpx->prop_changed_func(backend, channel, property, xbpx->prop_changed_data);
+    } else {
         xfconf_proptree_add_property(properties, property, value, FALSE);
+        if(xbpx->prop_changed_func)
+            xbpx->prop_changed_func(backend, channel, property, xbpx->prop_changed_data);
+    }
     
     xfconf_backend_perchannel_xml_schedule_save(xbpx, channel);
     
@@ -499,6 +514,9 @@
         }
         return FALSE;
     }
+
+    if(xbpx->prop_changed_func)
+        xbpx->prop_changed_func(backend, channel, property, xbpx->prop_changed_data);
     
     xfconf_backend_perchannel_xml_schedule_save(xbpx, channel);
     
@@ -538,6 +556,9 @@
         return FALSE;
     }
     g_free(filename);
+
+    /* FIXME: do we want to do a PropertyChanged for each property
+     * in the channel?  or should we add a ChannelRemoved signal? */
     
     return TRUE;
 }
@@ -557,8 +578,19 @@
     return TRUE;
 }
 
+static void
+xfconf_backend_perchannel_xml_register_property_changed_func(XfconfBackend *backend,
+                                                             XfconfPropertyChangedFunc func,
+                                                             gpointer user_data)
+{
+    XfconfBackendPerchannelXml *xbpx = XFCONF_BACKEND_PERCHANNEL_XML(backend);
 
+    xbpx->prop_changed_func = func;
+    xbpx->prop_changed_data = user_data;
+}
 
+
+
 static GNode *
 xfconf_proptree_lookup_node(GNode *proptree,
                             const gchar *name)

Modified: xfconf/trunk/xfconfd/xfconf-backend.c
===================================================================
--- xfconf/trunk/xfconfd/xfconf-backend.c	2008-04-07 08:48:58 UTC (rev 26785)
+++ xfconf/trunk/xfconfd/xfconf-backend.c	2008-04-07 08:49:10 UTC (rev 26786)
@@ -309,3 +309,27 @@
     
     return iface->flush(backend, error);
 }
+
+/**
+ * xfconf_backend_register_property_changed_func:
+ * @backend: The #XfconfBackend.
+ * @func: A function of type #XfconfPropertyChangeFunc.
+ * @user_data: Arbitrary caller-supplied data.
+ *
+ * Registers a function to be called when a property changes.  The
+ * backend implementation should keep a pointer to @func and @user_data
+ * and call @func when a property in the configuration store changes.
+ **/
+void
+xfconf_backend_register_property_changed_func(XfconfBackend *backend,
+                                              XfconfPropertyChangedFunc func,
+                                              gpointer user_data)
+{
+    XfconfBackendInterface *iface = XFCONF_BACKEND_GET_INTERFACE(backend);
+
+    g_return_if_fail(iface);
+    if(!iface->register_property_changed_func)
+        return;
+
+    iface->register_property_changed_func(backend, func, user_data);
+}

Modified: xfconf/trunk/xfconfd/xfconf-backend.h
===================================================================
--- xfconf/trunk/xfconfd/xfconf-backend.h	2008-04-07 08:48:58 UTC (rev 26785)
+++ xfconf/trunk/xfconfd/xfconf-backend.h	2008-04-07 08:49:10 UTC (rev 26786)
@@ -52,6 +52,11 @@
 typedef struct _XfconfBackend           XfconfBackend;
 typedef struct _XfconfBackendInterface  XfconfBackendInterface;
 
+typedef void (*XfconfPropertyChangedFunc)(XfconfBackend *backend,
+                                          const gchar *channel,
+                                          const gchar *property,
+                                          gpointer user_data);
+
 struct _XfconfBackendInterface
 {
     GTypeInterface parent;
@@ -93,6 +98,10 @@
     
     gboolean (*flush)(XfconfBackend *backend,
                       GError **error);
+
+    void (*register_property_changed_func)(XfconfBackend *backend,
+                                           XfconfPropertyChangedFunc func,
+                                           gpointer user_data);
     
     /*< reserved for future expansion >*/
     void (*_xb_reserved0)();
@@ -141,6 +150,10 @@
 gboolean xfconf_backend_flush(XfconfBackend *backend,
                               GError **error);
 
+void xfconf_backend_register_property_changed_func(XfconfBackend *backend,
+                                                   XfconfPropertyChangedFunc func,
+                                                   gpointer user_data);
+
 G_END_DECLS
 
 #endif  /* __XFCONF_BACKEND_H__ */

Modified: xfconf/trunk/xfconfd/xfconf-daemon.c
===================================================================
--- xfconf/trunk/xfconfd/xfconf-daemon.c	2008-04-07 08:48:58 UTC (rev 26785)
+++ xfconf/trunk/xfconfd/xfconf-daemon.c	2008-04-07 08:49:10 UTC (rev 26786)
@@ -120,6 +120,7 @@
     GList *l;
     
     for(l = xfconfd->backends; l; l = l->next) {
+        xfconf_backend_register_property_changed_func(l->data, NULL, NULL);
         xfconf_backend_flush(l->data, NULL);
         g_object_unref(l->data);
     }
@@ -133,6 +134,37 @@
 
 
 
+static void
+xfconf_daemon_backend_property_changed(XfconfBackend *backend,
+                                       const gchar *channel,
+                                       const gchar *property,
+                                       gpointer user_data)
+{
+    XfconfDaemon *xfconfd = user_data;
+    DBusGProxy *signal_proxy;
+    DBusMessage *msg;
+
+    /* FIXME: this function needs to be rewritten to not suck.  cache
+     * the DBusGProxy?  is there a better way to emit signals anyway? */
+
+    signal_proxy = dbus_g_proxy_new_for_name(xfconfd->dbus_conn,
+                                             "org.xfce.Xfconf",
+                                             "/org/xfce/Xfconf",
+                                             "org.xfce.Xfconf");
+
+    msg = dbus_message_new_signal("/org/xfce/Xfconf", "org.xfce.Xfconf",
+                                  "PropertyChanged");
+    dbus_message_append_args(msg,
+                             DBUS_TYPE_STRING, &channel,
+                             DBUS_TYPE_STRING, &property,
+                             DBUS_TYPE_INVALID);
+
+    dbus_g_proxy_send(signal_proxy, msg, NULL);
+    
+    g_object_unref(G_OBJECT(signal_proxy));
+    dbus_message_unref(msg);
+}
+
 static gboolean
 xfconf_set_property(XfconfDaemon *xfconfd,
                     const gchar *channel,
@@ -364,7 +396,7 @@
         
         return FALSE;
     }
-    
+
     return TRUE;
 }
 
@@ -384,8 +416,12 @@
                       error1->message);
             g_error_free(error1);
             error1 = NULL;
-        } else
+        } else {
             xfconfd->backends = g_list_prepend(xfconfd->backends, backend);
+            xfconf_backend_register_property_changed_func(backend,
+                                                          xfconf_daemon_backend_property_changed,
+                                                          xfconfd);
+        }
     }
                                            
     if(!xfconfd->backends) {



More information about the Xfce4-commits mailing list