diff options
Diffstat (limited to 'ubuntu_gtk_custom_menu_items.patch')
-rw-r--r-- | ubuntu_gtk_custom_menu_items.patch | 185 |
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 + |