Merge lp:~ted/libdbusmenu/serializable-menuitem into lp:libdbusmenu/0.5
- serializable-menuitem
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mikkel Kamstrup Erlandsen (community) | Needs Fixing | ||
Review via email: mp+47604@code.launchpad.net |
Commit message
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.
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
Ted Gould (ted) wrote : | # |
On Thu, 2011-01-27 at 09:49 +0000, Mikkel Kamstrup Erlandsen wrote:
> The function prototypes DbusmenuClientT
> DbusmenuClientT
r215
> Can we avoid double namespacing on these two functions?:
>
> dbusmenu_
> dbusmenu_
>
> Becomes:
>
> dbusmenu_
> dbusmenu_
Yes, was looking for a good way to shorten these, thanks!
r214
> Can you add some section docs describing what the purpose of
> DbusmenuGtkSeri
> reviewing this code I am still not entirely sure what it's
> supposed to do :-)
r216
Preview Diff
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 |
The function prototypes DbusmenuClientT ypeHandler and DbusmenuClientT ypeDestroyHandl er needs documentation.
Can we avoid double namespacing on these two functions?:
dbusmenu_ gtk_serializabl e_menu_ item_build_ dbusmenu_ menuitem( ) gtk_serializabl e_menu_ item_set_ dbusmenu_ menuitem( )
dbusmenu_
Becomes:
dbusmenu_ gtk_serializabl e_menu_ item_build_ menuitem( ) gtk_serializabl e_menu_ item_set_ menuitem( )
dbusmenu_
Can you add some section docs describing what the purpose of DbusmenuGtkSeri alizableMenuIte m is, and how to use it? After reviewing this code I am still not entirely sure what it's supposed to do :-)