1
From 59168f3c1a72f610b693cd1ed4cfa5fac281079a Mon Sep 17 00:00:00 2001
2
From: Lars Uebernickel <lars.uebernickel@canonical.com>
3
Date: Wed, 6 Nov 2013 14:48:19 +0100
4
Subject: [PATCH] Add UbuntuMenuItemFactory
6
UbuntuMenuItemFactory is an interface for creating widgets for menu
7
items in a GMenuModel that have an 'x-canonical-type' attribute.
9
It is needed by unity and should not be considered public API.
11
gtk/Makefile.am | 3 ++
12
gtk/gtkmenushell.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
13
gtk/gtkmenutrackeritem.c | 16 +++++++++++
14
gtk/gtkmenutrackeritem.h | 4 +++
15
gtk/ubuntu-private.h | 32 +++++++++++++++++++++
16
gtk/ubuntumenuitemfactory.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
17
gtk/ubuntumenuitemfactory.h | 61 +++++++++++++++++++++++++++++++++++++++
18
7 files changed, 255 insertions(+)
19
create mode 100644 gtk/ubuntu-private.h
20
create mode 100644 gtk/ubuntumenuitemfactory.c
21
create mode 100644 gtk/ubuntumenuitemfactory.h
23
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
24
index 51153e6..3c01638 100644
27
@@ -108,6 +108,8 @@ include $(srcdir)/inspector/Makefile.inc
28
gtk_public_h_sources = \
32
+ ubuntumenuitemfactory.h \
36
@@ -528,6 +530,7 @@ gtk_base_c_sources = \
38
$(deprecated_c_sources) \
39
$(inspector_c_sources) \
40
+ ubuntumenuitemfactory.c \
43
gtkactionobservable.c \
44
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
45
index e1ba138..6d7a2f6 100644
46
--- a/gtk/gtkmenushell.c
47
+++ b/gtk/gtkmenushell.c
50
#include "a11y/gtkmenushellaccessible.h"
52
+#include "ubuntu-private.h"
55
#define MENU_SHELL_TIMEOUT 500
56
#define MENU_POPUP_DELAY 225
57
@@ -2044,6 +2046,58 @@ gtk_menu_shell_tracker_remove_func (gint position,
58
gtk_widget_destroy (child);
62
+create_custom_menu_item (GMenuItem *item,
64
+ const gchar *action_namespace)
67
+ GActionGroup *actions;
68
+ GtkMenuItem *widget = NULL;
71
+ g_menu_item_get_attribute (item, "x-canonical-type", "s", &type);
73
+ if (action_namespace)
77
+ /* Rewrite the menu item to include the fully qualified action
78
+ * name to make writing widgets easier. This won't break, as
79
+ * we don't use the tracker item for custom items.
81
+ if (g_menu_item_get_attribute (item, "action", "s", &action))
85
+ fullname = g_strconcat (action_namespace, ".", action, NULL);
86
+ g_menu_item_set_attribute (item, "action", "s", fullname);
93
+ /* Passing the parent muxer is wrong, but we'll only have access
94
+ * to the menuitem's muxer after the widget has been created.
95
+ * Thus we'd need some other form of passing the action group to
96
+ * the widget, which would complicate things for no practical
97
+ * reason: the panel service is the only consumer of this API and
98
+ * it will never call gtk_widget_insert_action_group() on the
99
+ * returned menu item.
101
+ actions = G_ACTION_GROUP (_gtk_widget_get_action_muxer (parent, TRUE));
103
+ for (it = ubuntu_menu_item_factory_get_all (); it != NULL && widget == NULL; it = it->next)
104
+ widget = ubuntu_menu_item_factory_create_menu_item (it->data, type, item, actions);
106
+ if (widget == NULL)
107
+ g_warning ("Cannot create custom menu item of type '%s'", type);
110
+ return GTK_WIDGET (widget);
114
gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
116
@@ -2051,6 +2105,9 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
118
GtkMenuShell *menu_shell = user_data;
120
+ GMenuItem *menuitem;
122
+ menuitem = gtk_menu_tracker_item_get_menu_item (item);
124
if (gtk_menu_tracker_item_get_is_separator (item))
126
@@ -2112,6 +2169,18 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
128
gtk_widget_show (widget);
130
+ else if (g_menu_item_get_attribute (menuitem, "x-canonical-type", "s", NULL))
132
+ const gchar *namespace;
134
+ namespace = gtk_menu_tracker_item_get_action_namespace (item);
135
+ widget = create_custom_menu_item (menuitem, GTK_WIDGET (menu_shell), namespace);
137
+ if (widget == NULL)
140
+ gtk_widget_show (widget);
144
widget = gtk_model_menu_item_new ();
145
diff --git a/gtk/gtkmenutrackeritem.c b/gtk/gtkmenutrackeritem.c
146
index c304b66..cd0c796 100644
147
--- a/gtk/gtkmenutrackeritem.c
148
+++ b/gtk/gtkmenutrackeritem.c
149
@@ -979,3 +979,19 @@ gtk_menu_tracker_item_may_disappear (GtkMenuTrackerItem *self)
151
return self->hidden_when != HIDDEN_NEVER;
155
+gtk_menu_tracker_item_get_menu_item (GtkMenuTrackerItem *self)
157
+ g_return_val_if_fail (GTK_IS_MENU_TRACKER_ITEM (self), NULL);
163
+gtk_menu_tracker_item_get_action_namespace (GtkMenuTrackerItem *self)
165
+ g_return_val_if_fail (GTK_IS_MENU_TRACKER_ITEM (self), NULL);
167
+ return self->action_namespace;
169
diff --git a/gtk/gtkmenutrackeritem.h b/gtk/gtkmenutrackeritem.h
170
index 6b4fcb5..d74fe92 100644
171
--- a/gtk/gtkmenutrackeritem.h
172
+++ b/gtk/gtkmenutrackeritem.h
173
@@ -92,4 +92,8 @@ void gtk_menu_tracker_item_request_submenu_shown (GtkMenu
175
gboolean gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self);
177
+GMenuItem * gtk_menu_tracker_item_get_menu_item (GtkMenuTrackerItem *self);
179
+const gchar * gtk_menu_tracker_item_get_action_namespace (GtkMenuTrackerItem *self);
182
diff --git a/gtk/ubuntu-private.h b/gtk/ubuntu-private.h
184
index 0000000..3ed366f
186
+++ b/gtk/ubuntu-private.h
189
+* Copyright 2013 Canonical Ltd.
191
+* This program is free software: you can redistribute it and/or modify it
192
+* under the terms of the GNU General Public License version 3, as published
193
+* by the Free Software Foundation.
195
+* This program is distributed in the hope that it will be useful, but
196
+* WITHOUT ANY WARRANTY; without even the implied warranties of
197
+* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
198
+* PURPOSE. See the GNU General Public License for more details.
200
+* You should have received a copy of the GNU General Public License along
201
+* with this program. If not, see <http://www.gnu.org/licenses/>.
204
+* Lars Uebernickel <lars.uebernickel@canonical.com>
208
+ * Warning: this file is not part of gtk+, but an Ubuntu-specific extension.
209
+ * The API provided here is meant to be used only from Unity.
211
+ * Applications should not use this.
214
+#ifndef __UBUNTU_PRIVATE_H__
215
+#define __UBUNTU_PRIVATE_H__
217
+#include "ubuntumenuitemfactory.h"
220
diff --git a/gtk/ubuntumenuitemfactory.c b/gtk/ubuntumenuitemfactory.c
222
index 0000000..24eb214
224
+++ b/gtk/ubuntumenuitemfactory.c
227
+* Copyright 2013 Canonical Ltd.
229
+* This program is free software: you can redistribute it and/or modify it
230
+* under the terms of the GNU General Public License version 3, as published
231
+* by the Free Software Foundation.
233
+* This program is distributed in the hope that it will be useful, but
234
+* WITHOUT ANY WARRANTY; without even the implied warranties of
235
+* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
236
+* PURPOSE. See the GNU General Public License for more details.
238
+* You should have received a copy of the GNU General Public License along
239
+* with this program. If not, see <http://www.gnu.org/licenses/>.
242
+* Lars Uebernickel <lars.uebernickel@canonical.com>
246
+#include "ubuntumenuitemfactory.h"
248
+G_DEFINE_INTERFACE_WITH_CODE (UbuntuMenuItemFactory, ubuntu_menu_item_factory, G_TYPE_OBJECT,
249
+ GIOExtensionPoint *ep = g_io_extension_point_register (UBUNTU_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME);
250
+ g_io_extension_point_set_required_type (ep, g_define_type_id);)
253
+ * ubuntu_menu_item_factory_get_all:
255
+ * Returns a static list of all registered factories.
258
+ubuntu_menu_item_factory_get_all (void)
260
+ static GList *factories = NULL;
262
+ if (factories == NULL)
264
+ GIOExtensionPoint *ep;
267
+ g_type_ensure (UBUNTU_TYPE_MENU_ITEM_FACTORY);
268
+ ep = g_io_extension_point_lookup (UBUNTU_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME);
269
+ for (it = g_io_extension_point_get_extensions (ep); it != NULL; it = it->next)
271
+ GIOExtension *ext = it->data;
272
+ UbuntuMenuItemFactory *factory;
274
+ factory = g_object_new (g_io_extension_get_type (ext), NULL);
275
+ factories = g_list_prepend (factories, factory);
277
+ factories = g_list_reverse (factories);
284
+ubuntu_menu_item_factory_default_init (UbuntuMenuItemFactoryInterface *iface)
289
+ubuntu_menu_item_factory_create_menu_item (UbuntuMenuItemFactory *factory,
291
+ GMenuItem *menuitem,
292
+ GActionGroup *actions)
294
+ return UBUNTU_MENU_ITEM_FACTORY_GET_IFACE (factory)->create_menu_item (factory, type, menuitem, actions);
296
diff --git a/gtk/ubuntumenuitemfactory.h b/gtk/ubuntumenuitemfactory.h
298
index 0000000..e97539d
300
+++ b/gtk/ubuntumenuitemfactory.h
303
+* Copyright 2013 Canonical Ltd.
305
+* This program is free software: you can redistribute it and/or modify it
306
+* under the terms of the GNU General Public License version 3, as published
307
+* by the Free Software Foundation.
309
+* This program is distributed in the hope that it will be useful, but
310
+* WITHOUT ANY WARRANTY; without even the implied warranties of
311
+* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
312
+* PURPOSE. See the GNU General Public License for more details.
314
+* You should have received a copy of the GNU General Public License along
315
+* with this program. If not, see <http://www.gnu.org/licenses/>.
318
+* Lars Uebernickel <lars.uebernickel@canonical.com>
321
+#ifndef __UBUNTU_MENU_ITEM_FACTORY_H__
322
+#define __UBUNTU_MENU_ITEM_FACTORY_H__
324
+#include <gtk/gtkmenuitem.h>
328
+#define UBUNTU_TYPE_MENU_ITEM_FACTORY (ubuntu_menu_item_factory_get_type ())
329
+#define UBUNTU_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), UBUNTU_TYPE_MENU_ITEM_FACTORY, UbuntuMenuItemFactory))
330
+#define UBUNTU_IS_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), UBUNTU_TYPE_MENU_ITEM_FACTORY))
331
+#define UBUNTU_MENU_ITEM_FACTORY_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), UBUNTU_TYPE_MENU_ITEM_FACTORY, UbuntuMenuItemFactoryInterface))
333
+#define UBUNTU_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME "ubuntu-menu-item-factory"
335
+typedef struct _UbuntuMenuItemFactoryInterface UbuntuMenuItemFactoryInterface;
336
+typedef struct _UbuntuMenuItemFactory UbuntuMenuItemFactory;
338
+struct _UbuntuMenuItemFactoryInterface
340
+ GTypeInterface iface;
342
+ GtkMenuItem * (*create_menu_item) (UbuntuMenuItemFactory *factory,
344
+ GMenuItem *menuitem,
345
+ GActionGroup *actions);
348
+GDK_AVAILABLE_IN_3_10
349
+GList * ubuntu_menu_item_factory_get_all (void);
351
+GDK_AVAILABLE_IN_3_10
352
+GType ubuntu_menu_item_factory_get_type (void);
354
+GDK_AVAILABLE_IN_3_10
355
+GtkMenuItem * ubuntu_menu_item_factory_create_menu_item (UbuntuMenuItemFactory *factory,
357
+ GMenuItem *menuitem,
358
+ GActionGroup *actions);