summarylogtreecommitdiffstats
path: root/ubuntu_gtk_custom_menu_items.patch
diff options
context:
space:
mode:
Diffstat (limited to 'ubuntu_gtk_custom_menu_items.patch')
-rw-r--r--ubuntu_gtk_custom_menu_items.patch185
1 files changed, 185 insertions, 0 deletions
diff --git a/ubuntu_gtk_custom_menu_items.patch b/ubuntu_gtk_custom_menu_items.patch
new file mode 100644
index 000000000000..70d9d0326b6a
--- /dev/null
+++ b/ubuntu_gtk_custom_menu_items.patch
@@ -0,0 +1,185 @@
+From 59168f3c1a72f610b693cd1ed4cfa5fac281079a Mon Sep 17 00:00:00 2001
+From: Lars Uebernickel <lars.uebernickel@canonical.com>
+Date: Wed, 6 Nov 2013 14:48:19 +0100
+Subject: [PATCH] Add UbuntuMenuItemFactory
+
+UbuntuMenuItemFactory is an interface for creating widgets for menu
+items in a GMenuModel that have an 'x-canonical-type' attribute.
+
+It is needed by unity and should not be considered public API.
+---
+ gtk/Makefile.am | 3 ++
+ gtk/gtkmenushell.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
+ gtk/gtkmenutrackeritem.c | 16 +++++++++++
+ gtk/gtkmenutrackeritem.h | 4 +++
+ gtk/ubuntu-private.h | 32 +++++++++++++++++++++
+ gtk/ubuntumenuitemfactory.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
+ gtk/ubuntumenuitemfactory.h | 61 +++++++++++++++++++++++++++++++++++++++
+ 7 files changed, 255 insertions(+)
+ create mode 100644 gtk/ubuntu-private.h
+ create mode 100644 gtk/ubuntumenuitemfactory.c
+ create mode 100644 gtk/ubuntumenuitemfactory.h
+
+diff --git a/gtk/Makefile.am b/gtk/Makefile.am
+index 51153e6..3c01638 100644
+--- a/gtk/Makefile.am
++++ b/gtk/Makefile.am
+@@ -108,6 +108,8 @@ include $(srcdir)/inspector/Makefile.inc
+ gtk_public_h_sources = \
+ gtk.h \
+ gtk-autocleanups.h \
++ ubuntu-private.h \
++ ubuntumenuitemfactory.h \
+ gtkx.h \
+ gtkx-autocleanups.h \
+ gtk-a11y.h \
+@@ -528,6 +530,7 @@ gtk_base_c_sources = \
+ $(a11y_c_sources) \
+ $(deprecated_c_sources) \
+ $(inspector_c_sources) \
++ ubuntumenuitemfactory.c \
+ gtkactionmuxer.c \
+ gtkactionobserver.c \
+ gtkactionobservable.c \
+diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
+index e1ba138..6d7a2f6 100644
+--- a/gtk/gtkmenushell.c
++++ b/gtk/gtkmenushell.c
+@@ -80,6 +80,8 @@
+
+ #include "a11y/gtkmenushellaccessible.h"
+
++#include "ubuntu-private.h"
++
+
+ #define MENU_SHELL_TIMEOUT 500
+ #define MENU_POPUP_DELAY 225
+@@ -2044,6 +2046,58 @@ gtk_menu_shell_tracker_remove_func (gint position,
+ gtk_widget_destroy (child);
+ }
+
++static GtkWidget *
++create_custom_menu_item (GMenuItem *item,
++ GtkWidget *parent,
++ const gchar *action_namespace)
++{
++ gchar *type;
++ GActionGroup *actions;
++ GtkMenuItem *widget = NULL;
++ GList *it;
++
++ g_menu_item_get_attribute (item, "x-canonical-type", "s", &type);
++
++ if (action_namespace)
++ {
++ gchar *action;
++
++ /* Rewrite the menu item to include the fully qualified action
++ * name to make writing widgets easier. This won't break, as
++ * we don't use the tracker item for custom items.
++ */
++ if (g_menu_item_get_attribute (item, "action", "s", &action))
++ {
++ gchar *fullname;
++
++ fullname = g_strconcat (action_namespace, ".", action, NULL);
++ g_menu_item_set_attribute (item, "action", "s", fullname);
++
++ g_free (fullname);
++ g_free (action);
++ }
++ }
++
++ /* Passing the parent muxer is wrong, but we'll only have access
++ * to the menuitem's muxer after the widget has been created.
++ * Thus we'd need some other form of passing the action group to
++ * the widget, which would complicate things for no practical
++ * reason: the panel service is the only consumer of this API and
++ * it will never call gtk_widget_insert_action_group() on the
++ * returned menu item.
++ */
++ actions = G_ACTION_GROUP (_gtk_widget_get_action_muxer (parent, TRUE));
++
++ for (it = ubuntu_menu_item_factory_get_all (); it != NULL && widget == NULL; it = it->next)
++ widget = ubuntu_menu_item_factory_create_menu_item (it->data, type, item, actions);
++
++ if (widget == NULL)
++ g_warning ("Cannot create custom menu item of type '%s'", type);
++
++ g_free (type);
++ return GTK_WIDGET (widget);
++}
++
+ static void
+ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
+ gint position,
+@@ -2051,6 +2105,9 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
+ {
+ GtkMenuShell *menu_shell = user_data;
+ GtkWidget *widget;
++ GMenuItem *menuitem;
++
++ menuitem = gtk_menu_tracker_item_get_menu_item (item);
+
+ if (gtk_menu_tracker_item_get_is_separator (item))
+ {
+@@ -2112,6 +2169,18 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
+
+ gtk_widget_show (widget);
+ }
++ else if (g_menu_item_get_attribute (menuitem, "x-canonical-type", "s", NULL))
++ {
++ const gchar *namespace;
++
++ namespace = gtk_menu_tracker_item_get_action_namespace (item);
++ widget = create_custom_menu_item (menuitem, GTK_WIDGET (menu_shell), namespace);
++
++ if (widget == NULL)
++ return;
++
++ gtk_widget_show (widget);
++ }
+ else
+ {
+ widget = gtk_model_menu_item_new ();
+diff --git a/gtk/gtkmenutrackeritem.c b/gtk/gtkmenutrackeritem.c
+index c304b66..cd0c796 100644
+--- a/gtk/gtkmenutrackeritem.c
++++ b/gtk/gtkmenutrackeritem.c
+@@ -979,3 +979,19 @@ gtk_menu_tracker_item_may_disappear (GtkMenuTrackerItem *self)
+ {
+ return self->hidden_when != HIDDEN_NEVER;
+ }
++
++GMenuItem *
++gtk_menu_tracker_item_get_menu_item (GtkMenuTrackerItem *self)
++{
++ g_return_val_if_fail (GTK_IS_MENU_TRACKER_ITEM (self), NULL);
++
++ return self->item;
++}
++
++const gchar *
++gtk_menu_tracker_item_get_action_namespace (GtkMenuTrackerItem *self)
++{
++ g_return_val_if_fail (GTK_IS_MENU_TRACKER_ITEM (self), NULL);
++
++ return self->action_namespace;
++}
+diff --git a/gtk/gtkmenutrackeritem.h b/gtk/gtkmenutrackeritem.h
+index 6b4fcb5..d74fe92 100644
+--- a/gtk/gtkmenutrackeritem.h
++++ b/gtk/gtkmenutrackeritem.h
+@@ -92,4 +92,8 @@ void gtk_menu_tracker_item_request_submenu_shown (GtkMenu
+
+ gboolean gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self);
+
++GMenuItem * gtk_menu_tracker_item_get_menu_item (GtkMenuTrackerItem *self);
++
++const gchar * gtk_menu_tracker_item_get_action_namespace (GtkMenuTrackerItem *self);
++
+ #endif
+
+--
+2.1.4
+