diff options
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r-- | libdbusmenu-gtk/Makefile.am | 8 | ||||
-rw-r--r-- | libdbusmenu-gtk/client.c | 40 | ||||
-rw-r--r-- | libdbusmenu-gtk/genericmenuitem-enum-types.h.in | 2 | ||||
-rw-r--r-- | libdbusmenu-gtk/genericmenuitem.c | 4 | ||||
-rw-r--r-- | libdbusmenu-gtk/genericmenuitem.h | 2 | ||||
-rw-r--r-- | libdbusmenu-gtk/menu.c | 2 | ||||
-rw-r--r-- | libdbusmenu-gtk/parser.c | 163 |
7 files changed, 170 insertions, 51 deletions
diff --git a/libdbusmenu-gtk/Makefile.am b/libdbusmenu-gtk/Makefile.am index b10bea0..ff8555e 100644 --- a/libdbusmenu-gtk/Makefile.am +++ b/libdbusmenu-gtk/Makefile.am @@ -157,14 +157,14 @@ if HAVE_VALA if HAVE_INTROSPECTION vapidir = $(datadir)/vala/vapi -vapi_DATA = dbusmenu-gtk$(VER)-0.4.vapi +vapi_DATA = DbusmenuGtk$(VER)-0.4.vapi -dbusmenu-gtk$(VER)-0.4.vapi: DbusmenuGtk$(VER)-0.4.tmp.gir Makefile.am - $(VALA_API_GEN) --library=dbusmenu-gtk$(VER)-0.4 \ +DbusmenuGtk$(VER)-0.4.vapi: DbusmenuGtk$(VER)-0.4.tmp.gir Makefile.am + $(VALA_API_GEN) --library=DbusmenuGtk$(VER)-0.4 \ --pkg gdk-pixbuf-2.0 \ --pkg $(GTKVALA) \ --pkg atk \ - --pkg dbusmenu-glib-0.4 \ + --pkg Dbusmenu-0.4 \ --vapidir=$(top_builddir)/libdbusmenu-glib \ $< diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 60af93f..d345313 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -130,16 +130,31 @@ dbusmenu_gtkclient_init (DbusmenuGtkClient *self) return; } +static void +clear_shortcut_foreach (DbusmenuMenuitem *mi, gpointer gclient) +{ + guint key = 0; + GtkMenuItem * gmi; + GdkModifierType mod = 0; + DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT (gclient); + + gmi = dbusmenu_gtkclient_menuitem_get (client, mi); + dbusmenu_gtkclient_menuitem_get (client, mi); + dbusmenu_menuitem_property_get_shortcut (mi, &key, &mod); + if (key) + gtk_widget_remove_accelerator (GTK_WIDGET (gmi), client->priv->agroup, key, mod); +} + /* Just calling the super class. Future use. */ static void dbusmenu_gtkclient_dispose (GObject *object) { - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(object); + DbusmenuMenuitem * root; + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT(object)->priv; - if (priv->agroup != NULL) { - g_object_unref(priv->agroup); - priv->agroup = NULL; - } + if ((root = dbusmenu_client_get_root (DBUSMENU_CLIENT(object)))) + dbusmenu_menuitem_foreach (root, clear_shortcut_foreach, object); + g_clear_object (&priv->agroup); if (priv->old_themedirs) { remove_theme_dirs(gtk_icon_theme_get_default(), priv->old_themedirs); @@ -161,7 +176,6 @@ dbusmenu_gtkclient_dispose (GObject *object) static void dbusmenu_gtkclient_finalize (GObject *object) { - G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->finalize (object); return; } @@ -193,7 +207,7 @@ theme_dir_ref (GtkIconTheme * theme, GHashTable * db, const gchar * dir) return; } -/* Unreference the theme directory, and if it's count goes to zero then +/* Unreference the theme directory, and if its count goes to zero then we need to remove it from the search path. */ static void theme_dir_unref (GtkIconTheme * theme, GHashTable * db, const gchar * dir) @@ -361,8 +375,6 @@ do_swap_agroup (DbusmenuMenuitem * mi, gpointer userdata) { static void swap_agroup (DbusmenuMenuitem *mi, gpointer userdata) { do_swap_agroup (mi, userdata); - - return; /* See what I did here, Ted? :) */ } /* Refresh the shortcut for an entry */ @@ -462,7 +474,7 @@ static const gchar * data_delayed_close = "dbusmenugtk-data-delayed-close"; static void menu_item_start_activating(DbusmenuMenuitem * mi) { - /* Mark this item and all it's parents as activating */ + /* Mark this item and all its parents as activating */ DbusmenuMenuitem * parent = mi; do { g_object_set_data(G_OBJECT(parent), data_activating, @@ -485,7 +497,7 @@ menu_item_stop_activating(DbusmenuMenuitem * mi) if (!menu_item_is_activating(mi)) return; - /* Mark this item and all it's parents as not activating and finally + /* Mark this item and all its parents as not activating and finally send their queued close event. */ g_object_set_data(G_OBJECT(mi), data_activating, GINT_TO_POINTER(FALSE)); @@ -1180,7 +1192,11 @@ image_property_handle (DbusmenuMenuitem * item, const gchar * property, GVariant /* If we have an image already built from a name that is way better than a pixbuf. Keep it. */ if (gtkimage != NULL && (gtk_image_get_storage_type(GTK_IMAGE(gtkimage)) == GTK_IMAGE_ICON_NAME || gtk_image_get_storage_type(GTK_IMAGE(gtkimage)) == GTK_IMAGE_EMPTY)) { - return; + const gchar *icon_name = NULL; + gtk_image_get_icon_name (GTK_IMAGE(gtkimage), &icon_name, NULL); + if ((icon_name != NULL) && gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), icon_name)) { + return; + } } } diff --git a/libdbusmenu-gtk/genericmenuitem-enum-types.h.in b/libdbusmenu-gtk/genericmenuitem-enum-types.h.in index 5758438..afd9132 100644 --- a/libdbusmenu-gtk/genericmenuitem-enum-types.h.in +++ b/libdbusmenu-gtk/genericmenuitem-enum-types.h.in @@ -43,7 +43,7 @@ G_END_DECLS /*** END file-tail ***/ /*** BEGIN file-production ***/ -/* Enumerations from file: "@filename@" */ +/* Enumerations from file: "@basename@" */ #include "@basename@" /*** END file-production ***/ diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 75bdbbd..9707ba3 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -1,6 +1,6 @@ /* A menuitem subclass that has the ability to do lots of different -things depending on it's settings. +things depending on its settings. Copyright 2009 Canonical Ltd. @@ -279,7 +279,7 @@ set_label (GtkMenuItem * menu_item, const gchar * in_label) gchar * local_label = NULL; switch (GENERICMENUITEM(menu_item)->priv->disposition) { case GENERICMENUITEM_DISPOSITION_NORMAL: - local_label = g_strdup(in_label); + local_label = g_markup_escape_text(in_label, -1); break; case GENERICMENUITEM_DISPOSITION_INFORMATIONAL: case GENERICMENUITEM_DISPOSITION_WARNING: diff --git a/libdbusmenu-gtk/genericmenuitem.h b/libdbusmenu-gtk/genericmenuitem.h index 0b7df55..0164f13 100644 --- a/libdbusmenu-gtk/genericmenuitem.h +++ b/libdbusmenu-gtk/genericmenuitem.h @@ -1,6 +1,6 @@ /* A menuitem subclass that has the ability to do lots of different -things depending on it's settings. +things depending on its settings. Copyright 2009 Canonical Ltd. diff --git a/libdbusmenu-gtk/menu.c b/libdbusmenu-gtk/menu.c index 236a596..3ec419a 100644 --- a/libdbusmenu-gtk/menu.c +++ b/libdbusmenu-gtk/menu.c @@ -296,7 +296,7 @@ root_child_delete (DbusmenuMenuitem * root, DbusmenuMenuitem * child, DbusmenuGt return; } -/* Called when the child is realized, and thus has all of it's +/* Called when the child is realized, and thus has all of its properties and GTK-isms. We can put it in our menu here. */ static void child_realized (DbusmenuMenuitem * child, gpointer userdata) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 2f7277c..b09e984 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -60,6 +60,10 @@ typedef struct _ParserData gulong widget_accel_handler_id; gulong widget_toggle_handler_id; gulong widget_visible_handler_id; + gulong widget_screen_changed_handler_id; + + GtkSettings *settings; + gulong settings_notify_handler_id; } ParserData; @@ -116,6 +120,12 @@ static void widget_notify_cb (GtkWidget * widget, static void widget_add_cb (GtkWidget * widget, GtkWidget * child, gpointer data); +static void widget_screen_changed_cb (GtkWidget * widget, + GdkScreen * old_screen, + gpointer data); +static void settings_notify_cb (GtkSettings * settings, + GParamSpec * pspec, + gpointer data); static gboolean should_show_image (GtkImage * image); static void menuitem_notify_cb (GtkWidget * widget, GParamSpec * pspec, @@ -130,6 +140,7 @@ static const char * interned_str_active = NULL; static const char * interned_str_always_show_image = NULL; static const char * interned_str_file = NULL; static const char * interned_str_gicon = NULL; +static const char * interned_str_gtk_menu_images = NULL; static const char * interned_str_icon_name = NULL; static const char * interned_str_icon_set = NULL; static const char * interned_str_image = NULL; @@ -155,6 +166,7 @@ ensure_interned_strings_loaded (void) interned_str_always_show_image = g_intern_static_string ("always-show-image"); interned_str_file = g_intern_static_string ("file"); interned_str_gicon = g_intern_static_string ("gicon"); + interned_str_gtk_menu_images = g_intern_static_string ("gtk-menu-images"); interned_str_icon_name = g_intern_static_string ("icon-name"); interned_str_icon_set = g_intern_static_string ("icon-set"); interned_str_image = g_intern_static_string ("image"); @@ -261,10 +273,47 @@ dbusmenu_gtk_parse_menu_structure (GtkWidget * widget) DbusmenuMenuitem * dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget) { - if (!GTK_IS_MENU_ITEM(widget)) { - return NULL; - } - return DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM)); + GObject * o = NULL; + DbusmenuMenuitem * ret = NULL; + + if (GTK_IS_MENU_ITEM (widget)) + o = g_object_get_data (G_OBJECT(widget), CACHED_MENUITEM); + + if (o && DBUSMENU_IS_MENUITEM(o)) + ret = DBUSMENU_MENUITEM (o); + + return ret; +} + +/* remove our dbusmenuitem's hooks to a GtkWidget, + such as when either of them are being destroyed */ +static void +disconnect_from_widget (GtkWidget * widget) +{ + ParserData * pdata = parser_data_get_from_widget (widget); + + if (pdata && pdata->widget) + { + GObject * o; + + g_assert (pdata->widget == widget); + + /* stop listening to signals from the widget */ + o = G_OBJECT (pdata->widget); + dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_notify_handler_id); + dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_add_handler_id); + dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_accel_handler_id); + dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_toggle_handler_id); + dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_visible_handler_id); + dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_screen_changed_handler_id); + + /* clear the menuitem's widget pointer */ + g_object_remove_weak_pointer (o, (gpointer*)&pdata->widget); + pdata->widget = NULL; + + /* clear the widget's menuitem pointer */ + g_object_set_data(o, CACHED_MENUITEM, NULL); + } } static void @@ -285,16 +334,13 @@ parser_data_free (ParserData * pdata) } if (pdata->widget != NULL) { - GObject * o = G_OBJECT(pdata->widget); - dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_notify_handler_id); - dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_add_handler_id); - dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_accel_handler_id); - dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_toggle_handler_id); - dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_visible_handler_id); - g_object_remove_weak_pointer(o, (gpointer*)&pdata->widget); - - /* since the DbusmenuMenuitem is being destroyed, uncache it from the GtkWidget */ - g_object_steal_data(o, CACHED_MENUITEM); + disconnect_from_widget (pdata->widget); + } + + if (pdata->settings != NULL) { + dbusmenu_gtk_clear_signal_handler (pdata->settings, + &pdata->settings_notify_handler_id); + g_object_unref (pdata->settings); } if (pdata->shell != NULL) { @@ -321,7 +367,7 @@ parser_data_free (ParserData * pdata) return; } -/* Gets the positon of the child with its' parent if it has one. +/* Gets the positon of the child with its parent if it has one. Returns -1 if the position is unable to be calculated. */ static gint get_child_position (GtkWidget * child) @@ -360,7 +406,7 @@ new_menuitem (GtkWidget * widget) pdata->widget = widget; g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget); - g_object_set_data(G_OBJECT(widget), CACHED_MENUITEM, item); + g_object_set_data_full(G_OBJECT(widget), CACHED_MENUITEM, g_object_ref(item), g_object_unref); return item; } @@ -746,6 +792,10 @@ construct_dbusmenu_for_widget (GtkWidget * widget) pdata->widget_add_handler_id = g_signal_connect (widget, "add", G_CALLBACK (widget_add_cb), mi); + pdata->widget_screen_changed_handler_id = g_signal_connect (widget, "screen-changed", + G_CALLBACK (widget_screen_changed_cb), mi); + widget_screen_changed_cb (widget, NULL, mi); + return mi; } @@ -1098,6 +1148,14 @@ item_activated (DbusmenuMenuitem *item, guint timestamp, gpointer user_data) if (GTK_IS_MENU_ITEM (child)) { + GtkWidget *parent = gtk_widget_get_parent(child); + if (GTK_IS_MENU (parent)) + { + gint pos = get_child_position (child); + if (pos >= 0) + gtk_menu_set_active (GTK_MENU(parent), pos); + } + gdk_threads_enter (); gtk_menu_item_activate (GTK_MENU_ITEM (child)); gdk_threads_leave (); @@ -1282,6 +1340,56 @@ widget_add_cb (GtkWidget *widget, handle_first_label (data); } +/* Pass NULL for pspec to update all settings at once */ +static void +widget_screen_changed_cb (GtkWidget * widget, GdkScreen * old_screen, gpointer data) +{ + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); + g_return_if_fail (mi != NULL); + + ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA); + + if (pdata->settings != NULL) + { + dbusmenu_gtk_clear_signal_handler (pdata->settings, + &pdata->settings_notify_handler_id); + g_object_unref (pdata->settings); + } + + pdata->settings = g_object_ref (gtk_widget_get_settings (widget)); + pdata->settings_notify_handler_id = g_signal_connect (pdata->settings, "notify", + G_CALLBACK (settings_notify_cb), mi); + + /* And update widget now that we have a new GtkSettings */ + settings_notify_cb (gtk_widget_get_settings (widget), NULL, mi); +} + +/* Pass NULL for pspec to update all settings at once */ +static void +settings_notify_cb (GtkSettings * settings, GParamSpec * pspec, gpointer data) +{ + GValue prop_value = {0}; + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); + g_return_if_fail (mi != NULL); + + ensure_interned_strings_loaded (); + + if (pspec != NULL) + { + g_value_init (&prop_value, pspec->value_type); + g_object_get_property (G_OBJECT (settings), pspec->name, &prop_value); + } + + if (pspec == NULL || pspec->name == interned_str_gtk_menu_images) + { + ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA); + update_icon (mi, pdata, GTK_IMAGE(pdata->image)); + } + + if (pspec != NULL) + g_value_unset (&prop_value); +} + /* A child item was added to a menu we're watching. Let's try to integrate it. */ static void item_inserted_cb (GtkContainer *menu, @@ -1306,24 +1414,19 @@ item_inserted_cb (GtkContainer *menu, /* A child item was removed from a menu we're watching. */ static void -item_removed_cb (GtkContainer *menu, GtkWidget *widget, gpointer data) +item_removed_cb (GtkContainer *parent_w, GtkWidget *child_w, gpointer data) { - gpointer pmi = g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM); - if (pmi == NULL) { - return; - } - - DbusmenuMenuitem * child = DBUSMENU_MENUITEM(pmi); + DbusmenuMenuitem * child_mi; - pmi = g_object_get_data(G_OBJECT(menu), CACHED_MENUITEM); - if (pmi == NULL) { - return; - } + if ((child_mi = dbusmenu_gtk_parse_get_cached_item (child_w))) + { + DbusmenuMenuitem * parent_mi; - DbusmenuMenuitem * parent = DBUSMENU_MENUITEM(pmi); + if ((parent_mi = dbusmenu_gtk_parse_get_cached_item (GTK_WIDGET(parent_w)))) + dbusmenu_menuitem_child_delete (parent_mi, child_mi); - dbusmenu_menuitem_child_delete(parent, child); - return; + disconnect_from_widget (child_w); + } } static gboolean |