From 0c5bf8a18aee42ca70fbb9823f009279d00e0c6c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 10:22:30 -0600 Subject: Adding in templated objects for the proxy subclass --- libdbusmenu-glib/Makefile.am | 3 +++ libdbusmenu-glib/menuitem-proxy.c | 56 +++++++++++++++++++++++++++++++++++++++ libdbusmenu-glib/menuitem-proxy.h | 44 ++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 libdbusmenu-glib/menuitem-proxy.c create mode 100644 libdbusmenu-glib/menuitem-proxy.h (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am index 998af50..65ebf4c 100644 --- a/libdbusmenu-glib/Makefile.am +++ b/libdbusmenu-glib/Makefile.am @@ -12,6 +12,7 @@ libdbusmenu_glibincludedir=$(includedir)/libdbusmenu-0.1/libdbusmenu-glib/ libdbusmenu_glibinclude_HEADERS = \ menuitem.h \ + menuitem-proxy.h \ server.h \ client.h @@ -23,6 +24,8 @@ libdbusmenu_glib_la_SOURCES = \ menuitem-marshal.h \ menuitem-marshal.c \ menuitem-private.h \ + menuitem-proxy.h \ + menuitem-proxy.c \ server.h \ server.c \ server-marshal.h \ diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c new file mode 100644 index 0000000..d5a9733 --- /dev/null +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -0,0 +1,56 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "menuitem-proxy.h" + +typedef struct _DbusmenuMenuitemProxyPrivate DbusmenuMenuitemProxyPrivate; +struct _DbusmenuMenuitemProxyPrivate { + gint placeholder; +}; + +#define DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyPrivate)) + +static void dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass); +static void dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self); +static void dbusmenu_menuitem_proxy_dispose (GObject *object); +static void dbusmenu_menuitem_proxy_finalize (GObject *object); + +G_DEFINE_TYPE (DbusmenuMenuitemProxy, dbusmenu_menuitem_proxy, DBUSMENU_TYPE_MENUITEM); + +static void +dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (DbusmenuMenuitemProxyPrivate)); + + object_class->dispose = dbusmenu_menuitem_proxy_dispose; + object_class->finalize = dbusmenu_menuitem_proxy_finalize; + + return; +} + +static void +dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self) +{ + + return; +} + +static void +dbusmenu_menuitem_proxy_dispose (GObject *object) +{ + + G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->dispose (object); + return; +} + +static void +dbusmenu_menuitem_proxy_finalize (GObject *object) +{ + + G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->finalize (object); + return; +} diff --git a/libdbusmenu-glib/menuitem-proxy.h b/libdbusmenu-glib/menuitem-proxy.h new file mode 100644 index 0000000..6a86fae --- /dev/null +++ b/libdbusmenu-glib/menuitem-proxy.h @@ -0,0 +1,44 @@ +#ifndef __DBUSMENU_MENUITEM_PROXY_H__ +#define __DBUSMENU_MENUITEM_PROXY_H__ + +#include +#include +#include "menuitem.h" + +G_BEGIN_DECLS + +#define DBUSMENU_TYPE_MENUITEM_PROXY (dbusmenu_menuitem_proxy_get_type ()) +#define DBUSMENU_MENUITEM_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxy)) +#define DBUSMENU_MENUITEM_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyClass)) +#define DBUSMENU_IS_MENUITEM_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_TYPE_MENUITEM_PROXY)) +#define DBUSMENU_IS_MENUITEM_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_MENUITEM_PROXY)) +#define DBUSMENU_MENUITEM_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyClass)) + +typedef struct _DbusmenuMenuitemProxy DbusmenuMenuitemProxy; +typedef struct _DbusmenuMenuitemProxyClass DbusmenuMenuitemProxyClass; + +/** + DbusmenuMenuitemProxyClass: + @parent_class: The Class of #DbusmeneMenuitem + + Functions and signal slots for #DbusmenuMenuitemProxy. +*/ +struct _DbusmenuMenuitemProxyClass { + DbusmenuMenuitemClass parent_class; +}; + +/** + DbusmeneMenuitemProxy: + @parent: The instance of #DbusmenuMenuitem + + Public instance data for a #DbusmenuMenuitemProxy. +*/ +struct _DbusmenuMenuitemProxy { + DbusmenuMenuitem parent; +}; + +GType dbusmenu_menuitem_proxy_get_type (void); + +G_END_DECLS + +#endif -- cgit v1.2.3 From db0e5c1bd674d437325638181ef0467855b19878 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 11:42:16 -0600 Subject: License headers --- libdbusmenu-glib/menuitem-proxy.c | 28 ++++++++++++++++++++++++++++ libdbusmenu-glib/menuitem-proxy.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index d5a9733..13ca09c 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -1,3 +1,31 @@ +/* +An object to ferry over properties and signals between two different +dbusmenu instances. Useful for services. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of either or both of the following licenses: + +1) the GNU Lesser General Public License version 3, as published by the +Free Software Foundation; and/or +2) the GNU Lesser General Public License version 2.1, as published by +the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR +PURPOSE. See the applicable version of the GNU Lesser General Public +License for more details. + +You should have received a copy of both the GNU Lesser General Public +License version 3 and version 2.1 along with this program. If not, see + +*/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/libdbusmenu-glib/menuitem-proxy.h b/libdbusmenu-glib/menuitem-proxy.h index 6a86fae..7e593d8 100644 --- a/libdbusmenu-glib/menuitem-proxy.h +++ b/libdbusmenu-glib/menuitem-proxy.h @@ -1,3 +1,31 @@ +/* +An object to ferry over properties and signals between two different +dbusmenu instances. Useful for services. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of either or both of the following licenses: + +1) the GNU Lesser General Public License version 3, as published by the +Free Software Foundation; and/or +2) the GNU Lesser General Public License version 2.1, as published by +the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR +PURPOSE. See the applicable version of the GNU Lesser General Public +License for more details. + +You should have received a copy of both the GNU Lesser General Public +License version 3 and version 2.1 along with this program. If not, see + +*/ + #ifndef __DBUSMENU_MENUITEM_PROXY_H__ #define __DBUSMENU_MENUITEM_PROXY_H__ -- cgit v1.2.3 From c6e66acdc7ae9cebbe3592905206760f7b168694 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 11:49:17 -0600 Subject: Adding in event handling. --- libdbusmenu-glib/menuitem-proxy.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 13ca09c..98788c6 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -34,7 +34,7 @@ License version 3 and version 2.1 along with this program. If not, see typedef struct _DbusmenuMenuitemProxyPrivate DbusmenuMenuitemProxyPrivate; struct _DbusmenuMenuitemProxyPrivate { - gint placeholder; + DbusmenuMenuitem * mi; }; #define DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(o) \ @@ -44,6 +44,7 @@ static void dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klas static void dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self); static void dbusmenu_menuitem_proxy_dispose (GObject *object); static void dbusmenu_menuitem_proxy_finalize (GObject *object); +static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); G_DEFINE_TYPE (DbusmenuMenuitemProxy, dbusmenu_menuitem_proxy, DBUSMENU_TYPE_MENUITEM); @@ -57,6 +58,10 @@ dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass) object_class->dispose = dbusmenu_menuitem_proxy_dispose; object_class->finalize = dbusmenu_menuitem_proxy_finalize; + DbusmenuMenuitemClass * miclass = DBUSMENU_MENUITEM_CLASS(klass); + + miclass->handle_event = handle_event; + return; } @@ -82,3 +87,14 @@ dbusmenu_menuitem_proxy_finalize (GObject *object) G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->finalize (object); return; } + +/* Takes the event and passes it along to the item that we're + playing proxy for. */ +static void +handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp) +{ + g_return_if_fail(DBUSMENU_IS_MENUITEM_PROXY(mi)); + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(mi); + g_return_if_fail(priv->mi != NULL); + return dbusmenu_menuitem_handle_event(priv->mi, name, value, timestamp); +} -- cgit v1.2.3 From 89fb85dd78c224893ff80498fdf9a57210604a79 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 11:53:00 -0600 Subject: Lifecycle for the menuitem --- libdbusmenu-glib/menuitem-proxy.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 98788c6..836056e 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -68,18 +68,29 @@ dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass) static void dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self) { + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(self); + + priv->mi = NULL; return; } +/* Remove references to objects */ static void dbusmenu_menuitem_proxy_dispose (GObject *object) { + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(object); + + if (priv->mi != NULL) { + g_object_unref(G_OBJECT(priv->mi)); + priv->mi = NULL; + } G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->dispose (object); return; } +/* Free any memory that we've allocated */ static void dbusmenu_menuitem_proxy_finalize (GObject *object) { -- cgit v1.2.3 From 106cfac3df317f1244d7d779ed2cb640eb359a6c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 12:00:14 -0600 Subject: Moving the menuitem association into a set of functions to make a complex operation more clear. --- libdbusmenu-glib/menuitem-proxy.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 836056e..b50d8a5 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -45,6 +45,8 @@ static void dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self); static void dbusmenu_menuitem_proxy_dispose (GObject *object); static void dbusmenu_menuitem_proxy_finalize (GObject *object); static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); +static void add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi); +static void remove_menuitem (DbusmenuMenuitemProxy * pmi); G_DEFINE_TYPE (DbusmenuMenuitemProxy, dbusmenu_menuitem_proxy, DBUSMENU_TYPE_MENUITEM); @@ -79,12 +81,7 @@ dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self) static void dbusmenu_menuitem_proxy_dispose (GObject *object) { - DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(object); - - if (priv->mi != NULL) { - g_object_unref(G_OBJECT(priv->mi)); - priv->mi = NULL; - } + remove_menuitem(DBUSMENU_MENUITEM_PROXY(object)); G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->dispose (object); return; @@ -109,3 +106,32 @@ handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, g g_return_if_fail(priv->mi != NULL); return dbusmenu_menuitem_handle_event(priv->mi, name, value, timestamp); } + +/* References all of the things we need for talking to this menuitem + including signals and other data. If the menuitem already has + properties we need to signal that they've changed for us. */ +static void +add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi) +{ + + return; +} + +/* Removes the menuitem from being our proxy. Typically this isn't + done until this object is destroyed, but who knows?!? */ +static void +remove_menuitem (DbusmenuMenuitemProxy * pmi) +{ + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(pmi); + if (priv->mi == NULL) { + return; + } + + /* Remove signals */ + + /* Unref */ + g_object_unref(G_OBJECT(priv->mi)); + priv->mi = NULL; + + return; +} -- cgit v1.2.3 From cd276bc30c0c05155868420b7afb0f4e3ce66a37 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 14:15:36 -0600 Subject: Setting up code to get and set the menuitem. --- libdbusmenu-glib/menuitem-proxy.c | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index b50d8a5..d91ecfd 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -37,6 +37,14 @@ struct _DbusmenuMenuitemProxyPrivate { DbusmenuMenuitem * mi; }; +/* Properties */ +enum { + PROP_0, + PROP_MENU_ITEM +}; + +#define PROP_MENU_ITEM_S "menu-item" + #define DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyPrivate)) @@ -44,6 +52,8 @@ static void dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klas static void dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self); static void dbusmenu_menuitem_proxy_dispose (GObject *object); static void dbusmenu_menuitem_proxy_finalize (GObject *object); +static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); +static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); static void add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi); static void remove_menuitem (DbusmenuMenuitemProxy * pmi); @@ -59,11 +69,19 @@ dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass) object_class->dispose = dbusmenu_menuitem_proxy_dispose; object_class->finalize = dbusmenu_menuitem_proxy_finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; DbusmenuMenuitemClass * miclass = DBUSMENU_MENUITEM_CLASS(klass); miclass->handle_event = handle_event; + g_object_class_install_property (object_class, PROP_MENU_ITEM, + g_param_spec_object(PROP_MENU_ITEM_S, "The Menuitem we're proxying", + "An instance of the DbusmenuMenuitem class that this menuitem will mimic.", + DBUSMENU_TYPE_MENUITEM, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + return; } @@ -96,6 +114,42 @@ dbusmenu_menuitem_proxy_finalize (GObject *object) return; } +/* Set a property using the generic GObject interface */ +static void +set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) +{ + switch (id) { + case PROP_MENU_ITEM: { + GObject * lobj = g_value_get_object(value); + add_menuitem(DBUSMENU_MENUITEM_PROXY(obj), DBUSMENU_MENUITEM(lobj)); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec); + break; + } + + return; +} + +/* Get a property using the generic GObject interface */ +static void +get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) +{ + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(obj); + + switch (id) { + case PROP_MENU_ITEM: + g_value_set_object(value, priv->mi); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec); + break; + } + + return; +} + /* Takes the event and passes it along to the item that we're playing proxy for. */ static void -- cgit v1.2.3 From 4222ceb8b29f0fd45e90a3e9260bfd44accebf23 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 14:40:54 -0600 Subject: Reffing it and pulling it into the private struct. --- libdbusmenu-glib/menuitem-proxy.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index d91ecfd..39315ae 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -167,6 +167,17 @@ handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, g static void add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi) { + /* Put it in private */ + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(pmi); + if (priv->mi != NULL) { + remove_menuitem(pmi); + } + priv->mi = mi; + g_object_ref(G_OBJECT(priv->mi)); + + /* Attach signals */ + + /* Go through children and wrap them */ return; } -- cgit v1.2.3 From 2617e7e630e8ee29da21d3f2944887164af5c9af Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 22:23:17 -0600 Subject: Building the proxy item new function. --- libdbusmenu-glib/menuitem-proxy.c | 19 +++++++++++++++++++ libdbusmenu-glib/menuitem-proxy.h | 1 + 2 files changed, 20 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 39315ae..9a83419 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -200,3 +200,22 @@ remove_menuitem (DbusmenuMenuitemProxy * pmi) return; } + +/** + dbusmenu_menuitem_proxy_new: + @mi: The #DbusmenuMenuitem to proxy + + Builds a new #DbusmenuMenuitemProxy object that proxies + all of the values for @mi. + + Return value: A new #DbusmenuMenuitemProxy object. +*/ +DbusmenuMenuitemProxy * +dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi) +{ + DbusmenuMenuitemProxy * pmi = g_object_new(DBUSMENU_TYPE_MENUITEM_PROXY, + PROP_MENU_ITEM_S, mi, + NULL); + + return pmi; +} diff --git a/libdbusmenu-glib/menuitem-proxy.h b/libdbusmenu-glib/menuitem-proxy.h index 7e593d8..dcf1e8d 100644 --- a/libdbusmenu-glib/menuitem-proxy.h +++ b/libdbusmenu-glib/menuitem-proxy.h @@ -66,6 +66,7 @@ struct _DbusmenuMenuitemProxy { }; GType dbusmenu_menuitem_proxy_get_type (void); +DbusmenuMenuitemProxy * dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi); G_END_DECLS -- cgit v1.2.3 From fb1e4ab223f5fd203ac5330a040b8a222bc96ca8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 23:06:22 -0600 Subject: Setting up signals, and the easy ones are filled out. --- libdbusmenu-glib/menuitem-proxy.c | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 9a83419..3bd2684 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -161,6 +161,43 @@ handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, g return dbusmenu_menuitem_handle_event(priv->mi, name, value, timestamp); } +/* Watches a property change and makes sure to put that value + into our property list. */ +static void +proxy_item_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, gpointer user_data) +{ + DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data); + dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(pmi), property, value); + return; +} + +/* Looks for a child getting added and wraps it and places it + in our list of children. */ +static void +proxy_item_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer user_data) +{ + DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data); + DbusmenuMenuitemProxy * child_pmi = dbusmenu_menuitem_proxy_new(child); + dbusmenu_menuitem_child_add_position(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(child_pmi), position); + return; +} + +/* Find the wrapper for this child and remove it as well. */ +static void +proxy_item_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, gpointer user_data) +{ + + return; +} + +/* Find the wrapper for the item and move it in our child list */ +static void +proxy_item_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos) +{ + + return; +} + /* References all of the things we need for talking to this menuitem including signals and other data. If the menuitem already has properties we need to signal that they've changed for us. */ @@ -176,6 +213,12 @@ add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi) g_object_ref(G_OBJECT(priv->mi)); /* Attach signals */ + g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(proxy_item_property_changed), pmi); + g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(proxy_item_child_added), pmi); + g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(proxy_item_child_removed), pmi); + g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(proxy_item_child_moved), pmi); + + /* Grab (cache) Properties */ /* Go through children and wrap them */ -- cgit v1.2.3 From 8b2d9eb519c695b71ca08fd4afb71b086160d8b4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 23:12:22 -0600 Subject: Storing the handler IDs so that we can easily disconnect the signals later. --- libdbusmenu-glib/menuitem-proxy.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 3bd2684..22d2d61 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -35,6 +35,10 @@ License version 3 and version 2.1 along with this program. If not, see typedef struct _DbusmenuMenuitemProxyPrivate DbusmenuMenuitemProxyPrivate; struct _DbusmenuMenuitemProxyPrivate { DbusmenuMenuitem * mi; + gulong sig_property_changed; + gulong sig_child_added; + gulong sig_child_removed; + gulong sig_child_moved; }; /* Properties */ @@ -92,6 +96,11 @@ dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self) priv->mi = NULL; + priv->sig_property_changed = 0; + priv->sig_child_added = 0; + priv->sig_child_removed = 0; + priv->sig_child_moved = 0; + return; } @@ -213,10 +222,10 @@ add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi) g_object_ref(G_OBJECT(priv->mi)); /* Attach signals */ - g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(proxy_item_property_changed), pmi); - g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(proxy_item_child_added), pmi); - g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(proxy_item_child_removed), pmi); - g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(proxy_item_child_moved), pmi); + priv->sig_property_changed = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(proxy_item_property_changed), pmi); + priv->sig_child_added = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(proxy_item_child_added), pmi); + priv->sig_child_removed = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(proxy_item_child_removed), pmi); + priv->sig_child_moved = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(proxy_item_child_moved), pmi); /* Grab (cache) Properties */ @@ -236,6 +245,18 @@ remove_menuitem (DbusmenuMenuitemProxy * pmi) } /* Remove signals */ + if (priv->sig_property_changed != 0) { + g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_property_changed); + } + if (priv->sig_child_added != 0) { + g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_child_added); + } + if (priv->sig_child_removed != 0) { + g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_child_removed); + } + if (priv->sig_child_moved != 0) { + g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_child_moved); + } /* Unref */ g_object_unref(G_OBJECT(priv->mi)); -- cgit v1.2.3 From 20a6ad89877a6f0a4c279fdda313499e64ff8b5a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 23:30:04 -0600 Subject: Stealing (caching) all of the properties now too! --- libdbusmenu-glib/menuitem-proxy.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 22d2d61..0bbfd26 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -228,6 +228,13 @@ add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi) priv->sig_child_moved = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(proxy_item_child_moved), pmi); /* Grab (cache) Properties */ + GList * props = dbusmenu_menuitem_properties_list(priv->mi); + GList * prop; + for (prop = props; prop != NULL; prop = g_list_next(prop)) { + gchar * prop_name = (gchar *)prop->data; + dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(pmi), prop_name, dbusmenu_menuitem_property_get_value(priv->mi, prop_name)); + } + g_list_free(props); /* Go through children and wrap them */ @@ -262,6 +269,8 @@ remove_menuitem (DbusmenuMenuitemProxy * pmi) g_object_unref(G_OBJECT(priv->mi)); priv->mi = NULL; + /* Remove our own children */ + return; } -- cgit v1.2.3 From e92fb8d011ef38491a724b828bb83b1a63a810cb Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 23:34:06 -0600 Subject: Killing our children --- libdbusmenu-glib/menuitem-proxy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 0bbfd26..78244d3 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -207,6 +207,13 @@ proxy_item_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, gui return; } +/* Making g_object_unref into a GFunc */ +static void +func_g_object_unref (gpointer data, gpointer user_data) +{ + return g_object_unref(G_OBJECT(data)); +} + /* References all of the things we need for talking to this menuitem including signals and other data. If the menuitem already has properties we need to signal that they've changed for us. */ @@ -270,6 +277,9 @@ remove_menuitem (DbusmenuMenuitemProxy * pmi) priv->mi = NULL; /* Remove our own children */ + GList * children = dbusmenu_menuitem_take_children(DBUSMENU_MENUITEM(pmi)); + g_list_foreach(children, func_g_object_unref, NULL); + g_list_free(children); return; } -- cgit v1.2.3 From b97fc51147023d89368411bc408c1333c276f515 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 9 Feb 2010 23:36:47 -0600 Subject: Adding children in. --- libdbusmenu-glib/menuitem-proxy.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 78244d3..ece797d 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -244,6 +244,12 @@ add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi) g_list_free(props); /* Go through children and wrap them */ + GList * children = dbusmenu_menuitem_get_children(priv->mi); + GList * child; + for (child = children; child != NULL; child = g_list_next(child)) { + DbusmenuMenuitemProxy * child_pmi = dbusmenu_menuitem_proxy_new(DBUSMENU_MENUITEM(child->data)); + dbusmenu_menuitem_child_append(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(child_pmi)); + } return; } -- cgit v1.2.3 From 6218dd513fb61750af75b9c647c76cdb33f72893 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Feb 2010 16:59:39 -0600 Subject: Accessor for the mi private variable --- libdbusmenu-glib/menuitem-proxy.c | 18 ++++++++++++++++++ libdbusmenu-glib/menuitem-proxy.h | 1 + 2 files changed, 19 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index ece797d..796561d 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -308,3 +308,21 @@ dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi) return pmi; } + +/** + dbusmenu_menuitem_proxy_get_wrapped: + @pmi: #DbusmenuMenuitemProxy to look into + + Accesses the private variable of which #DbusmenuMenuitem + we are doing the proxying for. + + Return value: A #DbusmenuMenuitem object or a #NULL if we + don't have one or there is an error. +*/ +DbusmenuMenuitem * +dbusmenu_menuitem_proxy_get_wrapped (DbusmenuMenuitemProxy * pmi) +{ + g_return_val_if_fail(DBUSMENU_MENUITEM_PROXY(pmi), NULL); + DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(pmi); + return priv->mi; +} diff --git a/libdbusmenu-glib/menuitem-proxy.h b/libdbusmenu-glib/menuitem-proxy.h index dcf1e8d..56c4941 100644 --- a/libdbusmenu-glib/menuitem-proxy.h +++ b/libdbusmenu-glib/menuitem-proxy.h @@ -67,6 +67,7 @@ struct _DbusmenuMenuitemProxy { GType dbusmenu_menuitem_proxy_get_type (void); DbusmenuMenuitemProxy * dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi); +DbusmenuMenuitem * dbusmenu_menuitem_proxy_get_wrapped (DbusmenuMenuitemProxy * pmi); G_END_DECLS -- cgit v1.2.3 From 52cb0d03b8b49f8af1e76258228dd72eff039031 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Feb 2010 17:07:13 -0600 Subject: Fleshing out delete --- libdbusmenu-glib/menuitem-proxy.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index 796561d..f61d2e7 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -195,6 +195,23 @@ proxy_item_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, gui static void proxy_item_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, gpointer user_data) { + DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data); + GList * children = dbusmenu_menuitem_get_children(DBUSMENU_MENUITEM(pmi)); + DbusmenuMenuitemProxy * finalpmi = NULL; + GList * childitem; + + for (childitem = children; childitem != NULL; childitem = g_list_next(childitem)) { + DbusmenuMenuitemProxy * childpmi = (DbusmenuMenuitemProxy *)childitem->data; + DbusmenuMenuitem * childmi = dbusmenu_menuitem_proxy_get_wrapped(childpmi); + if (childmi == child) { + finalpmi = childpmi; + break; + } + } + + if (finalpmi != NULL) { + dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(finalpmi)); + } return; } -- cgit v1.2.3 From 3f50ef61be29c8e3511cc4d86a5d986759cd9ccb Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Feb 2010 17:08:47 -0600 Subject: Fleshing out the moved function. --- libdbusmenu-glib/menuitem-proxy.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/menuitem-proxy.c b/libdbusmenu-glib/menuitem-proxy.c index f61d2e7..2dd5ada 100644 --- a/libdbusmenu-glib/menuitem-proxy.c +++ b/libdbusmenu-glib/menuitem-proxy.c @@ -218,8 +218,25 @@ proxy_item_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, g /* Find the wrapper for the item and move it in our child list */ static void -proxy_item_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos) +proxy_item_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, gpointer user_data) { + DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data); + GList * children = dbusmenu_menuitem_get_children(DBUSMENU_MENUITEM(pmi)); + DbusmenuMenuitemProxy * finalpmi = NULL; + GList * childitem; + + for (childitem = children; childitem != NULL; childitem = g_list_next(childitem)) { + DbusmenuMenuitemProxy * childpmi = (DbusmenuMenuitemProxy *)childitem->data; + DbusmenuMenuitem * childmi = dbusmenu_menuitem_proxy_get_wrapped(childpmi); + if (childmi == child) { + finalpmi = childpmi; + break; + } + } + + if (finalpmi != NULL) { + dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(finalpmi), newpos); + } return; } -- cgit v1.2.3 From d4a35054867dfcb78c4ced2df7a63f34242f21c1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Feb 2010 21:42:58 -0600 Subject: Creating the delayed array, and cleaning it up too. --- libdbusmenu-glib/client.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 2302110..f138b0b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -75,6 +75,8 @@ struct _DbusmenuClientPrivate DBusGProxy * dbusproxy; GHashTable * type_handlers; + + GArray * delayed_properties; }; typedef struct _newItemPropData newItemPropData; @@ -85,6 +87,21 @@ struct _newItemPropData DbusmenuMenuitem * parent; }; +typedef struct _propertyDelay propertyDelay; +struct _propertyDelay +{ + guint revsion; + GArray * entries; +}; + +typedef struct _propertyDelayValue propertyDelayValue; +struct _propertyDelayValue +{ + gint id; + gchar * name; + GValue value; +}; + #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate)) @@ -208,6 +225,8 @@ dbusmenu_client_init (DbusmenuClient *self) priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + priv->delayed_properties = g_array_new(FALSE, TRUE, sizeof(propertyDelay)); + return; } @@ -255,6 +274,23 @@ dbusmenu_client_finalize (GObject *object) g_hash_table_destroy(priv->type_handlers); } + if (priv->delayed_properties) { + gint i; + for (i = 0; i < priv->delayed_properties->len; i++) { + propertyDelay * delay = &g_array_index(priv->delayed_properties, propertyDelay, i); + gint j; + for (j = 0; j < delay->entries->len; j++) { + propertyDelayValue * value = &g_array_index(delay->entries, propertyDelayValue, j); + g_free(value->name); + g_value_unset(&value->value); + } + g_array_free(delay->entries, TRUE); + delay->entries = NULL; + } + g_array_free(priv->delayed_properties, TRUE); + priv->delayed_properties = NULL; + } + G_OBJECT_CLASS (dbusmenu_client_parent_class)->finalize (object); return; } -- cgit v1.2.3 From 618b94db5b21412385a84f65fb7636833a74fc23 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Feb 2010 22:33:06 -0600 Subject: Start to delay ID updates that are gotten when we know we're out of sync. --- libdbusmenu-glib/client.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f138b0b..c53166b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -90,7 +90,7 @@ struct _newItemPropData typedef struct _propertyDelay propertyDelay; struct _propertyDelay { - guint revsion; + guint revision; GArray * entries; }; @@ -355,6 +355,49 @@ layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * return; } +/* Add an entry to the set of entries that are delayed until the + layout has been updated to this revision */ +static void +delay_prop_update (guint revision, GArray * delayarray, gint id, gchar * prop, GValue * value) +{ + propertyDelay * delay = NULL; + gint i; + + /* First look for something with this revision number. This + array should be really short, probably not more than an entry or + two so there is no reason to optimize this. */ + for (i = 0; i < delayarray->len; i++) { + propertyDelay * localdelay = &g_array_index(delayarray, propertyDelay, i); + if (localdelay->revision == revision) { + delay = localdelay; + break; + } + } + + /* If we don't have any entires for this revision number then we + need to create a new one with it's own array of entires. */ + if (delay == NULL) { + propertyDelay localdelay = {0}; + localdelay.revision = revision; + localdelay.entries = g_array_new(FALSE, TRUE, sizeof(propertyDelayValue)); + + g_array_append_val(delayarray, localdelay); + delay = &g_array_index(delayarray, propertyDelay, delayarray->len - 1); + } + + /* Build the actual entry and tack it on the end of the array + of entries */ + propertyDelayValue delayvalue = {0}; + delayvalue.id = id; + delayvalue.name = g_strdup(prop); + + g_value_init(&delayvalue.value, G_VALUE_TYPE(value)); + g_value_copy(value, &delayvalue.value); + + g_array_append_val(delay->entries, delayvalue); + return; +} + /* Signal from the server that a property has changed on one of our menuitems */ static void @@ -369,7 +412,17 @@ id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, D #endif DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - g_return_if_fail(priv->root != NULL); + + /* If we're not on the right revision, we need to cache the property + changes as it could be that the menuitems don't exist yet. */ + if (priv->my_revision != priv->current_revision) { + delay_prop_update(priv->current_revision, priv->delayed_properties, id, property, value); + return; + } + + if (priv->root != NULL) { + return; + } DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id); g_return_if_fail(menuitem != NULL); -- cgit v1.2.3 From 285ee828ae89c5cc5bbf6e829c84d3980ac2f3c4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Feb 2010 22:52:37 -0600 Subject: Putting in code to undo the array as the layouts get updated. --- libdbusmenu-glib/client.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index c53166b..191ea03 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -885,16 +885,19 @@ update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, vo DbusmenuClient * client = DBUSMENU_CLIENT(data); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + /* Check to make sure this isn't an issue */ if (error != NULL) { g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message); return; } + /* Try to take in the layout that we got */ if (!parse_layout(client, xml)) { g_warning("Unable to parse layout!"); return; } + /* Success, so we need to update our local variables */ priv->my_revision = rev; /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */ priv->layoutcall = NULL; @@ -903,6 +906,41 @@ update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, vo #endif g_signal_emit(G_OBJECT(client), signals[LAYOUT_UPDATED], 0, TRUE); + /* Apply the delayed properties that were queued up while + we were waiting on this layout update. */ + if (G_LIKELY(priv->delayed_properties != NULL)) { + gint i; + for (i = 0; i < priv->delayed_properties->len; i++) { + propertyDelay * delay = &g_array_index(priv->delayed_properties, propertyDelay, i); + if (delay->revision > priv->my_revision) { + /* Check to see if this is for future revisions, which + is possible if there is a ton of updates. */ + break; + } + + gint j; + for (j = 0; j < delay->entries->len; j++) { + propertyDelayValue * value = &g_array_index(delay->entries, propertyDelayValue, j); + DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, value->id); + if (mi != NULL) { + dbusmenu_menuitem_property_set_value(mi, value->name, &value->value); + } + g_free(value->name); + g_value_unset(&value->value); + } + g_array_free(delay->entries, TRUE); + + /* We're removing the entry and moving the index down one + to ensure that we adjust for the shift in the array. The + reality is that i is always 0. You understood this loop + until you got here, didn't you :) */ + g_array_remove_index(priv->delayed_properties, i); + i--; + } + } + + /* Check to see if we got another update in the time this + one was issued. */ if (priv->my_revision < priv->current_revision) { update_layout(client); } -- cgit v1.2.3 From f7133702f0bec20aa4bebda08c7dd60431529b0b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Sat, 13 Feb 2010 00:03:36 -0600 Subject: Making it so that NULL roots also cause the items to get delayed until we have a root element. --- libdbusmenu-glib/client.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 191ea03..edffb07 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -415,15 +415,14 @@ id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, D /* If we're not on the right revision, we need to cache the property changes as it could be that the menuitems don't exist yet. */ - if (priv->my_revision != priv->current_revision) { + if (priv->root == NULL || priv->my_revision != priv->current_revision) { + #ifdef MASSIVEDEBUGGING + g_debug("Delaying prop update until rev %d for id %d property %s", priv->current_revision, id, property); + #endif delay_prop_update(priv->current_revision, priv->delayed_properties, id, property, value); return; } - if (priv->root != NULL) { - return; - } - DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id); g_return_if_fail(menuitem != NULL); @@ -923,6 +922,9 @@ update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, vo propertyDelayValue * value = &g_array_index(delay->entries, propertyDelayValue, j); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, value->id); if (mi != NULL) { + #ifdef MASSIVEDEBUGGING + g_debug("Applying delayed property id %d property %s", value->id, value->name); + #endif dbusmenu_menuitem_property_set_value(mi, value->name, &value->value); } g_free(value->name); -- cgit v1.2.3 From 8021b8e5434ecc2d76495c1d3e52cc9a0691852a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Sat, 13 Feb 2010 01:06:39 -0600 Subject: Properly handing a child changing to make sure to recurse down the structure setting up the signals. --- libdbusmenu-glib/server.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'libdbusmenu-glib') diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index f8267c2..15ec281 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -301,10 +301,29 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * val return; } +/* Adds the signals for this entry to the list and looks at + the children of this entry to add the signals we need + as well. We like signals. */ +static void +added_check_children (gpointer data, gpointer user_data) +{ + DbusmenuMenuitem * mi = (DbusmenuMenuitem *)data; + DbusmenuServer * server = (DbusmenuServer *)user_data; + + menuitem_signals_create(mi, server); + g_list_foreach(dbusmenu_menuitem_get_children(mi), added_check_children, server); + + return; +} + +/* Callback for when a child is added. We need to connect everything + up and signal that the layout has changed. */ static void menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint pos, DbusmenuServer * server) { menuitem_signals_create(child, server); + g_list_foreach(dbusmenu_menuitem_get_children(child), added_check_children, server); + /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; -- cgit v1.2.3