aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-gtk
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r--libdbusmenu-gtk/Makefile.am8
-rw-r--r--libdbusmenu-gtk/client.c40
-rw-r--r--libdbusmenu-gtk/genericmenuitem-enum-types.h.in2
-rw-r--r--libdbusmenu-gtk/genericmenuitem.c4
-rw-r--r--libdbusmenu-gtk/genericmenuitem.h2
-rw-r--r--libdbusmenu-gtk/menu.c2
-rw-r--r--libdbusmenu-gtk/parser.c163
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