[Xfce4-commits] <xfce4-panel:devel> D-Bus overhaul for the wrapper communication.

Nick Schermer noreply at xfce.org
Thu Nov 19 21:44:02 CET 2009


Updating branch refs/heads/devel
         to 1d725a5eeb756d81b9782f275c073814fdb7eba7 (commit)
       from c228694229d90f882092e56cd04aa68650d5248f (commit)

commit 1d725a5eeb756d81b9782f275c073814fdb7eba7
Author: Nick Schermer <nick at xfce.org>
Date:   Thu Nov 19 21:40:47 2009 +0100

    D-Bus overhaul for the wrapper communication.
    
    We now set a unique path for each wrapper that will
    show up under org.xfce.Panel. This makes it easier to
    understand in the wrapper (no message filtering) and moves
    all the external communication in the panel-plugin-external.c
    code.

 common/panel-builder.h                |    5 +
 common/panel-dbus.h                   |   39 ++--
 panel/Makefile.am                     |    4 +
 panel/panel-dbus-client.c             |    5 +-
 panel/panel-dbus-service-infos.xml    |   43 ----
 panel/panel-dbus-service.c            |  112 +--------
 panel/panel-dbus-service.h            |   11 +-
 panel/panel-marshal.list              |    1 +
 panel/panel-plugin-external-infos.xml |   41 ++++
 panel/panel-plugin-external.c         |  413 ++++++++++++++++++++++++---------
 plugins/actions/actions.c             |    1 +
 plugins/clock/clock.c                 |    1 +
 plugins/launcher/launcher-dialog.c    |    1 +
 plugins/pager/pager.c                 |    1 +
 plugins/separator/separator.c         |    2 +
 plugins/systray/systray.c             |    5 +-
 plugins/tasklist/tasklist.c           |    1 +
 plugins/windowmenu/windowmenu.c       |    1 +
 wrapper/Makefile.am                   |    4 +-
 wrapper/main.c                        |  218 +++++++-----------
 20 files changed, 484 insertions(+), 425 deletions(-)

diff --git a/common/panel-builder.h b/common/panel-builder.h
index e553269..553b800 100644
--- a/common/panel-builder.h
+++ b/common/panel-builder.h
@@ -22,6 +22,11 @@
 #include <gtk/gtk.h>
 #include <libxfce4panel/libxfce4panel.h>
 
+/* Hook to make sure GtkBuilder knows are the XfceTitledDialog object */
+#define PANEL_BUILDER_LINK_4UI \
+  if (xfce_titled_dialog_get_type () == 0) \
+    return;
+
 GtkBuilder *panel_builder_new (XfcePanelPlugin  *panel_plugin,
                                const gchar      *buffer,
                                gsize             length,
diff --git a/common/panel-dbus.h b/common/panel-dbus.h
index 01a0335..453b288 100644
--- a/common/panel-dbus.h
+++ b/common/panel-dbus.h
@@ -19,28 +19,25 @@
 #ifndef __PANEL_DBUS_H__
 #define __PANEL_DBUS_H__
 
-typedef enum _DBusPropertyChanged DBusPropertyChanged;
-
 /* panel dbus names */
-#define PANEL_DBUS_PATH             "/org/xfce/Panel"
-#define PANEL_DBUS_PANEL_INTERFACE  "org.xfce.Panel"
-#define PANEL_DBUS_PLUGIN_INTERFACE "org.xfce.PanelPlugin"
-
-enum _DBusPropertyChanged
-{
-  /* provider iface */
-  PROPERTY_CHANGED_PROVIDER_SIZE = 0,
-  PROPERTY_CHANGED_PROVIDER_ORIENTATION,
-  PROPERTY_CHANGED_PROVIDER_SCREEN_POSITION,
-  PROPERTY_CHANGED_PROVIDER_EMIT_SAVE,
-  PROPERTY_CHANGED_PROVIDER_EMIT_SHOW_CONFIGURE,
-  PROPERTY_CHANGED_PROVIDER_EMIT_SHOW_ABOUT,
-  PROPERTY_CHANGED_PROVIDER_REMOVE,
+#define PANEL_DBUS_NAME              "org.xfce.Panel"
+#define PANEL_DBUS_PATH              "/org/xfce/Panel"
+#define PANEL_DBUS_INTERFACE         PANEL_DBUS_NAME
+#define PANEL_DBUS_WRAPPER_PATH      PANEL_DBUS_PATH "/Wrapper/%d"
+#define PANEL_DBUS_WRAPPER_INTERFACE PANEL_DBUS_INTERFACE ".Wrapper"
 
-  /* wrapper plug */
-  PROPERTY_CHANGED_WRAPPER_BACKGROUND_ALPHA,
-  PROPERTY_CHANGED_WRAPPER_SET_SENSITIVE,
-  PROPERTY_CHANGED_WRAPPER_QUIT
-};
+/* internal signals send over dbus */
+#define SIGNAL_PREFIX                   '_'
+#define SIGNAL_PREFIX_S                 "_"
+#define SIGNAL_SET_SIZE                 SIGNAL_PREFIX_S "a"
+#define SIGNAL_SET_ORIENTATION          SIGNAL_PREFIX_S "b"
+#define SIGNAL_SET_SCREEN_POSITION      SIGNAL_PREFIX_S "c"
+#define SIGNAL_SAVE                     SIGNAL_PREFIX_S "d"
+#define SIGNAL_SHOW_CONFIGURE           SIGNAL_PREFIX_S "e"
+#define SIGNAL_SHOW_ABOUT               SIGNAL_PREFIX_S "f"
+#define SIGNAL_REMOVE                   SIGNAL_PREFIX_S "g"
+#define SIGNAL_WRAPPER_QUIT             SIGNAL_PREFIX_S "h"
+#define SIGNAL_WRAPPER_SET_SENSITIVE    SIGNAL_PREFIX_S "i"
+#define SIGNAL_WRAPPER_BACKGROUND_ALPHA SIGNAL_PREFIX_S "j"
 
 #endif /* !__PANEL_DBUS_H__ */
diff --git a/panel/Makefile.am b/panel/Makefile.am
index 3d07e43..733e06f 100644
--- a/panel/Makefile.am
+++ b/panel/Makefile.am
@@ -17,6 +17,7 @@ xfce4_panel_built_sources = \
 	panel-dbus-client-infos.h \
 	panel-marshal.h \
 	panel-marshal.c \
+	panel-plugin-external-infos.h \
 	panel-preferences-dialog-ui.h
 
 xfce4_panel_SOURCES = \
@@ -84,6 +85,9 @@ panel-dbus-service-infos.h: $(srcdir)/panel-dbus-service-infos.xml Makefile
 panel-dbus-client-infos.h: $(srcdir)/panel-dbus-service-infos.xml Makefile
 	$(AM_V_GEN) dbus-binding-tool --mode=glib-client $< > $@
 
+panel-plugin-external-infos.h: $(srcdir)/panel-plugin-external-infos.xml Makefile
+	$(AM_V_GEN) dbus-binding-tool --prefix=panel_plugin_external --mode=glib-server $< > $@
+
 panel-preferences-dialog-ui.h: $(srcdir)/panel-preferences-dialog.ui Makefile
 	$(AM_V_GEN) exo-csource --static --strip-comments --strip-content --name=panel_preferences_dialog_ui $< >$@
 
diff --git a/panel/panel-dbus-client.c b/panel/panel-dbus-client.c
index 81ffa0b..99d8396 100644
--- a/panel/panel-dbus-client.c
+++ b/panel/panel-dbus-client.c
@@ -30,7 +30,6 @@
 #include <panel/panel-dbus-client.h>
 #include <panel/panel-dbus-service.h>
 
-#define DBUS_GLIB_CLIENT_WRAPPERS_org_xfce_PanelPlugin /* hack to exclude the wrapper client code */
 #include <panel/panel-dbus-client-infos.h>
 
 
@@ -48,9 +47,9 @@ panel_dbus_client_get_proxy (GError **error)
 
   /* get the proxy */
   dbus_proxy = dbus_g_proxy_new_for_name_owner (dbus_connection,
-                                                PANEL_DBUS_PANEL_INTERFACE,
+                                                PANEL_DBUS_NAME,
                                                 PANEL_DBUS_PATH,
-                                                PANEL_DBUS_PANEL_INTERFACE,
+                                                PANEL_DBUS_INTERFACE,
                                                 error);
 
   return dbus_proxy;
diff --git a/panel/panel-dbus-service-infos.xml b/panel/panel-dbus-service-infos.xml
index f9b2d77..5a9dd59 100644
--- a/panel/panel-dbus-service-infos.xml
+++ b/panel/panel-dbus-service-infos.xml
@@ -63,47 +63,4 @@
       <arg name="restart" direction="in" type="b" />
     </method>
   </interface>
-
-  <!--
-    org.xfce.PanelPlugin
-
-    The panel plugin specific interface, used for communication
-    between the panel and the wrapper. This interface should not
-    be implemented by any other application.
-
-    This interface is also subject to change. So, unless you know
-    what you are doing, don't use it.
-  -->
-  <interface name="org.xfce.PanelPlugin">
-    <annotation name="org.freedesktop.DBus.GLib.CSymbol"
-                value="panel_dbus_service_plugin" />
-    <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol"
-                value="wrapper_dbus_client" />
-
-    <!--
-      Emitted when a panel property changed, monitored by the wrapper. This
-      is emitted to all plugins but they will filter out their property
-      based on the @plugin-id. The @property is an enum from DBusPropertyChanged,
-      see common/panel-dbus.h.
-
-      Panel -> Wrapper -> XfcePanelPluginProvider
-    -->
-    <signal name="PropertyChanged">
-      <arg name="plugin_id" type="i" />
-      <arg name="property" type="i" />
-      <arg name="value" type="v" />
-    </signal>
-
-    <!--
-      This method is called from the wrapper and notifies the panel about an
-      action that should be performed. the @signal is an enum from
-      XfcePanelPluginProviderSignal, see libxfce4panel/xfce-panel-plugin-provider.h.
-
-      XfcePanelPluginProvider -> Wrapper -> Panel
-    -->
-    <method name="ProviderSignal">
-      <arg name="plugin_id" direction="in" type="i" />
-      <arg name="signal" direction="in" type="i" />
-    </method>
-  </interface>
 </node>
diff --git a/panel/panel-dbus-service.c b/panel/panel-dbus-service.c
index 9ec4d18..7435a1c 100644
--- a/panel/panel-dbus-service.c
+++ b/panel/panel-dbus-service.c
@@ -58,10 +58,6 @@ static gboolean  panel_dbus_service_add_new_item               (PanelDBusService
 static gboolean  panel_dbus_service_terminate                  (PanelDBusService  *service,
                                                                 gboolean           restart,
                                                                 GError           **error);
-static gboolean  panel_dbus_service_plugin_provider_signal     (PanelDBusService  *service,
-                                                                gint               plugin_id,
-                                                                gint               provider_signal,
-                                                                GError            *error);
 
 
 
@@ -70,12 +66,6 @@ static gboolean  panel_dbus_service_plugin_provider_signal     (PanelDBusService
 
 
 
-enum
-{
-  PROPERTY_CHANGED,
-  LAST_SIGNAL
-};
-
 struct _PanelDBusServiceClass
 {
   GObjectClass __parent__;
@@ -92,7 +82,6 @@ struct _PanelDBusService
 
 
 static gboolean dbus_exit_restart = FALSE;
-static guint    dbus_service_signals[LAST_SIGNAL];
 
 
 
@@ -108,23 +97,8 @@ panel_dbus_service_class_init (PanelDBusServiceClass *klass)
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = panel_dbus_service_finalize;
 
-  /**
-   * Emitted when an external plugin property should be updated. The
-   * wrapper connects to this dbus signal.
-   **/
-  dbus_service_signals[PROPERTY_CHANGED] =
-    g_signal_new (g_intern_static_string ("property-changed"),
-                  G_TYPE_FROM_CLASS (gobject_class),
-                  G_SIGNAL_RUN_LAST,
-                  0, NULL, NULL,
-                  panel_marshal_VOID__INT_INT_BOXED,
-                  G_TYPE_NONE, 3,
-                  G_TYPE_INT,
-                  G_TYPE_INT,
-                  G_TYPE_VALUE);
-
-  /* install the d-bus info for our class */
-  dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), &dbus_glib_panel_dbus_service_object_info);
+  dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+      &dbus_glib_panel_dbus_service_object_info);
 }
 
 
@@ -135,24 +109,16 @@ panel_dbus_service_init (PanelDBusService *service)
   GError         *error = NULL;
   DBusConnection *connection;
 
-  /* TODO implement derror handing in the dbus_bus_request_name functions */
-
-  /* try to connect to the session bus */
   service->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-
   if (G_LIKELY (service->connection != NULL))
     {
-      /* get the connection */
+      /* TODO handle error */
       connection = dbus_g_connection_get_connection (service->connection);
+      dbus_bus_request_name (connection, PANEL_DBUS_NAME, 0, NULL);
 
-      /* request the org.xfce.Panel name */
-      dbus_bus_request_name (connection, PANEL_DBUS_PANEL_INTERFACE, 0, NULL);
-
-      /* request the org.xfce.PanelPlugin name */
-      dbus_bus_request_name (connection, PANEL_DBUS_PLUGIN_INTERFACE, 0, NULL);
-
-      /* register the /org/xfce/Panel object */
-      dbus_g_connection_register_g_object (service->connection, PANEL_DBUS_PATH,
+      /* register this object */
+      dbus_g_connection_register_g_object (service->connection,
+                                           PANEL_DBUS_PATH,
                                            G_OBJECT (service));
     }
   else
@@ -175,16 +141,9 @@ panel_dbus_service_finalize (GObject *object)
 
   if (G_LIKELY (service->connection != NULL))
     {
-      /* get the connection */
-      connection = dbus_g_connection_get_connection (service->connection);
-
       /* release the org.xfce.Panel name */
-      dbus_bus_release_name (connection, PANEL_DBUS_PANEL_INTERFACE, NULL);
-
-      /* release the org.xfce.PanelPlugin name */
-      dbus_bus_release_name (connection, PANEL_DBUS_PLUGIN_INTERFACE, NULL);
-
-      /* flush the connection */
+      connection = dbus_g_connection_get_connection (service->connection);
+      dbus_bus_release_name (connection, PANEL_DBUS_NAME, NULL);
       dbus_g_connection_flush (service->connection);
 
       /* release the connection */
@@ -298,36 +257,6 @@ panel_dbus_service_terminate (PanelDBusService  *service,
 
 
 
-static gboolean
-panel_dbus_service_plugin_provider_signal (PanelDBusService *service,
-                                           gint              plugin_id,
-                                           gint              provider_signal,
-                                           GError           *error)
-{
-  PanelModuleFactory *factory;
-  GtkWidget          *provider;
-
-  panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
-  panel_return_val_if_fail (plugin_id != -1, FALSE);
-
-  /* get the module factory */
-  factory = panel_module_factory_get ();
-
-  /* get the plugin from the factory */
-  provider = panel_module_factory_get_plugin (factory, plugin_id);
-
-  /* emit the signal for the local plugin provider */
-  if (G_LIKELY (provider))
-    xfce_panel_plugin_provider_emit_signal (XFCE_PANEL_PLUGIN_PROVIDER (provider), provider_signal);
-
-  /* release the factory */
-  g_object_unref (G_OBJECT (factory));
-
-  return TRUE;
-}
-
-
-
 PanelDBusService *
 panel_dbus_service_get (void)
 {
@@ -349,29 +278,6 @@ panel_dbus_service_get (void)
 
 
 void
-panel_dbus_service_plugin_property_changed (gint                 plugin_id,
-                                            DBusPropertyChanged  property,
-                                            const GValue        *value)
-{
-  PanelDBusService *service;
-
-  panel_return_if_fail (plugin_id != -1);
-  panel_return_if_fail (value && G_TYPE_CHECK_VALUE (value));
-
-  /* get the dbus service */
-  service = panel_dbus_service_get ();
-
-  /* emit the signal */
-  g_signal_emit (G_OBJECT (service), dbus_service_signals[PROPERTY_CHANGED],
-                 0, plugin_id, property, value);
-
-  /* release */
-  g_object_unref (G_OBJECT (service));
-}
-
-
-
-void
 panel_dbus_service_exit_panel (gboolean restart)
 {
   XfceSMClient *sm_client;
diff --git a/panel/panel-dbus-service.h b/panel/panel-dbus-service.h
index a48bc21..da8c14a 100644
--- a/panel/panel-dbus-service.h
+++ b/panel/panel-dbus-service.h
@@ -34,16 +34,13 @@ typedef struct _PanelDBusService      PanelDBusService;
 
 
 
-GType               panel_dbus_service_get_type                (void) G_GNUC_CONST;
+GType               panel_dbus_service_get_type    (void) G_GNUC_CONST;
 
-PanelDBusService   *panel_dbus_service_get                     (void);
+PanelDBusService   *panel_dbus_service_get         (void);
 
-void                panel_dbus_service_plugin_property_changed (gint                 plugin_id,
-                                                                DBusPropertyChanged  property,
-                                                                const GValue        *value);
+void                panel_dbus_service_exit_panel  (gboolean restart);
 
-void                panel_dbus_service_exit_panel              (gboolean             restart);
-gboolean            panel_dbus_service_get_restart             (void);
+gboolean            panel_dbus_service_get_restart (void);
 
 G_END_DECLS
 
diff --git a/panel/panel-marshal.list b/panel/panel-marshal.list
index 1e5ab84..5eeace3 100644
--- a/panel/panel-marshal.list
+++ b/panel/panel-marshal.list
@@ -1 +1,2 @@
 VOID:INT,INT,BOXED
+VOID:STRING,BOXED,UINT
diff --git a/panel/panel-plugin-external-infos.xml b/panel/panel-plugin-external-infos.xml
new file mode 100644
index 0000000..6012a4e
--- /dev/null
+++ b/panel/panel-plugin-external-infos.xml
@@ -0,0 +1,41 @@
+<node name="/org/xfce/Panel/Wrapper">
+  <!--
+    org.xfce.Panel.Wrapper
+  -->
+  <interface name="org.xfce.Panel.Wrapper">
+    <annotation name="org.freedesktop.DBus.GLib.CSymbol"
+                value="panel_plugin_external_dbus" />
+    <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol"
+                value="wrapper_dbus" />
+
+    <!--
+      property : Name of the property to set on the wrapper. This is used
+                 for both panel values (no reply required) and plugin
+                 event (require a reply from the plugin).
+      value    : GValue with the value for the property.
+      reply_id : 0 if no reply is needed, if bigger then 0, the id to
+                 return together with the Reply method.
+    -->
+    <signal name="Set">
+      <arg name="property" type="s" />
+      <arg name="value" type="v" />
+      <arg name="reply_id" type="u" />
+    </signal>
+
+    <!--
+      replay_id : The reply id given during the request.
+      value     : The return value for the reply.
+    -->
+    <method name="Reply">
+      <arg name="reply_id" type="u" />
+      <arg name="value" type="v" />
+    </method>
+
+    <!--
+      signal : A provider signal from XfcePanelPluginProviderSignal.
+    -->
+    <method name="ProviderSignal">
+      <arg name="signal" type="u" />
+    </method>
+  </interface>
+</node>
diff --git a/panel/panel-plugin-external.c b/panel/panel-plugin-external.c
index 49671f3..353c6ac 100644
--- a/panel/panel-plugin-external.c
+++ b/panel/panel-plugin-external.c
@@ -38,10 +38,10 @@
 #include <libxfce4panel/libxfce4panel.h>
 #include <libxfce4panel/xfce-panel-plugin-provider.h>
 
+#include <panel/panel-marshal.h>
 #include <panel/panel-module.h>
 #include <panel/panel-plugin-external.h>
 #include <panel/panel-window.h>
-#include <panel/panel-dbus-service.h>
 
 /* Number of automatic plugin restarts before the
  * panel asks the users what to do. This code is
@@ -54,14 +54,39 @@
 
 
 
+typedef struct _QueuedData QueuedData;
+
+
+
 static void         panel_plugin_external_provider_init         (XfcePanelPluginProviderIface    *iface);
+static GObject     *panel_plugin_external_constructor           (GType                            type,
+                                                                 guint                            n_construct_params,
+                                                                 GObjectConstructParam           *construct_params);
 static void         panel_plugin_external_finalize              (GObject                         *object);
+static void         panel_plugin_external_get_property          (GObject                         *object,
+                                                                 guint                            prop_id,
+                                                                 GValue                          *value,
+                                                                 GParamSpec                      *pspec);
+static void         panel_plugin_external_set_property          (GObject                         *object,
+                                                                 guint                            prop_id,
+                                                                 const GValue                    *value,
+                                                                 GParamSpec                      *pspec);
 static void         panel_plugin_external_realize               (GtkWidget                       *widget);
 static void         panel_plugin_external_unrealize             (GtkWidget                       *widget);
 static gboolean     panel_plugin_external_plug_removed          (GtkSocket                       *socket);
 static void         panel_plugin_external_plug_added            (GtkSocket                       *socket);
-static void         panel_plugin_external_provider_signal       (XfcePanelPluginProvider         *provider,
-                                                                 XfcePanelPluginProviderSignal    signal);
+static gboolean     panel_plugin_external_dbus_reply            (PanelPluginExternal             *external,
+                                                                 guint                            reply_id,
+                                                                 const GValue                    *value,
+                                                                 GError                         **error);
+static gboolean     panel_plugin_external_dbus_provider_signal  (PanelPluginExternal             *external,
+                                                                 XfcePanelPluginProviderSignal    provider_signal,
+                                                                 GError                         **error);
+static void         panel_plugin_external_dbus_set              (PanelPluginExternal             *external,
+                                                                 const gchar                     *property,
+                                                                 const GValue                    *value);
+static void         panel_plugin_external_dbus_set_noop         (PanelPluginExternal             *external,
+                                                                 const gchar                     *property);
 static const gchar *panel_plugin_external_get_name              (XfcePanelPluginProvider         *provider);
 static gint         panel_plugin_external_get_unique_id         (XfcePanelPluginProvider         *provider);
 static void         panel_plugin_external_set_size              (XfcePanelPluginProvider         *provider,
@@ -77,15 +102,17 @@ static gboolean     panel_plugin_external_get_show_about        (XfcePanelPlugin
 static void         panel_plugin_external_show_about            (XfcePanelPluginProvider         *provider);
 static void         panel_plugin_external_remove                (XfcePanelPluginProvider         *provider);
 static void         panel_plugin_external_set_sensitive         (PanelPluginExternal             *external);
-static void         panel_plugin_external_set_property          (PanelPluginExternal             *external,
-                                                                 DBusPropertyChanged              property,
-                                                                 const GValue                    *value);
-static void         panel_plugin_external_set_property_noop     (PanelPluginExternal             *external,
-                                                                 DBusPropertyChanged              property);
 static void         panel_plugin_external_child_watch           (GPid                             pid,
                                                                  gint                             status,
                                                                  gpointer                         user_data);
 static void         panel_plugin_external_child_watch_destroyed (gpointer                         user_data);
+static void         panel_plugin_external_queue_data_free       (QueuedData                      *data);
+
+
+
+/* include the dbus glue generated by dbus-binding-tool */
+#include <panel/panel-plugin-external-infos.h>
+
 
 
 struct _PanelPluginExternalClass
@@ -124,12 +151,29 @@ struct _PanelPluginExternal
   guint             watch_id;
 };
 
-typedef struct
+struct _QueuedData
 {
-  DBusPropertyChanged property;
-  GValue              value;
-}
-QueuedData;
+  gchar  *property;
+  GValue  value;
+};
+
+enum
+{
+  PROP_0,
+  PROP_MODULE,
+  PROP_UNIQUE_ID,
+  PROP_ARGUMENTS
+};
+
+enum
+{
+  SET,
+  LAST_SIGNAL
+};
+
+
+
+static guint external_signals[LAST_SIGNAL];
 
 
 
@@ -146,7 +190,10 @@ panel_plugin_external_class_init (PanelPluginExternalClass *klass)
   GtkSocketClass *gtksocket_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->constructor = panel_plugin_external_constructor;
   gobject_class->finalize = panel_plugin_external_finalize;
+  gobject_class->set_property = panel_plugin_external_set_property;
+  gobject_class->get_property = panel_plugin_external_get_property;
 
   gtkwidget_class = GTK_WIDGET_CLASS (klass);
   gtkwidget_class->realize = panel_plugin_external_realize;
@@ -155,6 +202,44 @@ panel_plugin_external_class_init (PanelPluginExternalClass *klass)
   gtksocket_class = GTK_SOCKET_CLASS (klass);
   gtksocket_class->plug_removed = panel_plugin_external_plug_removed;
   gtksocket_class->plug_added = panel_plugin_external_plug_added;
+
+  external_signals[SET] =
+    g_signal_new (g_intern_static_string ("set"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  panel_marshal_VOID__STRING_BOXED_UINT,
+                  G_TYPE_NONE, 3,
+                  G_TYPE_STRING,
+                  G_TYPE_VALUE,
+                  G_TYPE_UINT);
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_UNIQUE_ID,
+                                   g_param_spec_int ("unique-id", NULL, NULL,
+                                                     -1, G_MAXINT, -1,
+                                                     G_PARAM_READWRITE
+                                                     | G_PARAM_STATIC_STRINGS
+                                                     | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MODULE,
+                                   g_param_spec_object ("module", NULL, NULL,
+                                                        PANEL_TYPE_MODULE,
+                                                        G_PARAM_READWRITE
+                                                        | G_PARAM_STATIC_STRINGS
+                                                        | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_ARGUMENTS,
+                                   g_param_spec_boxed ("arguments", NULL, NULL,
+                                                       G_TYPE_STRV,
+                                                       G_PARAM_READWRITE
+                                                       | G_PARAM_STATIC_STRINGS
+                                                       | G_PARAM_CONSTRUCT_ONLY));
+
+  dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+      &dbus_glib_panel_plugin_external_object_info);
 }
 
 
@@ -173,7 +258,8 @@ panel_plugin_external_init (PanelPluginExternal *external)
   external->show_about = FALSE;
 
   /* signal to pass gtk_widget_set_sensitive() changes to the remote window */
-  g_signal_connect (G_OBJECT (external), "notify::sensitive", G_CALLBACK (panel_plugin_external_set_sensitive), NULL);
+  g_signal_connect (G_OBJECT (external), "notify::sensitive",
+      G_CALLBACK (panel_plugin_external_set_sensitive), NULL);
 }
 
 
@@ -181,7 +267,7 @@ panel_plugin_external_init (PanelPluginExternal *external)
 static void
 panel_plugin_external_provider_init (XfcePanelPluginProviderIface *iface)
 {
-  iface->provider_signal = panel_plugin_external_provider_signal;
+  iface->provider_signal = NULL;
   iface->get_name = panel_plugin_external_get_name;
   iface->get_unique_id = panel_plugin_external_get_unique_id;
   iface->set_size = panel_plugin_external_set_size;
@@ -197,12 +283,44 @@ panel_plugin_external_provider_init (XfcePanelPluginProviderIface *iface)
 
 
 
+static GObject *
+panel_plugin_external_constructor (GType                  type,
+                                   guint                  n_construct_params,
+                                   GObjectConstructParam *construct_params)
+{
+  GObject         *object;
+  gchar           *path;
+  DBusGConnection *connection;
+  GError          *error = NULL;
+
+  object = G_OBJECT_CLASS (panel_plugin_external_parent_class)->constructor (type, n_construct_params, construct_params);
+
+  /* register the object */
+  connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+  if (G_LIKELY (connection != NULL))
+    {
+      panel_return_val_if_fail (PANEL_PLUGIN_EXTERNAL (object)->unique_id != -1, NULL);
+      path = g_strdup_printf (PANEL_DBUS_WRAPPER_PATH, PANEL_PLUGIN_EXTERNAL (object)->unique_id);
+      dbus_g_connection_register_g_object (connection, path, object);
+      g_free (path);
+
+      dbus_g_connection_unref (connection);
+    }
+  else
+    {
+      g_critical ("Failed to get D-Bus session bus: %s", error->message);
+      g_error_free (error);
+    }
+
+  return object;
+}
+
+
+
 static void
 panel_plugin_external_finalize (GObject *object)
 {
   PanelPluginExternal *external = PANEL_PLUGIN_EXTERNAL (object);
-  GSList              *li;
-  QueuedData          *data;
 
   if (external->watch_id != 0)
     {
@@ -211,19 +329,15 @@ panel_plugin_external_finalize (GObject *object)
       g_child_watch_add (external->pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
     }
 
-  /* cleanup */
-  g_strfreev (external->arguments);
-
   /* free the queue */
-  for (li = external->dbus_queue; li != NULL; li = li->next)
+  if (G_UNLIKELY (external->dbus_queue != NULL))
     {
-      data = li->data;
-      g_value_unset (&data->value);
-      g_slice_free (QueuedData, data);
+      g_slist_foreach (external->dbus_queue, (GFunc) panel_plugin_external_queue_data_free, NULL);
+      g_slist_free (external->dbus_queue);
     }
-  g_slist_free (external->dbus_queue);
 
-  /* release the module */
+  g_strfreev (external->arguments);
+
   g_object_unref (G_OBJECT (external->module));
 
   (*G_OBJECT_CLASS (panel_plugin_external_parent_class)->finalize) (object);
@@ -232,6 +346,66 @@ panel_plugin_external_finalize (GObject *object)
 
 
 static void
+panel_plugin_external_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  PanelPluginExternal *external = PANEL_PLUGIN_EXTERNAL (object);
+
+  switch (prop_id)
+    {
+      case PROP_UNIQUE_ID:
+        g_value_set_int (value, external->unique_id);
+        break;
+
+      case PROP_ARGUMENTS:
+        g_value_set_boxed (value, external->arguments);
+        break;
+
+      case PROP_MODULE:
+        g_value_set_object (value, external->module);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+panel_plugin_external_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  PanelPluginExternal *external = PANEL_PLUGIN_EXTERNAL (object);
+
+  switch (prop_id)
+    {
+      case PROP_UNIQUE_ID:
+        external->unique_id = g_value_get_int (value);
+        break;
+
+      case PROP_ARGUMENTS:
+        external->arguments = g_value_dup_boxed (value);
+        break;
+
+      case PROP_MODULE:
+        external->module = g_value_dup_object (value);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
 panel_plugin_external_realize (GtkWidget *widget)
 {
   PanelPluginExternal  *external = PANEL_PLUGIN_EXTERNAL (widget);
@@ -254,10 +428,8 @@ panel_plugin_external_realize (GtkWidget *widget)
   if (G_UNLIKELY (external->arguments != NULL))
     argc += g_strv_length (external->arguments);
 
-  /* allocate argv */
-  argv = g_new0 (gchar *, argc);
-
   /* setup the basic argv */
+  argv = g_new0 (gchar *, argc);
   argv[0]  = (gchar *) LIBEXECDIR G_DIR_SEPARATOR_S "wrapper";
   argv[1]  = (gchar *) "-n";
   argv[2]  = (gchar *) panel_module_get_name (external->module);
@@ -317,9 +489,8 @@ panel_plugin_external_unrealize (GtkWidget *widget)
   g_value_set_boolean (&value, FALSE);
 
   /* send directly (don't queue here) */
-  panel_dbus_service_plugin_property_changed (external->unique_id,
-                                              PROPERTY_CHANGED_WRAPPER_QUIT,
-                                              &value);
+  g_signal_emit (G_OBJECT (external), external_signals[SET], 0,
+                 SIGNAL_WRAPPER_QUIT, &value, 0);
 
   /* unset */
   g_value_unset (&value);
@@ -365,7 +536,7 @@ panel_plugin_external_plug_removed (GtkSocket *socket)
       dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
                                        GTK_DIALOG_DESTROY_WITH_PARENT,
                                        GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
-                                       _("Plugin '%s' unexpectedly left the building, do you want to restart it?"),
+                                       _("Plugin \"%s\" unexpectedly left the building, do you want to restart it?"),
                                        panel_module_get_display_name (external->module));
       gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("If you press Execute "
                                                 "the panel will try to restart the plugin otherwise it "
@@ -443,11 +614,11 @@ panel_plugin_external_plug_added (GtkSocket *socket)
       for (li = external->dbus_queue; li != NULL; li = li->next)
         {
           data = li->data;
-          panel_dbus_service_plugin_property_changed (external->unique_id,
-                                                      data->property,
-                                                      &data->value);
-          g_value_unset (&data->value);
-          g_slice_free (QueuedData, data);
+
+          g_signal_emit (G_OBJECT (external), external_signals[SET], 0,
+                         data->property, &data->value, 0);
+
+          panel_plugin_external_queue_data_free (data);
         }
 
       /* free the list */
@@ -458,17 +629,28 @@ panel_plugin_external_plug_added (GtkSocket *socket)
 
 
 
-static void
-panel_plugin_external_provider_signal (XfcePanelPluginProvider       *provider,
-                                       XfcePanelPluginProviderSignal  provider_signal)
+static gboolean
+panel_plugin_external_dbus_reply (PanelPluginExternal  *external,
+                                  guint                 reply_id,
+                                  const GValue         *value,
+                                  GError              **error)
 {
-  PanelPluginExternal *external = PANEL_PLUGIN_EXTERNAL (provider);
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external), FALSE);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (external), FALSE);
+
+  return TRUE;
+}
 
-  panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider));
-  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
-  /* we handle some signals here, everything else is handled in
-   * panel-application */
+
+static gboolean
+panel_plugin_external_dbus_provider_signal (PanelPluginExternal            *external,
+                                            XfcePanelPluginProviderSignal   provider_signal,
+                                            GError                        **error)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external), FALSE);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (external), FALSE);
+
   switch (provider_signal)
     {
       case PROVIDER_SIGNAL_REMOVE_PLUGIN:
@@ -488,39 +670,21 @@ panel_plugin_external_provider_signal (XfcePanelPluginProvider       *provider,
         break;
 
       default:
+        /* other signals are handled in panel-applications.c */
+        xfce_panel_plugin_provider_emit_signal (XFCE_PANEL_PLUGIN_PROVIDER (external),
+                                                provider_signal);
         break;
     }
-}
-
-
-
-
-static const gchar *
-panel_plugin_external_get_name (XfcePanelPluginProvider *provider)
-{
-  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider), NULL);
-  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), NULL);
-
-  return panel_module_get_name (PANEL_PLUGIN_EXTERNAL (provider)->module);
-}
-
-
-
-static gint
-panel_plugin_external_get_unique_id (XfcePanelPluginProvider *provider)
-{
-  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider), -1);
-  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), -1);
 
-  return PANEL_PLUGIN_EXTERNAL (provider)->unique_id;
+  return TRUE;
 }
 
 
 
 static void
-panel_plugin_external_set_property (PanelPluginExternal *external,
-                                    DBusPropertyChanged  property,
-                                    const GValue        *value)
+panel_plugin_external_dbus_set (PanelPluginExternal *external,
+                                const gchar         *property,
+                                const GValue        *value)
 {
   QueuedData *data;
 
@@ -530,14 +694,14 @@ panel_plugin_external_set_property (PanelPluginExternal *external,
   if (G_LIKELY (external->plug_embedded))
     {
       /* directly send the new property */
-      panel_dbus_service_plugin_property_changed (external->unique_id,
-                                                  property, value);
+      g_signal_emit (G_OBJECT (external), external_signals[SET], 0,
+                     property, value, 0);
     }
   else
     {
       /* queue the property */
-      data = g_slice_new (QueuedData);
-      data->property = property;
+      data = g_slice_new0 (QueuedData);
+      data->property = g_strdup (property);
       g_value_init (&data->value, G_VALUE_TYPE (value));
       g_value_copy (value, &data->value);
 
@@ -549,8 +713,8 @@ panel_plugin_external_set_property (PanelPluginExternal *external,
 
 
 static void
-panel_plugin_external_set_property_noop (PanelPluginExternal *external,
-                                         DBusPropertyChanged  property)
+panel_plugin_external_dbus_set_noop (PanelPluginExternal *external,
+                                     const gchar         *property)
 {
   GValue value = { 0, };
 
@@ -561,7 +725,7 @@ panel_plugin_external_set_property_noop (PanelPluginExternal *external,
   g_value_set_boolean (&value, FALSE);
 
   /* send the value */
-  panel_plugin_external_set_property (external, property, &value);
+  panel_plugin_external_dbus_set (external, property, &value);
 
   /* unset */
   g_value_unset (&value);
@@ -569,6 +733,28 @@ panel_plugin_external_set_property_noop (PanelPluginExternal *external,
 
 
 
+static const gchar *
+panel_plugin_external_get_name (XfcePanelPluginProvider *provider)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider), NULL);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), NULL);
+
+  return panel_module_get_name (PANEL_PLUGIN_EXTERNAL (provider)->module);
+}
+
+
+
+static gint
+panel_plugin_external_get_unique_id (XfcePanelPluginProvider *provider)
+{
+  panel_return_val_if_fail (PANEL_IS_PLUGIN_EXTERNAL (provider), -1);
+  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), -1);
+
+  return PANEL_PLUGIN_EXTERNAL (provider)->unique_id;
+}
+
+
+
 static void
 panel_plugin_external_set_size (XfcePanelPluginProvider *provider,
                                 gint                     size)
@@ -583,9 +769,9 @@ panel_plugin_external_set_size (XfcePanelPluginProvider *provider,
   g_value_set_int (&value, size);
 
   /* send the value */
-  panel_plugin_external_set_property (PANEL_PLUGIN_EXTERNAL (provider),
-                                      PROPERTY_CHANGED_PROVIDER_SIZE,
-                                      &value);
+  panel_plugin_external_dbus_set (PANEL_PLUGIN_EXTERNAL (provider),
+                                  SIGNAL_SET_SIZE,
+                                  &value);
 
   /* unset */
   g_value_unset (&value);
@@ -607,9 +793,9 @@ panel_plugin_external_set_orientation (XfcePanelPluginProvider *provider,
   g_value_set_uint (&value, orientation);
 
   /* send the value */
-  panel_plugin_external_set_property (PANEL_PLUGIN_EXTERNAL (provider),
-                                      PROPERTY_CHANGED_PROVIDER_ORIENTATION,
-                                      &value);
+  panel_plugin_external_dbus_set (PANEL_PLUGIN_EXTERNAL (provider),
+                                  SIGNAL_SET_ORIENTATION,
+                                  &value);
 
   /* unset */
   g_value_unset (&value);
@@ -631,9 +817,9 @@ panel_plugin_external_set_screen_position (XfcePanelPluginProvider *provider,
   g_value_set_uint (&value, screen_position);
 
   /* send the value */
-  panel_plugin_external_set_property (PANEL_PLUGIN_EXTERNAL (provider),
-                                      PROPERTY_CHANGED_PROVIDER_SCREEN_POSITION,
-                                      &value);
+  panel_plugin_external_dbus_set (PANEL_PLUGIN_EXTERNAL (provider),
+                                  SIGNAL_SET_SCREEN_POSITION,
+                                  &value);
 
   /* unset */
   g_value_unset (&value);
@@ -648,8 +834,8 @@ panel_plugin_external_save (XfcePanelPluginProvider *provider)
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
   /* send signal to wrapper */
-  panel_plugin_external_set_property_noop (PANEL_PLUGIN_EXTERNAL (provider),
-                                           PROPERTY_CHANGED_PROVIDER_EMIT_SAVE);
+  panel_plugin_external_dbus_set_noop (PANEL_PLUGIN_EXTERNAL (provider),
+                                       SIGNAL_SAVE);
 }
 
 
@@ -672,8 +858,8 @@ panel_plugin_external_show_configure (XfcePanelPluginProvider *provider)
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
   /* send signal to wrapper */
-  panel_plugin_external_set_property_noop (PANEL_PLUGIN_EXTERNAL (provider),
-                                           PROPERTY_CHANGED_PROVIDER_EMIT_SHOW_CONFIGURE);
+  panel_plugin_external_dbus_set_noop (PANEL_PLUGIN_EXTERNAL (provider),
+                                       SIGNAL_SHOW_CONFIGURE);
 }
 
 
@@ -696,8 +882,8 @@ panel_plugin_external_show_about (XfcePanelPluginProvider *provider)
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
   /* send signal to wrapper */
-  panel_plugin_external_set_property_noop (PANEL_PLUGIN_EXTERNAL (provider),
-                                           PROPERTY_CHANGED_PROVIDER_EMIT_SHOW_ABOUT);
+  panel_plugin_external_dbus_set_noop (PANEL_PLUGIN_EXTERNAL (provider),
+                                       SIGNAL_SHOW_ABOUT);
 }
 
 
@@ -709,8 +895,8 @@ panel_plugin_external_remove (XfcePanelPluginProvider *provider)
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
 
   /* send signal to wrapper */
-  panel_plugin_external_set_property_noop (PANEL_PLUGIN_EXTERNAL (provider),
-                                           PROPERTY_CHANGED_PROVIDER_REMOVE);
+  panel_plugin_external_dbus_set_noop (PANEL_PLUGIN_EXTERNAL (provider),
+                                       SIGNAL_REMOVE);
 }
 
 
@@ -727,9 +913,9 @@ panel_plugin_external_set_sensitive (PanelPluginExternal *external)
   g_value_set_boolean (&value, GTK_WIDGET_IS_SENSITIVE (external));
 
   /* send message */
-  panel_plugin_external_set_property (external,
-                                      PROPERTY_CHANGED_WRAPPER_SET_SENSITIVE,
-                                      &value);
+  panel_plugin_external_dbus_set (external,
+                                  SIGNAL_WRAPPER_SET_SENSITIVE,
+                                  &value);
 
   /* unset */
   g_value_unset (&value);
@@ -772,25 +958,28 @@ panel_plugin_external_child_watch_destroyed (gpointer user_data)
 
 
 
+static void
+panel_plugin_external_queue_data_free (QueuedData *data)
+{
+  g_free (data->property);
+  g_value_unset (&data->value);
+  g_slice_free (QueuedData, data);
+}
+
+
+
 GtkWidget *
 panel_plugin_external_new (PanelModule  *module,
                            gint          unique_id,
                            gchar       **arguments)
 {
-  PanelPluginExternal *external;
-
   panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
   panel_return_val_if_fail (unique_id != -1, NULL);
 
-  /* create new object */
-  external = g_object_new (PANEL_TYPE_PLUGIN_EXTERNAL, NULL);
-
-  /* set name, id and module */
-  external->unique_id = unique_id;
-  external->module = g_object_ref (G_OBJECT (module));
-  external->arguments = g_strdupv (arguments);
-
-  return GTK_WIDGET (external);
+  return g_object_new (PANEL_TYPE_PLUGIN_EXTERNAL,
+                       "module", module,
+                       "unique-id", unique_id,
+                       "arguments", arguments, NULL);
 }
 
 
@@ -808,9 +997,9 @@ panel_plugin_external_set_background_alpha (PanelPluginExternal *external,
   g_value_set_int (&value, percentage);
 
   /* send message */
-  panel_plugin_external_set_property (external,
-                                      PROPERTY_CHANGED_WRAPPER_BACKGROUND_ALPHA,
-                                      &value);
+  panel_plugin_external_dbus_set (external,
+                                  SIGNAL_WRAPPER_BACKGROUND_ALPHA,
+                                  &value);
 
   /* unset */
   g_value_unset (&value);
diff --git a/plugins/actions/actions.c b/plugins/actions/actions.c
index 3ddc88c..9af7dfc 100644
--- a/plugins/actions/actions.c
+++ b/plugins/actions/actions.c
@@ -349,6 +349,7 @@ actions_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
   panel_return_if_fail (XFCE_IS_ACTIONS_PLUGIN (plugin));
 
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (panel_plugin, actions_dialog_ui,
                                actions_dialog_ui_length, &dialog);
   if (G_UNLIKELY (builder == NULL))
diff --git a/plugins/clock/clock.c b/plugins/clock/clock.c
index 6906c74..4363d59 100644
--- a/plugins/clock/clock.c
+++ b/plugins/clock/clock.c
@@ -631,6 +631,7 @@ clock_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
   panel_return_if_fail (XFCE_IS_CLOCK_PLUGIN (plugin));
 
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (panel_plugin, clock_dialog_ui,
                                clock_dialog_ui_length, &window);
   if (G_UNLIKELY (builder == NULL))
diff --git a/plugins/launcher/launcher-dialog.c b/plugins/launcher/launcher-dialog.c
index 7938c84..154b07c 100644
--- a/plugins/launcher/launcher-dialog.c
+++ b/plugins/launcher/launcher-dialog.c
@@ -767,6 +767,7 @@ launcher_dialog_show (LauncherPlugin *plugin)
   panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
 
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (XFCE_PANEL_PLUGIN (plugin), launcher_dialog_ui,
                                launcher_dialog_ui_length, &window);
   if (G_UNLIKELY (builder == NULL))
diff --git a/plugins/pager/pager.c b/plugins/pager/pager.c
index 3179921..a8c5a6c 100644
--- a/plugins/pager/pager.c
+++ b/plugins/pager/pager.c
@@ -426,6 +426,7 @@ pager_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
   panel_return_if_fail (XFCE_IS_PAGER_PLUGIN (plugin));
 
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (panel_plugin, pager_dialog_ui,
                                pager_dialog_ui_length, &dialog);
   if (G_UNLIKELY (builder == NULL))
diff --git a/plugins/separator/separator.c b/plugins/separator/separator.c
index da75d61..159da47 100644
--- a/plugins/separator/separator.c
+++ b/plugins/separator/separator.c
@@ -25,6 +25,7 @@
 #include <libxfce4panel/libxfce4panel.h>
 #include <libxfce4panel/xfce-panel-plugin-provider.h>
 #include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
 #include <common/panel-private.h>
 #include <common/panel-xfconf.h>
 #include <common/panel-builder.h>
@@ -290,6 +291,7 @@ separator_plugin_construct (XfcePanelPlugin *panel_plugin)
   xfce_panel_plugin_menu_show_configure (XFCE_PANEL_PLUGIN (plugin));
 
   /* connect all properties */
+  PANEL_BUILDER_LINK_4UI
   panel_properties_bind (NULL, G_OBJECT (plugin),
                          xfce_panel_plugin_get_property_base (panel_plugin),
                          properties, FALSE);
diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c
index c9105aa..49f247e 100644
--- a/plugins/systray/systray.c
+++ b/plugins/systray/systray.c
@@ -447,11 +447,8 @@ systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
   GtkBuilder    *builder;
   GObject       *dialog, *object;
 
-  /* fix gtk builder problem: "Invalid object type XfceTitledDialog" */
-  if (xfce_titled_dialog_get_type () == 0)
-    return;
-
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (panel_plugin, systray_dialog_ui,
                                systray_dialog_ui_length, &dialog);
   if (G_UNLIKELY (builder == NULL))
diff --git a/plugins/tasklist/tasklist.c b/plugins/tasklist/tasklist.c
index 0844974..c1a5a9d 100644
--- a/plugins/tasklist/tasklist.c
+++ b/plugins/tasklist/tasklist.c
@@ -182,6 +182,7 @@ tasklist_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
   GObject        *object;
 
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (panel_plugin, tasklist_dialog_ui,
                                tasklist_dialog_ui_length, &dialog);
   if (G_UNLIKELY (builder == NULL))
diff --git a/plugins/windowmenu/windowmenu.c b/plugins/windowmenu/windowmenu.c
index ac1c9fe..1019ad8 100644
--- a/plugins/windowmenu/windowmenu.c
+++ b/plugins/windowmenu/windowmenu.c
@@ -494,6 +494,7 @@ window_menu_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
                                 "style" };
 
   /* setup the dialog */
+  PANEL_BUILDER_LINK_4UI
   builder = panel_builder_new (panel_plugin, windowmenu_dialog_ui,
                                windowmenu_dialog_ui_length, &dialog);
   if (G_UNLIKELY (builder == NULL))
diff --git a/wrapper/Makefile.am b/wrapper/Makefile.am
index 1166120..663d693 100644
--- a/wrapper/Makefile.am
+++ b/wrapper/Makefile.am
@@ -45,7 +45,8 @@ wrapper_DEPENDENCIES = \
 	$(top_builddir)/libxfce4panel/libxfce4panel-$(LIBXFCE4PANEL_VERSION_API).la
 
 if MAINTAINER_MODE
-wrapper-dbus-client-infos.h: $(top_builddir)/panel/panel-dbus-service-infos.xml Makefile
+
+wrapper-dbus-client-infos.h: $(top_builddir)/panel/panel-plugin-external-infos.xml Makefile
 	$(AM_V_GEN) dbus-binding-tool --mode=glib-client $< > $@
 
 wrapper-marshal.h: $(top_builddir)/panel/panel-marshal.list Makefile
@@ -60,6 +61,7 @@ BUILT_SOURCES = \
 
 DISTCLEANFILES = \
 	$(wrapper_built_sources)
+
 endif
 
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/wrapper/main.c b/wrapper/main.c
index b91053a..9563097 100644
--- a/wrapper/main.c
+++ b/wrapper/main.c
@@ -48,7 +48,6 @@
 #include <wrapper/wrapper-marshal.h>
 #include <wrapper/wrapper-module.h>
 
-#define DBUS_GLIB_CLIENT_WRAPPERS_org_xfce_Panel /* hack to exclude the panel client code */
 #include <wrapper/wrapper-dbus-client-infos.h>
 
 
@@ -78,124 +77,84 @@ static GOptionEntry option_entries[] =
 
 
 static void
-dbus_gproxy_property_changed (DBusGProxy              *dbus_gproxy,
-                              gint                     plugin_id,
-                              DBusPropertyChanged      property,
-                              const GValue            *value,
-                              XfcePanelPluginProvider *provider)
+wrapper_gproxy_set (DBusGProxy              *dbus_gproxy,
+                    const gchar             *property,
+                    const GValue            *value,
+                    guint                    reply_id,
+                    XfcePanelPluginProvider *provider)
 {
   WrapperPlug *plug;
 
   panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
-  panel_return_if_fail (value && G_TYPE_CHECK_VALUE (value));
-  panel_return_if_fail (opt_unique_id == xfce_panel_plugin_provider_get_unique_id (provider));
-
-  /* check if the signal is for this plugin */
-  if (plugin_id != opt_unique_id)
-    return;
+  panel_return_if_fail (G_TYPE_CHECK_VALUE (value));
+  panel_return_if_fail (property != NULL);
 
-  /* handle the changed property send by the panel to the wrapper */
-  switch (property)
+  if (property != NULL && *property == SIGNAL_PREFIX)
     {
-      case PROPERTY_CHANGED_PROVIDER_SIZE:
-        xfce_panel_plugin_provider_set_size (provider,
-                                             g_value_get_int (value));
-        break;
-
-      case PROPERTY_CHANGED_PROVIDER_ORIENTATION:
-        xfce_panel_plugin_provider_set_orientation (provider,
-                                                    g_value_get_uint (value));
-        break;
-
-      case PROPERTY_CHANGED_PROVIDER_SCREEN_POSITION:
-        xfce_panel_plugin_provider_set_screen_position (provider,
-                                                        g_value_get_uint (value));
-        break;
-
-      case PROPERTY_CHANGED_PROVIDER_EMIT_SAVE:
+      if (strcmp (property, SIGNAL_SET_SIZE) == 0)
+        xfce_panel_plugin_provider_set_size (provider, g_value_get_int (value));
+      else if (strcmp (property, SIGNAL_SET_ORIENTATION) == 0)
+        xfce_panel_plugin_provider_set_orientation (provider, g_value_get_uint (value));
+      else if (strcmp (property, SIGNAL_SET_SCREEN_POSITION) == 0)
+        xfce_panel_plugin_provider_set_screen_position (provider, g_value_get_uint (value));
+      else if (strcmp (property, SIGNAL_SAVE) == 0)
         xfce_panel_plugin_provider_save (provider);
-        break;
-
-      case PROPERTY_CHANGED_PROVIDER_EMIT_SHOW_CONFIGURE:
+      else if (strcmp (property, SIGNAL_SHOW_CONFIGURE) == 0)
         xfce_panel_plugin_provider_show_configure (provider);
-        break;
-
-      case PROPERTY_CHANGED_PROVIDER_EMIT_SHOW_ABOUT:
+      else if (strcmp (property, SIGNAL_SHOW_ABOUT) == 0)
         xfce_panel_plugin_provider_show_about (provider);
-        break;
-
-      case PROPERTY_CHANGED_PROVIDER_REMOVE:
+      else if (strcmp (property, SIGNAL_REMOVE) == 0)
         xfce_panel_plugin_provider_remove (provider);
-        break;
-
-      case PROPERTY_CHANGED_WRAPPER_QUIT:
+      else if (strcmp (property, SIGNAL_WRAPPER_QUIT) == 0)
         gtk_main_quit ();
-        break;
-
-      case PROPERTY_CHANGED_WRAPPER_SET_SENSITIVE:
-        gtk_widget_set_sensitive (GTK_WIDGET (provider),
-                                  g_value_get_boolean (value));
-        break;
-
-      case PROPERTY_CHANGED_WRAPPER_BACKGROUND_ALPHA:
-        plug = g_object_get_qdata (G_OBJECT (provider), plug_quark);
-        wrapper_plug_set_background_alpha (plug, g_value_get_int (value) / 100.00);
-        break;
-
-      default:
-        g_message ("External plugin \"%s-%d\" received unknown property \"%d\".",
-                   wrapper_name, opt_unique_id, property);
-        break;
+      else if (strcmp (property, SIGNAL_WRAPPER_SET_SENSITIVE) == 0)
+        gtk_widget_set_sensitive (GTK_WIDGET (provider), g_value_get_boolean (value));
+      else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_ALPHA) == 0)
+        {
+          plug = g_object_get_qdata (G_OBJECT (provider), plug_quark);
+          wrapper_plug_set_background_alpha (plug, g_value_get_int (value) / 100.00);
+        }
+      else
+        {
+          g_message ("External plugin \"%s-%d\" received unknown internal property \"%s\".",
+                     wrapper_name, opt_unique_id, property);
+        }
+    }
+  else
+    {
+      /* external event */
     }
 }
 
 
 
 static void
-dbus_gproxy_provider_signal (XfcePanelPluginProvider       *provider,
-                             XfcePanelPluginProviderSignal  provider_signal,
-                             DBusGProxy                    *dbus_gproxy)
+dbus_gproxy_provider_signal_callback (DBusGProxy *proxy,
+                                      GError     *error,
+                                      gpointer    user_data)
 {
-  GError *error = NULL;
-
-  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
-  panel_return_if_fail (opt_unique_id == xfce_panel_plugin_provider_get_unique_id (provider));
-
-  /* send the provider signal to the panel */
-  if (!wrapper_dbus_client_provider_signal (dbus_gproxy, opt_unique_id,
-                                            provider_signal, &error))
+  if (G_UNLIKELY (error != NULL))
     {
-      g_critical ("DBus error: %s", error->message);
+      g_warning ("Failed to send provider signal %d: %s",
+                 GPOINTER_TO_UINT (user_data), error->message);
       g_error_free (error);
     }
 }
 
 
 
-static DBusHandlerResult
-dbus_gproxy_dbus_filter (DBusConnection *connection,
-                         DBusMessage    *message,
-                         gpointer        user_data)
+static void
+dbus_gproxy_provider_signal (XfcePanelPluginProvider       *provider,
+                             XfcePanelPluginProviderSignal  provider_signal,
+                             DBusGProxy                    *dbus_gproxy)
 {
-  gchar *service, *old_owner, *new_owner;
-
-  /* make sure this is a name-owner-changed signal */
-  if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
-    {
-      /* get the information of the changed service */
-      if (dbus_message_get_args (message, NULL,
-                                 DBUS_TYPE_STRING, &service,
-                                 DBUS_TYPE_STRING, &old_owner,
-                                 DBUS_TYPE_STRING, &new_owner,
-                                 DBUS_TYPE_INVALID))
-        {
-          /* check if the panel service lost the owner, if so, leave the mainloop */
-          if (strcmp (service, "org.xfce.Panel") == 0 && !IS_STRING (new_owner))
-            gtk_main_quit ();
-        }
-    }
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
+  panel_return_if_fail (opt_unique_id == xfce_panel_plugin_provider_get_unique_id (provider));
 
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  /* send the provider signal to the panel */
+  wrapper_dbus_provider_signal_async (dbus_gproxy, provider_signal,
+                                      dbus_gproxy_provider_signal_callback,
+                                      GUINT_TO_POINTER (provider_signal));
 }
 
 
@@ -214,11 +173,12 @@ main (gint argc, gchar **argv)
   XfcePanelPluginPreInit  preinit_func;
   gboolean                result;
   DBusGConnection        *dbus_gconnection;
-  DBusConnection         *dbus_connection;
   DBusGProxy             *dbus_gproxy = NULL;
   WrapperModule          *module = NULL;
   WrapperPlug            *plug;
   GtkWidget              *provider;
+  gchar                  *path;
+  guint                   gproxy_destroy_id = 0;
 
   /* set translation domain */
   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
@@ -273,45 +233,34 @@ main (gint argc, gchar **argv)
       goto leave;
     }
 
-  /* initialize gtk */
   gtk_init (&argc, &argv);
 
-  /* try to connect to dbus */
+  /* connect the dbus proxy */
   dbus_gconnection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
   if (G_UNLIKELY (dbus_gconnection == NULL))
     goto leave;
 
-  /* get the dbus connection from the gconnection */
-  dbus_connection = dbus_g_connection_get_connection (dbus_gconnection);
-
-  /* hookup a filter to monitor panel segfaults */
-  if (dbus_connection_add_filter (dbus_connection, dbus_gproxy_dbus_filter, NULL, NULL))
-    dbus_bus_add_match (dbus_connection,
-                        "type='signal',sender='" DBUS_SERVICE_DBUS
-                        "',path='" DBUS_PATH_DBUS
-                        "',interface='" DBUS_INTERFACE_DBUS
-                        "',member='NameOwnerChanged'", NULL);
-
-  /* get the dbus proxy for the plugin interface */
-  dbus_gproxy = dbus_g_proxy_new_for_name (dbus_gconnection,
-                                           PANEL_DBUS_PLUGIN_INTERFACE,
-                                           PANEL_DBUS_PATH,
-                                           PANEL_DBUS_PLUGIN_INTERFACE);
+  path = g_strdup_printf (PANEL_DBUS_WRAPPER_PATH, opt_unique_id);
+  dbus_gproxy = dbus_g_proxy_new_for_name_owner (dbus_gconnection,
+                                                 PANEL_DBUS_NAME,
+                                                 path,
+                                                 PANEL_DBUS_WRAPPER_INTERFACE,
+                                                 &error);
+  g_free (path);
   if (G_UNLIKELY (dbus_gproxy == NULL))
-    {
-      /* set error and leave */
-      g_set_error (&error, 0, 0,
-                   "Failed to create the dbus proxy for interface \"%s\"",
-                   PANEL_DBUS_PLUGIN_INTERFACE);
-      goto leave;
-    }
+    goto leave;
+
+  /* quit when the proxy is destroyed (panel segfault for example) */
+  gproxy_destroy_id = g_signal_connect (G_OBJECT (dbus_gproxy), "destroy",
+      G_CALLBACK (gtk_main_quit), NULL);
 
-  /* setup signal for property changes */
-  dbus_g_object_register_marshaller (wrapper_marshal_VOID__INT_INT_BOXED,
-                                     G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT,
-                                     G_TYPE_VALUE, G_TYPE_INVALID);
-  dbus_g_proxy_add_signal (dbus_gproxy, "PropertyChanged", G_TYPE_INT,
-                           G_TYPE_INT, G_TYPE_VALUE, G_TYPE_INVALID);
+  /* preparations for the signal */
+  dbus_g_object_register_marshaller (wrapper_marshal_VOID__STRING_BOXED_UINT,
+                                     G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE,
+                                     G_TYPE_UINT, G_TYPE_INVALID);
+  dbus_g_proxy_add_signal (dbus_gproxy, "Set",
+                           G_TYPE_STRING, G_TYPE_VALUE,
+                           G_TYPE_UINT, G_TYPE_INVALID);
 
   /* create the type module */
   module = wrapper_module_new (library);
@@ -328,6 +277,7 @@ main (gint argc, gchar **argv)
       /* create the wrapper plug */
       plug = wrapper_plug_new (opt_socket_id);
       gtk_container_add (GTK_CONTAINER (plug), GTK_WIDGET (provider));
+      g_object_add_weak_pointer (G_OBJECT (plug), (gpointer *) &plug);
       gtk_widget_show (GTK_WIDGET (plug));
 
       /* set plug data to provider */
@@ -339,8 +289,8 @@ main (gint argc, gchar **argv)
           G_CALLBACK (dbus_gproxy_provider_signal), dbus_gproxy);
 
       /* connect dbus signal to set provider properties send from the panel */
-      dbus_g_proxy_connect_signal (dbus_gproxy, "PropertyChanged",
-          G_CALLBACK (dbus_gproxy_property_changed), g_object_ref (provider),
+      dbus_g_proxy_connect_signal (dbus_gproxy, "Set",
+          G_CALLBACK (wrapper_gproxy_set), g_object_ref (provider),
           (GClosureNotify) g_object_unref);
 
       /* show the plugin */
@@ -352,12 +302,13 @@ main (gint argc, gchar **argv)
       /* enter the main loop */
       gtk_main ();
 
-      /* disconnect signal */
-      dbus_g_proxy_disconnect_signal (dbus_gproxy, "PropertyChanged",
-          G_CALLBACK (dbus_gproxy_property_changed), provider);
+      /* disconnect signals */
+      dbus_g_proxy_disconnect_signal (dbus_gproxy, "Set",
+          G_CALLBACK (wrapper_gproxy_set), provider);
 
       /* destroy the plug and provider */
-      gtk_widget_destroy (GTK_WIDGET (plug));
+      if (plug != NULL)
+        gtk_widget_destroy (GTK_WIDGET (plug));
     }
   else
     {
@@ -367,7 +318,12 @@ main (gint argc, gchar **argv)
 leave:
   /* release the proxy */
   if (G_LIKELY (dbus_gproxy != NULL))
-    g_object_unref (G_OBJECT (dbus_gproxy));
+    {
+      if (G_LIKELY (gproxy_destroy_id != 0))
+        g_signal_handler_disconnect (G_OBJECT (dbus_gproxy), gproxy_destroy_id);
+
+      g_object_unref (G_OBJECT (dbus_gproxy));
+    }
 
   /* close the type module */
   if (G_LIKELY (module != NULL))



More information about the Xfce4-commits mailing list