Merge lp:~ted/libdbusmenu/serializable-menuitem into lp:libdbusmenu/0.5

Proposed by Ted Gould
Status: Merged
Merged at revision: 197
Proposed branch: lp:~ted/libdbusmenu/serializable-menuitem
Merge into: lp:libdbusmenu/0.5
Diff against target: 687 lines (+489/-18)
11 files modified
.bzrignore (+3/-0)
docs/libdbusmenu-gtk/reference/Makefile.am (+1/-1)
docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml (+1/-1)
libdbusmenu-glib/client.c (+69/-7)
libdbusmenu-glib/client.h (+7/-1)
libdbusmenu-gtk/Makefile.am (+5/-2)
libdbusmenu-gtk/client.c (+4/-4)
libdbusmenu-gtk/dbusmenu-gtk.h (+1/-0)
libdbusmenu-gtk/menuitem.h (+2/-2)
libdbusmenu-gtk/serializablemenuitem.c (+288/-0)
libdbusmenu-gtk/serializablemenuitem.h (+108/-0)
To merge this branch: bzr merge lp:~ted/libdbusmenu/serializable-menuitem
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Needs Fixing
Review via email: mp+47604@code.launchpad.net

Description of the change

This adds a new object that can be subclassed from to create menuitems with enough data that they can be transported across dbusmenu transparently.

To post a comment you must log in.
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

The function prototypes DbusmenuClientTypeHandler and DbusmenuClientTypeDestroyHandler needs documentation.

Can we avoid double namespacing on these two functions?:

dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem()
dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem()

Becomes:

dbusmenu_gtk_serializable_menu_item_build_menuitem()
dbusmenu_gtk_serializable_menu_item_set_menuitem()

Can you add some section docs describing what the purpose of DbusmenuGtkSerializableMenuItem is, and how to use it? After reviewing this code I am still not entirely sure what it's supposed to do :-)

review: Needs Fixing
Revision history for this message
Ted Gould (ted) wrote :

On Thu, 2011-01-27 at 09:49 +0000, Mikkel Kamstrup Erlandsen wrote:
> The function prototypes DbusmenuClientTypeHandler and
> DbusmenuClientTypeDestroyHandler needs documentation.

r215

> Can we avoid double namespacing on these two functions?:
>
> dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem()
> dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem()
>
> Becomes:
>
> dbusmenu_gtk_serializable_menu_item_build_menuitem()
> dbusmenu_gtk_serializable_menu_item_set_menuitem()

Yes, was looking for a good way to shorten these, thanks!

r214

> Can you add some section docs describing what the purpose of
> DbusmenuGtkSerializableMenuItem is, and how to use it? After
> reviewing this code I am still not entirely sure what it's
> supposed to do :-)

r216

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2010-12-02 20:13:09 +0000
3+++ .bzrignore 2011-01-26 23:16:59 +0000
4@@ -220,3 +220,6 @@
5 libdbusmenu-gtk/DbusmenuGtk-0.4.vapi
6 libdbusmenu-gtk/dbusmenu-gtk-0.4.pc
7 libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc
8+libdbusmenu-gtk/libdbusmenu_gtk_la-serializablemenuitem.lo
9+docs/libdbusmenu-gtk/reference/html/DbusmenuGtkSerializableMenuItem.html
10+docs/libdbusmenu-gtk/reference/tmpl/serializablemenuitem.sgml
11
12=== modified file 'docs/libdbusmenu-gtk/reference/Makefile.am'
13--- docs/libdbusmenu-gtk/reference/Makefile.am 2010-11-23 21:19:52 +0000
14+++ docs/libdbusmenu-gtk/reference/Makefile.am 2011-01-26 23:16:59 +0000
15@@ -54,7 +54,7 @@
16
17 # Header files to ignore when scanning.
18 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
19-IGNORE_HFILES=
20+IGNORE_HFILES=genericmenuitem.h
21
22 # Images to copy into HTML directory.
23 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
24
25=== modified file 'docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml'
26--- docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml 2010-06-09 16:24:31 +0000
27+++ docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml 2011-01-26 23:16:59 +0000
28@@ -13,8 +13,8 @@
29 <title>API</title>
30 <xi:include href="xml/menu.xml"/>
31 <xi:include href="xml/client.xml"/>
32- <xi:include href="xml/genericmenuitem.xml"/>
33 <xi:include href="xml/menuitem.xml"/>
34+ <xi:include href="xml/serializablemenuitem.xml"/>
35
36 </chapter>
37 <chapter id="object-tree">
38
39=== modified file 'libdbusmenu-glib/client.c'
40--- libdbusmenu-glib/client.c 2011-01-26 23:12:22 +0000
41+++ libdbusmenu-glib/client.c 2011-01-26 23:16:59 +0000
42@@ -120,6 +120,15 @@
43 guint timestamp;
44 };
45
46+typedef struct _type_handler_t type_handler_t;
47+struct _type_handler_t {
48+ DbusmenuClient * client;
49+ DbusmenuClientTypeHandler cb;
50+ DbusmenuClientTypeDestroyHandler destroy_cb;
51+ gpointer user_data;
52+ gchar * type;
53+};
54+
55
56 #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv)
57 #define DBUSMENU_INTERFACE "com.canonical.dbusmenu"
58@@ -148,6 +157,7 @@
59 static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data);
60 static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data);
61 static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data);
62+static void type_handler_destroy (gpointer user_data);
63
64 /* Globals */
65 static GDBusNodeInfo * dbusmenu_node_info = NULL;
66@@ -310,7 +320,7 @@
67 priv->dbusproxy = 0;
68
69 priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal,
70- g_free, NULL);
71+ g_free, type_handler_destroy);
72
73 priv->delayed_idle = 0;
74 priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *));
75@@ -1153,17 +1163,17 @@
76 gboolean handled = FALSE;
77
78 const gchar * type;
79- DbusmenuClientTypeHandler newfunc = NULL;
80+ type_handler_t * th = NULL;
81
82 type = dbusmenu_menuitem_property_get(propdata->item, DBUSMENU_MENUITEM_PROP_TYPE);
83 if (type != NULL) {
84- newfunc = g_hash_table_lookup(priv->type_handlers, type);
85+ th = (type_handler_t *)g_hash_table_lookup(priv->type_handlers, type);
86 } else {
87- newfunc = g_hash_table_lookup(priv->type_handlers, DBUSMENU_CLIENT_TYPES_DEFAULT);
88+ th = (type_handler_t *)g_hash_table_lookup(priv->type_handlers, DBUSMENU_CLIENT_TYPES_DEFAULT);
89 }
90
91- if (newfunc != NULL) {
92- handled = newfunc(propdata->item, propdata->parent, propdata->client);
93+ if (th != NULL && th->cb != NULL) {
94+ handled = th->cb(propdata->item, propdata->parent, propdata->client, th->user_data);
95 }
96
97 #ifdef MASSIVEDEBUGGING
98@@ -1679,6 +1689,19 @@
99 return priv->root;
100 }
101
102+/* Remove the type handler when we're all done with it */
103+static void
104+type_handler_destroy (gpointer user_data)
105+{
106+ type_handler_t * th = (type_handler_t *)user_data;
107+ if (th->destroy_cb != NULL) {
108+ th->destroy_cb(th->client, th->type, th->user_data);
109+ }
110+ g_free(th->type);
111+ g_free(th);
112+ return;
113+}
114+
115 /**
116 dbusmenu_client_add_type_handler:
117 @client: Client where we're getting types coming in
118@@ -1703,6 +1726,37 @@
119 gboolean
120 dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc)
121 {
122+ return dbusmenu_client_add_type_handler_full(client, type, newfunc, NULL, NULL);
123+}
124+
125+/**
126+ dbusmenu_client_add_type_handler_full:
127+ @client: Client where we're getting types coming in
128+ @type: A text string that will be matched with the 'type'
129+ property on incoming menu items
130+ @newfunc: The function that will be executed with those new
131+ items when they come in.
132+ @user_data: Data passed to @newfunc when it is called
133+ @destroy_func: A function that is called when the type handler is
134+ removed (usually on client destruction) which will free
135+ the resources in @user_data.
136+
137+ This function connects into the type handling of the #DbusmenuClient.
138+ Every new menuitem that comes in immediately gets asked for it's
139+ properties. When we get those properties we check the 'type'
140+ property and look to see if it matches a handler that is known
141+ by the client. If so, the @newfunc function is executed on that
142+ #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem
143+ signal is sent.
144+
145+ In the future the known types will be sent to the server so that it
146+ can make choices about the menu item types availble.
147+
148+ Return value: If registering the new type was successful.
149+*/
150+gboolean
151+dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destroy_func)
152+{
153 g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), FALSE);
154 g_return_val_if_fail(type != NULL, FALSE);
155
156@@ -1723,6 +1777,14 @@
157 return FALSE;
158 }
159
160- g_hash_table_insert(priv->type_handlers, g_strdup(type), newfunc);
161+ type_handler_t * th = g_new0(type_handler_t, 1);
162+ th->client = client;
163+ th->cb = newfunc;
164+ th->destroy_cb = destroy_func;
165+ th->user_data = user_data;
166+ th->type = g_strdup(type);
167+
168+ g_hash_table_insert(priv->type_handlers, g_strdup(type), th);
169 return TRUE;
170 }
171+
172
173=== modified file 'libdbusmenu-glib/client.h'
174--- libdbusmenu-glib/client.h 2010-11-18 03:07:51 +0000
175+++ libdbusmenu-glib/client.h 2011-01-26 23:16:59 +0000
176@@ -110,7 +110,8 @@
177 DbusmenuClientPrivate * priv;
178 };
179
180-typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
181+typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
182+typedef void (*DbusmenuClientTypeDestroyHandler) (DbusmenuClient * client, const gchar * type, gpointer user_data);
183
184 GType dbusmenu_client_get_type (void);
185 DbusmenuClient * dbusmenu_client_new (const gchar * name,
186@@ -119,6 +120,11 @@
187 gboolean dbusmenu_client_add_type_handler (DbusmenuClient * client,
188 const gchar * type,
189 DbusmenuClientTypeHandler newfunc);
190+gboolean dbusmenu_client_add_type_handler_full (DbusmenuClient * client,
191+ const gchar * type,
192+ DbusmenuClientTypeHandler newfunc,
193+ gpointer user_data,
194+ DbusmenuClientTypeDestroyHandler destory_func);
195 void dbusmenu_client_send_event (DbusmenuClient * client,
196 gint id,
197 const gchar * name,
198
199=== modified file 'libdbusmenu-gtk/Makefile.am'
200--- libdbusmenu-gtk/Makefile.am 2011-01-21 16:35:55 +0000
201+++ libdbusmenu-gtk/Makefile.am 2011-01-26 23:16:59 +0000
202@@ -23,7 +23,8 @@
203 dbusmenu-gtk.h \
204 client.h \
205 menu.h \
206- menuitem.h
207+ menuitem.h \
208+ serializablemenuitem.h
209
210 libdbusmenu_gtk_la_SOURCES = \
211 client.h \
212@@ -33,7 +34,9 @@
213 menu.h \
214 menu.c \
215 menuitem.h \
216- menuitem.c
217+ menuitem.c \
218+ serializablemenuitem.h \
219+ serializablemenuitem.c
220
221 libdbusmenu_gtk_la_LDFLAGS = \
222 -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \
223
224=== modified file 'libdbusmenu-gtk/client.c'
225--- libdbusmenu-gtk/client.c 2011-01-18 21:59:36 +0000
226+++ libdbusmenu-gtk/client.c 2011-01-26 23:16:59 +0000
227@@ -54,8 +54,8 @@
228 static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient);
229 static void item_activate (DbusmenuClient * client, DbusmenuMenuitem * mi, guint timestamp, gpointer userdata);
230
231-static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
232-static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
233+static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
234+static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
235
236 static void process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value);
237 static void process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value);
238@@ -684,7 +684,7 @@
239 /* The base type handler that builds a plain ol'
240 GtkMenuItem to represent, well, the GtkMenuItem */
241 static gboolean
242-new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
243+new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
244 {
245 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
246 g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
247@@ -719,7 +719,7 @@
248 /* Type handler for the seperators where it builds
249 a GtkSeparator to act as the GtkMenuItem */
250 static gboolean
251-new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
252+new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
253 {
254 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
255 g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
256
257=== modified file 'libdbusmenu-gtk/dbusmenu-gtk.h'
258--- libdbusmenu-gtk/dbusmenu-gtk.h 2011-01-21 16:35:55 +0000
259+++ libdbusmenu-gtk/dbusmenu-gtk.h 2011-01-26 23:16:59 +0000
260@@ -36,5 +36,6 @@
261 #include <libdbusmenu-gtk/client.h>
262 #include <libdbusmenu-gtk/menu.h>
263 #include <libdbusmenu-gtk/menuitem.h>
264+#include <libdbusmenu-gtk/serializablemenuitem.h>
265
266 #endif /* __DBUSMENU_GLIB_H__ */
267
268=== modified file 'libdbusmenu-gtk/menuitem.h'
269--- libdbusmenu-gtk/menuitem.h 2010-12-13 13:40:01 +0000
270+++ libdbusmenu-gtk/menuitem.h 2011-01-26 23:16:59 +0000
271@@ -26,8 +26,8 @@
272 <http://www.gnu.org/licenses/>
273 */
274
275-#ifndef __DBUSMENU_GTKMENUITEM_H__
276-#define __DBUSMENU_GTKMENUITEM_H__ 1
277+#ifndef DBUSMENU_GTK_MENUITEM_H__
278+#define DBUSMENU_GTK_MENUITEM_H__ 1
279
280 #include <glib.h>
281 #include <gdk-pixbuf/gdk-pixbuf.h>
282
283=== added file 'libdbusmenu-gtk/serializablemenuitem.c'
284--- libdbusmenu-gtk/serializablemenuitem.c 1970-01-01 00:00:00 +0000
285+++ libdbusmenu-gtk/serializablemenuitem.c 2011-01-26 23:16:59 +0000
286@@ -0,0 +1,288 @@
287+/*
288+An object to act as a base class for easy GTK widgets that can be
289+transfered over dbusmenu.
290+
291+Copyright 2011 Canonical Ltd.
292+
293+Authors:
294+ Ted Gould <ted@canonical.com>
295+
296+This program is free software: you can redistribute it and/or modify it
297+under the terms of either or both of the following licenses:
298+
299+1) the GNU Lesser General Public License version 3, as published by the
300+Free Software Foundation; and/or
301+2) the GNU Lesser General Public License version 2.1, as published by
302+the Free Software Foundation.
303+
304+This program is distributed in the hope that it will be useful, but
305+WITHOUT ANY WARRANTY; without even the implied warranties of
306+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
307+PURPOSE. See the applicable version of the GNU Lesser General Public
308+License for more details.
309+
310+You should have received a copy of both the GNU Lesser General Public
311+License version 3 and version 2.1 along with this program. If not, see
312+<http://www.gnu.org/licenses/>
313+*/
314+
315+#ifdef HAVE_CONFIG_H
316+#include "config.h"
317+#endif
318+
319+#include "client.h"
320+#include "serializablemenuitem.h"
321+
322+/**
323+ DbusmenuGtkSerializableMenuItemPrivate:
324+ @mi: Menuitem to watch the property changes from
325+*/
326+struct _DbusmenuGtkSerializableMenuItemPrivate {
327+ DbusmenuMenuitem * mi;
328+};
329+
330+/* Properties */
331+enum {
332+ PROP_0,
333+ PROP_MENUITEM
334+};
335+
336+/* Private macro, only used in object init */
337+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_PRIVATE(o) \
338+(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemPrivate))
339+
340+/* Function prototypes */
341+static void dbusmenu_gtk_serializable_menu_item_class_init (DbusmenuGtkSerializableMenuItemClass *klass);
342+static void dbusmenu_gtk_serializable_menu_item_init (DbusmenuGtkSerializableMenuItem *self);
343+static void dbusmenu_gtk_serializable_menu_item_dispose (GObject *object);
344+static void dbusmenu_gtk_serializable_menu_item_finalize (GObject *object);
345+static void set_property (GObject * obj,
346+ guint id,
347+ const GValue * value,
348+ GParamSpec * pspec);
349+static void get_property (GObject * obj,
350+ guint id,
351+ GValue * value,
352+ GParamSpec * pspec);
353+
354+/* GObject boiler plate */
355+G_DEFINE_TYPE (DbusmenuGtkSerializableMenuItem, dbusmenu_gtk_serializable_menu_item, GTK_TYPE_MENU_ITEM);
356+
357+/* Initialize the stuff in the class structure */
358+static void
359+dbusmenu_gtk_serializable_menu_item_class_init (DbusmenuGtkSerializableMenuItemClass *klass)
360+{
361+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
362+
363+ g_type_class_add_private (klass, sizeof (DbusmenuGtkSerializableMenuItemPrivate));
364+
365+ object_class->dispose = dbusmenu_gtk_serializable_menu_item_dispose;
366+ object_class->finalize = dbusmenu_gtk_serializable_menu_item_finalize;
367+ object_class->set_property = set_property;
368+ object_class->get_property = get_property;
369+
370+ g_object_class_install_property (object_class, PROP_MENUITEM,
371+ g_param_spec_object(DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM, "DBusmenu Menuitem attached to item",
372+ "A menuitem who's properties are being watched and where changes should be watched for updates. It is the responsibility of subclasses to set up the signal handlers for those property changes.",
373+ DBUSMENU_TYPE_MENUITEM,
374+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
375+
376+ return;
377+}
378+
379+/* Initialize the object structures and private structure */
380+static void
381+dbusmenu_gtk_serializable_menu_item_init (DbusmenuGtkSerializableMenuItem *self)
382+{
383+ self->priv = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_PRIVATE(self);
384+
385+ self->priv->mi = NULL;
386+
387+ return;
388+}
389+
390+/* Free all references to objects */
391+static void
392+dbusmenu_gtk_serializable_menu_item_dispose (GObject *object)
393+{
394+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(object);
395+ g_return_if_fail(smi != NULL);
396+
397+ if (smi->priv->mi != NULL) {
398+ g_object_unref(G_OBJECT(smi->priv->mi));
399+ smi->priv->mi = NULL;
400+ }
401+
402+
403+ G_OBJECT_CLASS (dbusmenu_gtk_serializable_menu_item_parent_class)->dispose (object);
404+ return;
405+}
406+
407+/* Free memory */
408+static void
409+dbusmenu_gtk_serializable_menu_item_finalize (GObject *object)
410+{
411+
412+
413+
414+ G_OBJECT_CLASS (dbusmenu_gtk_serializable_menu_item_parent_class)->finalize (object);
415+ return;
416+}
417+
418+/* Set an object property */
419+static void
420+set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
421+{
422+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(obj);
423+
424+ switch (id) {
425+ case PROP_MENUITEM:
426+ smi->priv->mi = g_value_get_object(value);
427+ break;
428+ default:
429+ g_return_if_reached();
430+ break;
431+ }
432+
433+ return;
434+}
435+
436+/* Get an object property */
437+static void
438+get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
439+{
440+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(obj);
441+
442+ switch (id) {
443+ case PROP_MENUITEM:
444+ g_value_set_object(value, smi->priv->mi);
445+ break;
446+ default:
447+ g_return_if_reached();
448+ break;
449+ }
450+
451+ return;
452+}
453+
454+/**
455+ dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem:
456+ @smi: #DbusmenuGtkSerializableMenuItem to build a #DbusmenuMenuitem mirroring
457+
458+ This function is for menu items that are instanciated from
459+ GTK and have their properites set using GTK functions. This
460+ builds a #DbusmenuMenuitem that then has the properties that
461+ should be sent over the bus to create a new item of this
462+ type on the other side.
463+
464+ Return value: (transfer full) A #DbusmenuMenuitem who's values will be
465+ set by this object.
466+*/
467+DbusmenuMenuitem *
468+dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi)
469+{
470+ g_return_val_if_fail(DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(smi), NULL);
471+
472+ DbusmenuGtkSerializableMenuItemClass * klass = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_CLASS(smi);
473+ if (klass->build_dbusmenu_menuitem != NULL) {
474+ return klass->build_dbusmenu_menuitem(smi);
475+ }
476+
477+ return NULL;
478+}
479+
480+/* Callback to the generic type handler */
481+typedef struct _type_handler_t type_handler_t;
482+struct _type_handler_t {
483+ DbusmenuGtkSerializableMenuItemClass * class;
484+ GType type;
485+};
486+
487+/* Handle the type with this item. */
488+static gboolean
489+type_handler (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
490+{
491+ type_handler_t * th = (type_handler_t *)user_data;
492+
493+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(g_object_new(th->type, NULL));
494+ g_return_val_if_fail(smi != NULL, FALSE);
495+
496+ dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem(smi, newitem);
497+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(smi), parent);
498+
499+ return TRUE;
500+}
501+
502+/* Destruction is inevitable */
503+static void
504+type_destroy_handler (DbusmenuClient * client, const gchar * type, gpointer user_data)
505+{
506+ g_return_if_fail(user_data != NULL);
507+ type_handler_t * th = (type_handler_t *)user_data;
508+ g_type_class_unref(th->class);
509+ g_free(user_data);
510+ return;
511+}
512+
513+/**
514+ dbusmenu_gtk_serializable_menu_item_register_to_client:
515+ @client: #DbusmenuClient that we should register a type at.
516+ @item_type: The #GType of a class that is a subclass of #DbusmenuGtkSerializableMenuItem
517+
518+ Registers a generic handler for dealing with all subclasses of
519+ #DbusmenuGtkSerializableMenuItem. This handler responds to the callback,
520+ creates a new object and attaches it to the appropriate #DbusmenuMenuitem
521+ object.
522+*/
523+void
524+dbusmenu_gtk_serializable_menu_item_register_to_client (DbusmenuClient * client, GType item_type)
525+{
526+ g_return_if_fail(g_type_is_a(item_type, DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM));
527+
528+ gpointer type_class = g_type_class_ref(item_type);
529+ g_return_if_fail(type_class != NULL);
530+
531+ DbusmenuGtkSerializableMenuItemClass * class = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_CLASS(type_class);
532+
533+ if (class->get_type_string == NULL) {
534+ g_type_class_unref(type_class);
535+ g_error("No 'get_type_string' in subclass of DbusmenuGtkSerializableMenuItem");
536+ return;
537+ }
538+
539+ /* Register type */
540+ type_handler_t * th = g_new0(type_handler_t, 1);
541+ th->class = class;
542+ th->type = item_type;
543+ if (!dbusmenu_client_add_type_handler_full(client, class->get_type_string(), type_handler, th, type_destroy_handler)) {
544+ type_destroy_handler(client, class->get_type_string(), th);
545+ }
546+
547+ /* Register defaults */
548+ /* TODO: Need API on another branch */
549+
550+ return;
551+}
552+
553+/**
554+ dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem:
555+ @smi: #DbusmenuGtkSerializableMenuItem to set the @DbusmenuGtkSerializableMenuItem::dbusmenu-menuitem of
556+ @mi: Menuitem to get the properties from
557+
558+ This function is used on the server side to signal to the object
559+ that it should get its' property change events from @mi instead
560+ of expecting calls to its' API. A call to this function sets the
561+ property and subclasses should listen to the notify signal to
562+ pick up this property being set.
563+*/
564+void
565+dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi, DbusmenuMenuitem * mi)
566+{
567+ g_return_if_fail(DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(smi));
568+ g_return_if_fail(mi != NULL);
569+
570+ smi->priv->mi = mi;
571+ g_object_notify(G_OBJECT(smi), DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM);
572+
573+ return;
574+}
575
576=== added file 'libdbusmenu-gtk/serializablemenuitem.h'
577--- libdbusmenu-gtk/serializablemenuitem.h 1970-01-01 00:00:00 +0000
578+++ libdbusmenu-gtk/serializablemenuitem.h 2011-01-26 23:16:59 +0000
579@@ -0,0 +1,108 @@
580+/*
581+An object to act as a base class for easy GTK widgets that can be
582+transfered over dbusmenu.
583+
584+Copyright 2011 Canonical Ltd.
585+
586+Authors:
587+ Ted Gould <ted@canonical.com>
588+
589+This program is free software: you can redistribute it and/or modify it
590+under the terms of either or both of the following licenses:
591+
592+1) the GNU Lesser General Public License version 3, as published by the
593+Free Software Foundation; and/or
594+2) the GNU Lesser General Public License version 2.1, as published by
595+the Free Software Foundation.
596+
597+This program is distributed in the hope that it will be useful, but
598+WITHOUT ANY WARRANTY; without even the implied warranties of
599+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
600+PURPOSE. See the applicable version of the GNU Lesser General Public
601+License for more details.
602+
603+You should have received a copy of both the GNU Lesser General Public
604+License version 3 and version 2.1 along with this program. If not, see
605+<http://www.gnu.org/licenses/>
606+*/
607+
608+#ifndef DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_H__
609+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_H__ 1
610+
611+#include <glib.h>
612+#include <glib-object.h>
613+#include <gtk/gtk.h>
614+#include <libdbusmenu-glib/menuitem.h>
615+#include <libdbusmenu-glib/client.h>
616+
617+G_BEGIN_DECLS
618+
619+#define DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM (dbusmenu_gtk_serializable_menu_item_get_type ())
620+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItem))
621+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemClass))
622+#define DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM))
623+#define DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM))
624+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemClass))
625+
626+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM "dbusmenu-menuitem"
627+
628+typedef struct _DbusmenuGtkSerializableMenuItem DbusmenuGtkSerializableMenuItem;
629+typedef struct _DbusmenuGtkSerializableMenuItemClass DbusmenuGtkSerializableMenuItemClass;
630+typedef struct _DbusmenuGtkSerializableMenuItemPrivate DbusmenuGtkSerializableMenuItemPrivate;
631+
632+/**
633+ DbusmenuGtkSerializableMenuItemClass:
634+ @parent_class: Inherit from GtkMenuItem
635+ @get_type_string: Static function to get a string describing this type
636+ @get_default_properties: Return a hashtable of defaults for the menu item type
637+ @build_dbusmenu_menuitem: Build a menuitem that can be sent over dbus
638+ @_dbusmenu_gtk_serializable_menu_item_reserved1: Reserved for future use.
639+ @_dbusmenu_gtk_serializable_menu_item_reserved2: Reserved for future use.
640+ @_dbusmenu_gtk_serializable_menu_item_reserved3: Reserved for future use.
641+ @_dbusmenu_gtk_serializable_menu_item_reserved4: Reserved for future use.
642+ @_dbusmenu_gtk_serializable_menu_item_reserved5: Reserved for future use.
643+ @_dbusmenu_gtk_serializable_menu_item_reserved6: Reserved for future use.
644+*/
645+struct _DbusmenuGtkSerializableMenuItemClass {
646+ GtkMenuItemClass parent_class;
647+
648+ /* Subclassable functions */
649+ const gchar * (*get_type_string) (void);
650+ GHashTable * (*get_default_properties) (void);
651+
652+ DbusmenuMenuitem * (*build_dbusmenu_menuitem) (DbusmenuGtkSerializableMenuItem * smi);
653+
654+ /* Signals */
655+
656+
657+
658+ /* Empty Space */
659+ /*< Private >*/
660+ void (*_dbusmenu_gtk_serializable_menu_item_reserved1) (void);
661+ void (*_dbusmenu_gtk_serializable_menu_item_reserved2) (void);
662+ void (*_dbusmenu_gtk_serializable_menu_item_reserved3) (void);
663+ void (*_dbusmenu_gtk_serializable_menu_item_reserved4) (void);
664+ void (*_dbusmenu_gtk_serializable_menu_item_reserved5) (void);
665+ void (*_dbusmenu_gtk_serializable_menu_item_reserved6) (void);
666+};
667+
668+/**
669+ DbusmenuGtkSerializableMenuItem:
670+ @parent: Inherit from GtkMenuItem
671+ @priv: Blind structure of private variables
672+*/
673+struct _DbusmenuGtkSerializableMenuItem {
674+ GtkMenuItem parent;
675+
676+ DbusmenuGtkSerializableMenuItemPrivate * priv;
677+};
678+
679+GType dbusmenu_gtk_serializable_menu_item_get_type (void);
680+
681+DbusmenuMenuitem * dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi);
682+void dbusmenu_gtk_serializable_menu_item_register_to_client (DbusmenuClient * client, GType item_type);
683+void dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi, DbusmenuMenuitem * mi);
684+
685+G_END_DECLS
686+
687+#endif

Subscribers

People subscribed via source and target branches