[Xfce4-commits] <xfdesktop:master> Add menu item monitoring.

Nick Schermer noreply at xfce.org
Fri Nov 5 17:02:05 CET 2010


Updating branch refs/heads/master
         to 8efb089a60786d99fee1fdb7e7ae880d53bcc20b (commit)
       from bdf0e01e099628d978df4650dfdf65f6c79fdd71 (commit)

commit 8efb089a60786d99fee1fdb7e7ae880d53bcc20b
Author: Nick Schermer <nick at xfce.org>
Date:   Fri Nov 5 16:56:02 2010 +0100

    Add menu item monitoring.
    
    Reload the garcon menu if the reload-required signal is triggered
    and make XfdesktopAppMenuItem use the data inside GarconMenuItem.
    
    I've dropped the cache since it's not function as it should be,
    and because the GarconMenu is not destroyed, the menu information
    is still presereved in memory. This could be improved tho.
    
    Because the menu items are destroyed to between 2 popups, the
    changed-signal in the GarconMenuItem isn't very functional either,
    but it is implemented.

 src/menu.c                    |    5 -
 src/xfce-desktop-menu.c       |  205 +++------
 src/xfce-desktop-menu.h       |    6 -
 src/xfdesktop-app-menu-item.c |  926 +++++++++--------------------------------
 src/xfdesktop-app-menu-item.h |   52 +--
 5 files changed, 261 insertions(+), 933 deletions(-)

diff --git a/src/menu.c b/src/menu.c
index 4376d27..2e35f30 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -49,7 +49,6 @@ static gboolean show_desktop_menu_icons = TRUE;
 static void
 _stop_menu_module(void) {
     if(desktop_menu) {
-        xfce_desktop_menu_stop_autoregen(desktop_menu);
         xfce_desktop_menu_destroy(desktop_menu);
         desktop_menu = NULL;
     }
@@ -61,7 +60,6 @@ _start_menu_module(void)
     desktop_menu = xfce_desktop_menu_new(NULL, TRUE);
     if(desktop_menu) {
         xfce_desktop_menu_set_show_icons(desktop_menu, show_desktop_menu_icons);
-        xfce_desktop_menu_start_autoregen(desktop_menu, 10);
         return TRUE;
     } else {
         g_warning("%s: Unable to initialise menu module. Right-click menu will be unavailable.\n", PACKAGE);
@@ -84,9 +82,6 @@ menu_populate(XfceDesktop *desktop,
     if(!desktop_menu)
         return;
     
-    if(xfce_desktop_menu_need_update(desktop_menu))
-        xfce_desktop_menu_force_regen(desktop_menu);
-    
     /* check to see if the menu is empty.  if not, add the desktop menu
      * to a submenu */
     menu_children = gtk_container_get_children(GTK_CONTAINER(menu));
diff --git a/src/xfce-desktop-menu.c b/src/xfce-desktop-menu.c
index 74dc488..cc5b7fc 100644
--- a/src/xfce-desktop-menu.c
+++ b/src/xfce-desktop-menu.c
@@ -1,5 +1,5 @@
 /*  xfce4
- *  
+ *
  *  Copyright (C) 2002-2003 Jasper Huijsmans (huysmans at users.sourceforge.net)
  *                     2003 Biju Chacko (botsie at users.sourceforge.net)
  *                     2004 Danny Milosavljevic <danny.milo at gmx.net>
@@ -71,13 +71,10 @@ struct _XfceDesktopMenu
 {
     GarconMenu *garcon_menu;
 
-    gboolean cache_menu_items;
-    GList *menu_item_cache;
-	
     gchar *filename;  /* file the menu is currently using */
-    
+
     gboolean use_menu_icons;  /* show menu icons? */
-	
+
     gint idle_id;  /* source id for idled generation */
 };
 
@@ -89,21 +86,18 @@ static gboolean _generate_menu_idled(gpointer data);
 static gboolean _generate_menu(XfceDesktopMenu *desktop_menu);
 static void desktop_menu_add_items(XfceDesktopMenu *desktop_menu,
                                    GarconMenu *garcon_menu,
-                                   GtkWidget *menu,
-                                   GList **menu_items_return);
+                                   GtkWidget *menu);
 
 static void
-itheme_changed_cb(GtkIconTheme *itheme, gpointer user_data)
+xfce_desktop_menu_reload(XfceDesktopMenu *desktop_menu)
 {
-    XfceDesktopMenu *desktop_menu = user_data;
-
     /* this fixes bugs 3615 and 4342.  if both the .desktop files
      * and icon theme change very quickly after each other, we'll
      * get a crash when the icon theme gets regenerated when calling
      * gtk_icon_theme_lookup_icon(), which triggers a recursive regen.
      * so we'll idle the regen, and make sure we don't enter it
      * recursively.  same deal for _something_changed(). */
-
+    DBG("Schedule menu reload");
     if(!desktop_menu->idle_id)
         desktop_menu->idle_id = g_idle_add(_generate_menu_idled, desktop_menu);
 }
@@ -117,8 +111,7 @@ itheme_changed_cb(GtkIconTheme *itheme, gpointer user_data)
 static void
 desktop_menu_add_items(XfceDesktopMenu *desktop_menu,
                        GarconMenu *garcon_menu,
-                       GtkWidget *menu,
-                       GList **menu_items_return)
+                       GtkWidget *menu)
 {
     GList *items, *l;
     GtkWidget *submenu, *mi, *img;
@@ -127,9 +120,9 @@ desktop_menu_add_items(XfceDesktopMenu *desktop_menu,
     GarconMenuItem *garcon_item;
     const gchar *name, *icon_name;
 
-    g_return_if_fail((menu && !menu_items_return)
-                     || (!menu && menu_items_return));
-    
+    g_return_if_fail(GTK_IS_MENU(menu));
+    g_return_if_fail(GARCON_IS_MENU(garcon_menu));
+
     items = garcon_menu_get_elements(garcon_menu);
     for(l = items; l; l = l->next) {
         if(!garcon_menu_element_get_visible(l->data))
@@ -140,15 +133,15 @@ desktop_menu_add_items(XfceDesktopMenu *desktop_menu,
             garcon_submenu = l->data;
             garcon_directory = garcon_menu_get_directory(garcon_submenu);
             icon_name = NULL;
-            
+
             submenu = gtk_menu_new();
             gtk_widget_show(submenu);
-            
+
             if(garcon_directory) {
                 if(desktop_menu->use_menu_icons)
                     icon_name = garcon_menu_directory_get_icon_name(garcon_directory);
             }
-            
+
             name = garcon_menu_element_get_name(GARCON_MENU_ELEMENT(garcon_submenu));
 
             mi = gtk_image_menu_item_new_with_label(name);
@@ -161,14 +154,11 @@ desktop_menu_add_items(XfceDesktopMenu *desktop_menu,
             gtk_widget_show(mi);
             gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), submenu);
 
-            if(menu)
-                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
-            else
-                *menu_items_return = g_list_prepend(*menu_items_return, mi);
-            
+            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
+
             desktop_menu_add_items(desktop_menu, garcon_submenu,
-                                   submenu, NULL);
-            
+                                   submenu);
+
             /* we have to check emptiness down here instead of at the top of the
              * loop because there may be further submenus that are empty */
             if(!(tmpl = gtk_container_get_children(GTK_CONTAINER(submenu))))
@@ -179,32 +169,17 @@ desktop_menu_add_items(XfceDesktopMenu *desktop_menu,
             mi = gtk_separator_menu_item_new();
             gtk_widget_show(mi);
 
-            if(menu)
-                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
-            else
-                *menu_items_return = g_list_prepend(*menu_items_return, mi);
+            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
         } else if(GARCON_IS_MENU_ITEM(l->data)) {
             garcon_item = l->data;
-            
-            mi = xfdesktop_app_menu_item_new_full(garcon_menu_element_get_name(GARCON_MENU_ELEMENT(garcon_item)),
-                                                  garcon_menu_item_get_command(garcon_item),
-                                                  desktop_menu->use_menu_icons
-                                                    ? garcon_menu_item_get_icon_name(garcon_item)
-                                                    : NULL,
-                                                  garcon_menu_item_requires_terminal(garcon_item),
-                                                  garcon_menu_item_supports_startup_notification(garcon_item));
+
+            mi = xfdesktop_app_menu_item_new (GARCON_MENU_ITEM (garcon_item));
             gtk_widget_show(mi);
 
-            if(menu)
-                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
-            else
-                *menu_items_return = g_list_prepend(*menu_items_return, mi);
+            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
         }
     }
     g_list_free(items);
-
-    if(menu_items_return)
-        *menu_items_return = g_list_reverse(*menu_items_return);
 }
 
 static gboolean
@@ -214,7 +189,7 @@ _generate_menu(XfceDesktopMenu *desktop_menu)
     XfceKiosk *kiosk;
     gboolean user_menu;
     GError *error = NULL;
-    
+
     _xfce_desktop_menu_free_menudata(desktop_menu);
 
     if(!desktop_menu->filename) {
@@ -225,9 +200,12 @@ _generate_menu(XfceDesktopMenu *desktop_menu)
     kiosk = xfce_kiosk_new("xfdesktop");
     user_menu = xfce_kiosk_query(kiosk, "UserMenu");
     xfce_kiosk_free(kiosk);
-    
+
     DBG("menu file name is %s", desktop_menu->filename);
 
+    if(desktop_menu->garcon_menu)
+        g_object_unref(G_OBJECT(desktop_menu->garcon_menu));
+
     desktop_menu->garcon_menu = garcon_menu_new_for_path(desktop_menu->filename);
 
     if(!garcon_menu_load (desktop_menu->garcon_menu, NULL, &error)) {
@@ -238,10 +216,8 @@ _generate_menu(XfceDesktopMenu *desktop_menu)
         return FALSE;
     }
 
-    if(desktop_menu->cache_menu_items) {
-        desktop_menu_add_items(desktop_menu, desktop_menu->garcon_menu,
-                               NULL, &desktop_menu->menu_item_cache);
-    }
+    g_signal_connect_swapped(desktop_menu->garcon_menu, "reload-required",
+                             G_CALLBACK(xfce_desktop_menu_reload), desktop_menu);
 
     return ret;
 }
@@ -249,18 +225,11 @@ _generate_menu(XfceDesktopMenu *desktop_menu)
 static void
 _xfce_desktop_menu_free_menudata(XfceDesktopMenu *desktop_menu)
 {
-    if(desktop_menu->menu_item_cache) {
-        g_list_foreach(desktop_menu->menu_item_cache,
-                       (GFunc)gtk_widget_destroy, NULL);
-        g_list_free(desktop_menu->menu_item_cache);
-        desktop_menu->menu_item_cache = NULL;
-    }
-
     if(desktop_menu->garcon_menu) {
         g_object_unref(G_OBJECT(desktop_menu->garcon_menu));
         desktop_menu->garcon_menu = NULL;
     }
-    
+
     desktop_menu->garcon_menu = NULL;
 }
 
@@ -268,24 +237,13 @@ static gboolean
 _generate_menu_idled(gpointer data)
 {
     XfceDesktopMenu *desktop_menu = data;
-    
+
     g_return_val_if_fail(data != NULL, FALSE);
-    
+
     _generate_menu(desktop_menu);
     desktop_menu->idle_id = 0;
-    
-    return FALSE;
-}
 
-static void
-desktop_menu_recache(gpointer data,
-                     GObject *where_the_object_was)
-{
-    XfceDesktopMenu *desktop_menu = data;
-    if(!desktop_menu->menu_item_cache) {
-        desktop_menu_add_items(desktop_menu, desktop_menu->garcon_menu,
-                               NULL, &desktop_menu->menu_item_cache);
-    }
+    return FALSE;
 }
 
 static gchar *
@@ -301,7 +259,7 @@ xfce_desktop_get_menufile(void)
     kiosk = xfce_kiosk_new("xfdesktop");
     user_menu = xfce_kiosk_query(kiosk, "UserMenu");
     xfce_kiosk_free(kiosk);
-    
+
     if(user_menu) {
         gchar *file = xfce_resource_save_location(XFCE_RESOURCE_CONFIG,
                                                   "menus/xfce-applications.menu",
@@ -314,7 +272,7 @@ xfce_desktop_get_menufile(void)
                 g_free(file);
         }
     }
-    
+
     all_dirs = xfce_resource_lookup_all(XFCE_RESOURCE_CONFIG,
                                         "menus/xfce-applications.menu");
     for(i = 0; all_dirs[i]; i++) {
@@ -342,13 +300,14 @@ xfce_desktop_menu_new(const gchar *menu_file,
     XfceDesktopMenu *desktop_menu = g_new0(XfceDesktopMenu, 1);
 
     desktop_menu->use_menu_icons = TRUE;
-    desktop_menu->cache_menu_items = TRUE;  /* FIXME: hidden pref? */
-    
+
+    garcon_set_environment("XFCE");
+
     if(menu_file)
         desktop_menu->filename = g_strdup(menu_file);
     else
         desktop_menu->filename = xfce_desktop_get_menufile();
-    
+
     if(deferred)
         desktop_menu->idle_id = g_idle_add(_generate_menu_idled, desktop_menu);
     else {
@@ -358,12 +317,10 @@ xfce_desktop_menu_new(const gchar *menu_file,
         }
     }
 
-    garcon_set_environment("XFCE");
-
     _deskmenu_icon_theme = gtk_icon_theme_get_default();
-    g_signal_connect(G_OBJECT(_deskmenu_icon_theme), "changed",
-                     G_CALLBACK(itheme_changed_cb), desktop_menu);
-    
+    g_signal_connect_swapped(G_OBJECT(_deskmenu_icon_theme), "changed",
+                     G_CALLBACK(xfce_desktop_menu_reload), desktop_menu);
+
     return desktop_menu;
 }
 
@@ -372,7 +329,7 @@ xfce_desktop_menu_populate_menu(XfceDesktopMenu *desktop_menu,
                                      GtkWidget *menu)
 {
     g_return_if_fail(desktop_menu && menu);
-    
+
     if(!desktop_menu->garcon_menu) {
         if(desktop_menu->idle_id) {
             g_source_remove(desktop_menu->idle_id);
@@ -383,64 +340,27 @@ xfce_desktop_menu_populate_menu(XfceDesktopMenu *desktop_menu,
             return;
     }
 
-    if(desktop_menu->menu_item_cache) {
-        GList *l;
-        for(l = desktop_menu->menu_item_cache; l; l = l->next)
-            gtk_menu_shell_append(GTK_MENU_SHELL(menu), l->data);
-        g_list_free(desktop_menu->menu_item_cache);
-        desktop_menu->menu_item_cache = NULL;
-        g_object_weak_ref(G_OBJECT(menu), desktop_menu_recache,
-                          desktop_menu);
-    } else {
-        desktop_menu_add_items(desktop_menu, desktop_menu->garcon_menu,
-                               GTK_WIDGET(menu), NULL);
-    }
+    desktop_menu_add_items(desktop_menu, desktop_menu->garcon_menu,
+                           GTK_WIDGET(menu));
 }
 
 GtkWidget *
 xfce_desktop_menu_get_widget(XfceDesktopMenu *desktop_menu)
 {
     GtkWidget *menu;
-    
+
     g_return_val_if_fail(desktop_menu != NULL, NULL);
-    
+
     menu = gtk_menu_new();
-    
+
     xfce_desktop_menu_populate_menu(desktop_menu, menu);
-    
+
     if(!desktop_menu->garcon_menu) {
-        gtk_widget_destroy(menu);
-        return NULL;
+       gtk_widget_destroy(menu);
+       return NULL;
     }
-    
-    return menu;
-}
-
-G_CONST_RETURN gchar *
-xfce_desktop_menu_get_menu_file(XfceDesktopMenu *desktop_menu)
-{
-    g_return_val_if_fail(desktop_menu != NULL, NULL);
-    
-    return desktop_menu->filename;
-}
-
-gboolean
-xfce_desktop_menu_need_update(XfceDesktopMenu *desktop_menu)
-{
-    return FALSE;
-}
 
-void
-xfce_desktop_menu_start_autoregen(XfceDesktopMenu *desktop_menu,
-                                       guint delay)
-{
-    /* noop */
-}
-
-void
-xfce_desktop_menu_stop_autoregen(XfceDesktopMenu *desktop_menu)
-{
-    /* noop */
+    return menu;
 }
 
 void
@@ -448,7 +368,7 @@ xfce_desktop_menu_force_regen(XfceDesktopMenu *desktop_menu)
 {
     TRACE("dummy");
     g_return_if_fail(desktop_menu != NULL);
-    
+
     if(desktop_menu->idle_id) {
         g_source_remove(desktop_menu->idle_id);
         desktop_menu->idle_id = 0;
@@ -462,9 +382,10 @@ xfce_desktop_menu_set_show_icons(XfceDesktopMenu *desktop_menu,
                                       gboolean show_icons)
 {
     g_return_if_fail(desktop_menu != NULL);
-    
+
     if(desktop_menu->use_menu_icons != show_icons) {
         desktop_menu->use_menu_icons = show_icons;
+        xfdesktop_app_menu_item_set_show_icon(show_icons);
         if(desktop_menu->idle_id) {
             g_source_remove(desktop_menu->idle_id);
             desktop_menu->idle_id = 0;
@@ -477,18 +398,26 @@ void
 xfce_desktop_menu_destroy(XfceDesktopMenu *desktop_menu)
 {
     g_return_if_fail(desktop_menu != NULL);
-    TRACE("dummy");
-    
+    TRACE("menu destroyed");
+
     if(desktop_menu->idle_id) {
         g_source_remove(desktop_menu->idle_id);
         desktop_menu->idle_id = 0;
     }
-    
+
     g_signal_handlers_disconnect_by_func(_deskmenu_icon_theme,
-                                         G_CALLBACK(itheme_changed_cb),
+                                         G_CALLBACK(xfce_desktop_menu_reload),
                                          desktop_menu);
-    
+
     _xfce_desktop_menu_free_menudata(desktop_menu);
+
     g_free(desktop_menu->filename);
+
+    if(desktop_menu->garcon_menu) {
+        g_signal_handlers_disconnect_by_func(desktop_menu->garcon_menu,
+            G_CALLBACK(xfce_desktop_menu_reload), desktop_menu);
+        g_object_unref(G_OBJECT(desktop_menu->garcon_menu));
+    }
+
     g_free(desktop_menu);
 }
diff --git a/src/xfce-desktop-menu.h b/src/xfce-desktop-menu.h
index 5c20168..71e8dc6 100644
--- a/src/xfce-desktop-menu.h
+++ b/src/xfce-desktop-menu.h
@@ -20,7 +20,6 @@
 #define _XFCE_DESKTOP_MENU_H_
 
 #include "xfce-desktop.h"
-
 #include <xfconf/xfconf.h>
 
 G_BEGIN_DECLS
@@ -32,11 +31,6 @@ XfceDesktopMenu *xfce_desktop_menu_new(const gchar *menu_file,
 void xfce_desktop_menu_populate_menu(XfceDesktopMenu *desktop_menu,
                                           GtkWidget *menu);
 GtkWidget *xfce_desktop_menu_get_widget(XfceDesktopMenu *desktop_menu);
-G_CONST_RETURN gchar *xfce_desktop_menu_get_menu_file(XfceDesktopMenu *desktop_menu);
-gboolean xfce_desktop_menu_need_update(XfceDesktopMenu *desktop_menu);
-void xfce_desktop_menu_start_autoregen(XfceDesktopMenu *desktop_menu,
-                                            guint delay);
-void xfce_desktop_menu_stop_autoregen(XfceDesktopMenu *desktop_menu);
 void xfce_desktop_menu_force_regen(XfceDesktopMenu *desktop_menu);
 void xfce_desktop_menu_set_show_icons(XfceDesktopMenu *desktop_menu,
                                            gboolean show_icons);
diff --git a/src/xfdesktop-app-menu-item.c b/src/xfdesktop-app-menu-item.c
index 9d486c8..0bfddb9 100644
--- a/src/xfdesktop-app-menu-item.c
+++ b/src/xfdesktop-app-menu-item.c
@@ -39,17 +39,8 @@ struct _XfdesktopAppMenuItem
 {
     GtkImageMenuItem parent;
 
-    gchar *name;
-    gchar *command;
-    gboolean needs_term;
-    gboolean snotify;
-    gchar *icon_name;
-    gchar *icon_path;
-    gboolean icon_set;
-    
-    gchar *command_expanded;
-    gchar *dot_desktop_filename;
-    
+    GarconMenuItem *item;
+
     GtkWidget *accel_label;
 };
 
@@ -60,15 +51,11 @@ typedef struct _XfdesktopAppMenuItemClass
 
 enum
 {
-    PROP_ZERO = 0,
-    PROP_TERM,
-    PROP_CMD,
-    PROP_ICON,
-    PROP_LABEL,
-    PROP_SNOTIFY,
-    PROP_USE_UNDERLINE,
+    PROP_0,
+    PROP_ITEM
 };
 
+
 static void xfdesktop_app_menu_item_set_property(GObject *object,
                                                  guint prop_id,
                                                  const GValue *value,
@@ -79,220 +66,41 @@ static void xfdesktop_app_menu_item_get_property(GObject *object,
                                                  GParamSpec *pspec);
 static void xfdesktop_app_menu_item_finalize(GObject *object);
 
-static void xfdesktop_app_menu_item_realize(GtkWidget *widget);
+static void xfdesktop_app_menu_item_changed(XfdesktopAppMenuItem *app_menu_item);
 
-static void xfdesktop_app_menu_item_update_icon(XfdesktopAppMenuItem *app_menu_item);
-
-static void _command_activate_cb(GtkMenuItem *menu_item,
-                                 gpointer user_data);
+static void xfdesktop_app_menu_item_activate(XfdesktopAppMenuItem *app_menu_item);
 
 
 G_DEFINE_TYPE(XfdesktopAppMenuItem, xfdesktop_app_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
 
 
-static void
-_style_set_cb(GtkWidget *w, GtkStyle *prev_style, gpointer user_data)
-{
-    GtkStyle *style;
-    GList *children, *l;
-    
-    style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
-                                      "GtkMenuItem", "GtkMenuItem",
-                                      GTK_TYPE_IMAGE_MENU_ITEM);
-    children = gtk_container_get_children(GTK_CONTAINER(w));
-    for(l = children; l; l = l->next) {
-        if(GTK_IS_WIDGET(l->data))
-            gtk_widget_set_style(GTK_WIDGET(l->data), style);
-    }
-    g_list_free(children);
-}
 
-static void
-_expand_percent_vars(XfdesktopAppMenuItem *app_menu_item)
-{
-    GString *newstr;
-    gchar *p;
-    
-    g_return_if_fail(app_menu_item->command);
-    
-    newstr = g_string_sized_new(strlen(app_menu_item->command) + 1);
-    
-    for(p = app_menu_item->command; *p; ++p) {
-        if('%' == *p) {
-            ++p;
-            switch(*p) {
-                /* we don't care about these since we aren't passing filenames */
-                case 'f':
-                case 'F':
-                case 'u':
-                case 'U':
-                /* these are all deprecated */
-                case 'd':
-                case 'D':
-                case 'n':
-                case 'N':
-                case 'v':
-                case 'm':
-                    break;
-                
-                case 'i':
-                    if(G_LIKELY(app_menu_item->icon_name)) {
-                        gchar *str = g_shell_quote(app_menu_item->icon_name);
-                        g_string_append(newstr, "--icon ");
-                        g_string_append(newstr, str);
-                        g_free(str);
-                    }
-                    break;
-                
-                case 'c':
-                    if(G_LIKELY(app_menu_item->name)) {
-                        gchar *name_locale, *str;
-                        gsize bread = 0;
-                        GError *error = NULL;
-                        
-                        name_locale = g_locale_from_utf8(app_menu_item->name,
-                                                         -1, &bread, NULL,
-                                                         &error);
-                        if(name_locale) {
-                            str = g_shell_quote(name_locale);
-                            g_string_append(newstr, str);
-                            g_free(str);
-                            g_free(name_locale);
-                        } else {
-                            g_warning("Invalid UTF-8 in Name at byte %u: %s",
-                                      (guint)bread, error->message);
-                        }
-                    }
-                    break;
-                
-                case 'k':
-                    if(app_menu_item->dot_desktop_filename) {
-                        gchar *str = g_shell_quote(app_menu_item->dot_desktop_filename);
-                        g_string_append(newstr, str);
-                        g_free(str);
-                    }
-                    break;
-                
-                case '%':
-                    g_string_append_c(newstr, '%');
-                    break;
-                
-                default:
-                    g_warning("Invalid field code in Exec line: %%%c", *p);
-                    break;
-            }
-        } else
-            g_string_append_c(newstr, *p);
-    }
-        
-    app_menu_item->command_expanded = newstr->str;
-    g_string_free(newstr, FALSE);
-}
+static gboolean global_show_icons = TRUE;
+
 
-static void
-_command_activate_cb(GtkMenuItem *menu_item,
-                     gpointer user_data)
-{
-    XfdesktopAppMenuItem *app_menu_item = XFDESKTOP_APP_MENU_ITEM(menu_item);
-    
-    g_return_if_fail(app_menu_item && app_menu_item->command);
-    
-    /* we do this here instead of in _new*() for 2 reasons:
-     *   1. menu items that never get activated won't slow us down for no
-     *      reason.
-     *   2. we can't guarantee that the icon name or whatever (which can
-     *      influence the result of _expand_percent_vars()) has been set
-     *      when the command is first set.
-     */
-    if(!app_menu_item->command_expanded)
-        _expand_percent_vars(app_menu_item);
-    
-    if(!xfce_spawn_command_line_on_screen(gtk_widget_get_screen(GTK_WIDGET(menu_item)),
-                                          app_menu_item->command_expanded,
-                                          app_menu_item->needs_term,
-                                          app_menu_item->snotify, NULL))
-    {
-        g_warning("XfdesktopAppMenuItem: unable to spawn %s\n",
-                  app_menu_item->command_expanded);
-    }
-}
 
 static void
 xfdesktop_app_menu_item_class_init(XfdesktopAppMenuItemClass *klass)
 {
     GObjectClass *gobject_class = (GObjectClass *)klass;
-    GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
 
-    widget_class->realize = xfdesktop_app_menu_item_realize;
-    
     gobject_class->finalize = xfdesktop_app_menu_item_finalize;
     gobject_class->set_property = xfdesktop_app_menu_item_set_property;
     gobject_class->get_property = xfdesktop_app_menu_item_get_property;
-    
-    g_object_class_install_property(gobject_class, PROP_TERM,
-                                    g_param_spec_boolean("needs-term",
-                                                         _("Needs terminal"), 
-                                                         _("Whether or not the command needs a terminal to execute"),
-                                                         FALSE,
-                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
-    
-    g_object_class_install_property(gobject_class, PROP_CMD,
-                                    g_param_spec_string("command",
-                                                        _("Command"),
-                                                        _("The command to run when the item is clicked"),
-                                                        NULL,
-                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
-    
-    g_object_class_install_property(gobject_class, PROP_ICON,
-                                    g_param_spec_string("icon-name",
-                                                        _("Icon name"),
-                                                        _("The name of the themed icon to display next to the item"),
-                                                        NULL,
-                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
-    
-    g_object_class_install_property(gobject_class, PROP_LABEL,
-                                    g_param_spec_string("label",
-                                                        _("Label"),
-                                                        _("The label displayed in the item"),
-                                                        NULL,
-                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
-    
-    g_object_class_install_property(gobject_class, PROP_SNOTIFY,
-                                    g_param_spec_boolean("snotify",
-                                                         _("Startup notification"),
-                                                         _("Whether or not the app supports startup notification"),
-                                                         FALSE,
-                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
-    
-    g_object_class_install_property(gobject_class, PROP_USE_UNDERLINE,
-                                    g_param_spec_boolean("use-underline",
-                                                         _("Use underline"),
-                                                         _("Whether or not to use an underscore in the label as a keyboard mnemonic"),
-                                                         FALSE,
-                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+    g_object_class_install_property(gobject_class, PROP_ITEM,
+                                    g_param_spec_object("item", NULL, NULL,
+                                                        GARCON_TYPE_MENU_ITEM,
+                                                        G_PARAM_STATIC_STRINGS
+                                                        | G_PARAM_READWRITE
+                                                        | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
 xfdesktop_app_menu_item_init(XfdesktopAppMenuItem *app_menu_item)
 {
-    GtkWidget *accel_label;
-    
-    gtk_widget_add_events(GTK_WIDGET(app_menu_item),
-                          GDK_STRUCTURE_MASK | GDK_SUBSTRUCTURE_MASK
-                          | GDK_VISIBILITY_NOTIFY_MASK);
-    
     g_signal_connect(G_OBJECT(app_menu_item), "activate",
-                     G_CALLBACK(_command_activate_cb), NULL);
-    g_signal_connect(G_OBJECT(app_menu_item), "style-set",
-                     G_CALLBACK(_style_set_cb), NULL);
-    
-    app_menu_item->accel_label = accel_label = gtk_accel_label_new("");
-    gtk_misc_set_alignment(GTK_MISC(accel_label), 0.0, 0.5);
-    
-    gtk_container_add(GTK_CONTAINER(app_menu_item), accel_label);
-    gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(accel_label),
-                                     GTK_WIDGET(app_menu_item));
-    gtk_widget_show(accel_label);
+                     G_CALLBACK(xfdesktop_app_menu_item_activate), NULL);
 }
 
 static void
@@ -302,32 +110,20 @@ xfdesktop_app_menu_item_set_property(GObject *object,
                                      GParamSpec *pspec)
 {
     XfdesktopAppMenuItem *app_menu_item = XFDESKTOP_APP_MENU_ITEM(object);
-    
+
     switch(prop_id) {
-        case PROP_TERM:
-            xfdesktop_app_menu_item_set_needs_term(app_menu_item,
-                                                   g_value_get_boolean(value));
-            break;
-        case PROP_CMD:
-            xfdesktop_app_menu_item_set_command(app_menu_item,
-                                                g_value_get_string(value));
-            break;
-        case PROP_ICON:
-            xfdesktop_app_menu_item_set_icon_name(app_menu_item,
-                                                  g_value_get_string(value));
-            break;
-        case PROP_LABEL:
-            xfdesktop_app_menu_item_set_name(app_menu_item,
-                                             g_value_get_string(value));
-            break;
-        case PROP_SNOTIFY:
-            xfdesktop_app_menu_item_set_startup_notification(app_menu_item,
-                                                             g_value_get_boolean(value));
-            break;
-        case PROP_USE_UNDERLINE:
-            gtk_label_set_use_underline(GTK_LABEL(app_menu_item->accel_label),
-                                        g_value_get_boolean(value));
+        case PROP_ITEM:
+            if(app_menu_item->item) {
+                g_signal_handlers_disconnect_by_func(G_OBJECT(app_menu_item->item),
+                     G_CALLBACK(xfdesktop_app_menu_item_changed), app_menu_item);
+                g_object_unref(G_OBJECT(app_menu_item->item));
+            }
+            app_menu_item->item = g_value_dup_object(value);
+            g_signal_connect_swapped(G_OBJECT(app_menu_item->item), "changed",
+                                     G_CALLBACK(xfdesktop_app_menu_item_changed), app_menu_item);
+            xfdesktop_app_menu_item_changed (app_menu_item);
             break;
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
             break;
@@ -341,27 +137,12 @@ xfdesktop_app_menu_item_get_property(GObject *object,
                                      GParamSpec *pspec)
 {
     XfdesktopAppMenuItem *app_menu_item = XFDESKTOP_APP_MENU_ITEM(object);
-    
+
     switch(prop_id) {
-        case PROP_TERM:
-            g_value_set_boolean(value, app_menu_item->needs_term);
-            break;
-        case PROP_CMD:
-            g_value_set_string(value, app_menu_item->command);
-            break;
-        case PROP_ICON:
-            g_value_set_string(value, app_menu_item->icon_name);
-            break;
-        case PROP_LABEL:
-            g_value_set_string(value, app_menu_item->name);
-            break;
-        case PROP_SNOTIFY:
-            g_value_set_boolean(value, app_menu_item->snotify);
-            break;
-        case PROP_USE_UNDERLINE:
-            g_value_set_boolean(value,
-                                gtk_label_get_use_underline(GTK_LABEL(app_menu_item->accel_label)));
+        case PROP_ITEM:
+            g_value_set_object(value, app_menu_item->item);
             break;
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
             break;
@@ -372,534 +153,205 @@ static void
 xfdesktop_app_menu_item_finalize(GObject *object)
 {
     XfdesktopAppMenuItem *app_menu_item = XFDESKTOP_APP_MENU_ITEM(object);
-    
-    g_return_if_fail(app_menu_item != NULL);
-    
-    g_free(app_menu_item->name);
-    g_free(app_menu_item->command);
-    g_free(app_menu_item->icon_name);
-    g_free(app_menu_item->icon_path);
-    g_free(app_menu_item->command_expanded);
-    g_free(app_menu_item->dot_desktop_filename);
-    
-    G_OBJECT_CLASS(xfdesktop_app_menu_item_parent_class)->finalize(object);
-}
 
-static void
-xfdesktop_app_menu_item_realize(GtkWidget *widget)
-{
-    XfdesktopAppMenuItem *app_menu_item = XFDESKTOP_APP_MENU_ITEM(widget);
+    g_return_if_fail(app_menu_item != NULL);
 
-    GTK_WIDGET_CLASS(xfdesktop_app_menu_item_parent_class)->realize(widget);
+    if(app_menu_item->item) {
+        g_signal_handlers_disconnect_by_func(G_OBJECT(app_menu_item->item),
+                     G_CALLBACK(xfdesktop_app_menu_item_changed), app_menu_item);
+        g_object_unref(G_OBJECT(app_menu_item->item));
+    }
 
-    xfdesktop_app_menu_item_update_icon(app_menu_item);
+    G_OBJECT_CLASS(xfdesktop_app_menu_item_parent_class)->finalize(object);
 }
 
 static void
-xfdesktop_app_menu_item_update_icon(XfdesktopAppMenuItem *app_menu_item)
+xfdesktop_app_menu_item_set_icon(XfdesktopAppMenuItem *app_menu_item)
 {
-    GtkWidget *img;
-
-    if(!GTK_WIDGET_REALIZED(app_menu_item))
-        return;
-
-    img = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(app_menu_item));
-    if(!img) {
-        img = gtk_image_new();
-        gtk_widget_show(img);
-        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(app_menu_item), img);
-    } else
-        gtk_image_clear(GTK_IMAGE(img));
+    const gchar *icon_name;
+    gint w, h, size;
+    GdkPixbuf *pixbuf = NULL;
+    GtkWidget *image;
+    GtkIconTheme *icon_theme;
+    gchar *p, *name;
+    gchar *filename;
 
-    if(app_menu_item->icon_name) {
-        GtkIconTheme *itheme = gtk_icon_theme_get_default();
-
-        if(gtk_icon_theme_has_icon(itheme, app_menu_item->icon_name)) {
-            gtk_image_set_from_icon_name(GTK_IMAGE(img), app_menu_item->icon_name,
-                                         GTK_ICON_SIZE_MENU);
-        }
-    } else if(app_menu_item->icon_path) {
-        GdkPixbuf *pix;
-        gint w, h;
+    icon_name = garcon_menu_item_get_icon_name(app_menu_item->item);
 
+    if(G_LIKELY(icon_name)) {
         gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &w, &h);
-        
-        pix = gdk_pixbuf_new_from_file_at_scale(app_menu_item->icon_path,
-                                                w, h, TRUE, NULL);
-        if(pix) {
-            gtk_image_set_from_pixbuf(GTK_IMAGE(img), pix);
-            g_object_unref(G_OBJECT(pix));
+        size = MIN(w, h);
+
+        if (g_path_is_absolute (icon_name)) {
+            pixbuf = gdk_pixbuf_new_from_file_at_scale(icon_name, w, h, TRUE, NULL);
+        } else {
+            icon_theme = gtk_icon_theme_get_default();
+            pixbuf = gtk_icon_theme_load_icon(icon_theme, icon_name, size, 0, NULL);
+
+            if (G_UNLIKELY(pixbuf == NULL)) {
+                /* try to lookup names like application.png in the theme */
+                p = strrchr(icon_name, '.');
+                if (p) {
+                    name = g_strndup(icon_name, p - icon_name);
+                    pixbuf = gtk_icon_theme_load_icon(icon_theme, name, size, 0, NULL);
+                    g_free (name);
+                }
+
+                /* maybe they point to a file in the pixbufs folder */
+                if (G_UNLIKELY(pixbuf == NULL)) {
+                    filename = g_build_filename("pixmaps", name, NULL);
+                    name = xfce_resource_lookup(XFCE_RESOURCE_DATA, filename);
+                    g_free(filename);
+
+                    if(name)
+                        pixbuf = gdk_pixbuf_new_from_file(name, NULL);
+                    g_free(name);
+                }
+            }
         }
     }
-}
 
-/**
- * xfdesktop_app_menu_item_new:
- * @returns: A new #XfdesktopAppMenuItem.
- *
- * Creates a new #XfdesktopAppMenuItem with an empty label.
- *
- * Since 4.1
- **/
-GtkWidget *
-xfdesktop_app_menu_item_new(void)
-{
-    return g_object_new(XFDESKTOP_TYPE_APP_MENU_ITEM, NULL);
-}
+    if(G_LIKELY(pixbuf)) {
+        image = gtk_image_new_from_pixbuf(pixbuf);
+        g_object_unref(G_OBJECT(pixbuf));
+    } else {
+        image = gtk_image_new();
+    }
 
-/**
- * xfdesktop_app_menu_item_new_with_label:
- * @label: The text of the menu item.
- * @returns: A new #XfdesktopAppMenuItem.
- *
- * Creates a new #XfdesktopAppMenuItem containing a label.
- *
- * Since 4.1
- **/
-GtkWidget *
-xfdesktop_app_menu_item_new_with_label(const gchar *label)
-{
-    return g_object_new(XFDESKTOP_TYPE_APP_MENU_ITEM,
-                        "label", label,
-                        NULL);
+    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(app_menu_item), image);
 }
 
-/**
- * xfdesktop_app_menu_item_new_with_mnemonic:
- * @label: The text of the menu item, with an underscore in front of the
- *         mnemonic character.
- * @returns: A new #XfdesktopAppMenuItem.
- *
- * Creates a new #XfdesktopAppMenuItem containing a label. The label
- * will be created using gtk_label_new_with_mnemonic(), so underscores
- * in @label indicate the mnemonic for the menu item.
- *
- * Since 4.1
- **/
-GtkWidget *
-xfdesktop_app_menu_item_new_with_mnemonic(const gchar *label)
+static void
+xfdesktop_app_menu_item_changed(XfdesktopAppMenuItem *app_menu_item)
 {
-    return g_object_new(XFDESKTOP_TYPE_APP_MENU_ITEM,
-                        "label", label,
-                        "use-underline", TRUE,
-                        NULL);
-}
+    const gchar *label;
 
-/**
- * xfdesktop_app_menu_item_new_with_command:
- * @label: The text of the menu item.
- * @command: The command associated with the menu item.
- * @returns: A new #XfdesktopAppMenuItem.
- *
- * Creates a new #XfdesktopAppMenuItem containing a label. The item's @activate
- * signal will be connected such that @command will run when it is clicked.
- *
- * Since 4.1
- **/
-GtkWidget *
-xfdesktop_app_menu_item_new_with_command(const gchar *label,
-                                         const gchar *command)
-{
-    return g_object_new(XFDESKTOP_TYPE_APP_MENU_ITEM,
-                        "label", label,
-                        "command", command,
-                        NULL);
-}
+    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
+    g_return_if_fail(GARCON_IS_MENU_ITEM(app_menu_item->item));
 
-/**
- * xfdesktop_app_menu_item_new_full:
- * @label: The text of the menu item.
- * @command: The command associated with the menu item.
- * @icon_filename: The filename of the icon.
- * @needs_term: TRUE if the application needs a terminal, FALSE if not.
- * @snotify: TRUE if the application supports startup notification, FALSE if
- *           not.
- * @returns: A new #XfdesktopAppMenuItem.
- *
- * Single-function interface to create an #XfdesktopAppMenuItem.  Has the effect of
- * calling xfdesktop_app_menu_item_new_with_label() followed by all the
- * xfdesktop_app_menu_item_set_*() functions.
- *
- * Since 4.1
- **/
-GtkWidget *
-xfdesktop_app_menu_item_new_full(const gchar *label,
-                                 const gchar *command,
-                                 const gchar *icon_filename,
-                                 gboolean needs_term,
-                                 gboolean snotify)
-{
-    return g_object_new(XFDESKTOP_TYPE_APP_MENU_ITEM,
-                        "label", label,
-                        "command", command,
-                        "icon-name", icon_filename,
-                        "needs-term", needs_term,
-                        "snotify", snotify,
-                        NULL);
+    if(global_show_icons)
+        xfdesktop_app_menu_item_set_icon(app_menu_item);
+
+    label = garcon_menu_item_get_name(app_menu_item->item);
+    gtk_menu_item_set_label(GTK_MENU_ITEM(app_menu_item), label ? label : "");
 }
 
-#if 0
-/**
- * xfdesktop_app_menu_item_new_from_desktop_entry:
- * @entry: An #XfceDesktopEntry describing the menu item to create.
- * @show_icon: Sets whether or not to show an icon in the menu item.
- * @returns: A new #XfdesktopAppMenuItem, or %NULL on error.
- *
- * Creates a new #XfdesktopAppMenuItem using parameters from the application
- * specified in a #XfceDesktopEntry object. This has the effect of calling
- * xfdesktop_app_menu_item_new_with_command(), xfdesktop_app_menu_item_set_needs_term(),
- * xfdesktop_app_menu_item_set_icon_name(), and
- * xfdesktop_app_menu_item_set_startup_notification().
- *
- * Since 4.1
- **/
-GtkWidget *
-xfdesktop_app_menu_item_new_from_desktop_entry(XfceDesktopEntry *entry,
-                                               gboolean show_icon)
+static void
+xfdesktop_app_menu_item_append_quote (GString     *string,
+                                      const gchar *unquoted)
 {
-    XfdesktopAppMenuItem *app_menu_item;
-    gchar *name = NULL, *cmd = NULL, *icon = NULL, *snotify = NULL;
-    gchar *onlyshowin = NULL, *categories = NULL, *term = NULL;
-    const gchar *dfile;
-    
-    g_return_val_if_fail(XFCE_IS_DESKTOP_ENTRY(entry), NULL);
-    
-    if(xfce_desktop_entry_get_string(entry, "OnlyShowIn", FALSE, &onlyshowin)
-       || xfce_desktop_entry_get_string(entry, "Categories", FALSE,
-                                        &categories))
-    {
-        if((onlyshowin && strstr(onlyshowin, "XFCE;"))
-           || (categories && strstr(categories, "X-XFCE;")))
-        {
-            if(xfce_desktop_entry_has_translated_entry(entry, "GenericName")) {
-                xfce_desktop_entry_get_string(entry, "GenericName", TRUE,
-                                              &name);
-            } else if(xfce_desktop_entry_has_translated_entry(entry, "Name")) {
-                xfce_desktop_entry_get_string(entry, "Name", TRUE, &name);
-            } else {
-                xfce_desktop_entry_get_string(entry, "GenericName", FALSE,
-                                              &name);
-            }
-        } else if(onlyshowin) {
-            g_free(onlyshowin);
-            g_free(categories);
-            return NULL;
-        }
-        
-        g_free(onlyshowin);
-        g_free(categories);
-    }
-    
-    app_menu_item = XFDESKTOP_APP_MENU_ITEM(xfdesktop_app_menu_item_new());
-    
-    if(!name && !xfce_desktop_entry_get_string(entry, "Name", TRUE, &name)) {
-        gchar *tmp, *tmp1;
-        
-        tmp = g_filename_to_utf8(xfce_desktop_entry_get_file(entry), -1,
-                                 NULL, NULL, NULL);
-        if(!tmp)
-            tmp = g_strdup(xfce_desktop_entry_get_file(entry));
-            
-        if((tmp1 = g_strrstr(tmp, ".desktop")))
-            *tmp1 = 0;
-        if((tmp1 = g_strrstr(tmp, "/")))
-            tmp1++;
-        else
-            tmp1 = name;
-        name = g_strdup(tmp1);
-        g_free(tmp);
-    }
-    
-    app_menu_item->name = name;
-    
-    if(!g_utf8_validate(name, -1, NULL)) {
-        g_warning("XfdesktopAppMenuItem: 'name' failed utf8 validation for .desktop file '%s'",
-                  xfce_desktop_entry_get_file(entry));
-        gtk_widget_destroy(GTK_WIDGET(app_menu_item));
-        return NULL;
-    }
-    
-    gtk_label_set_text(GTK_LABEL(app_menu_item->accel_label),
-                       app_menu_item->name);
-    
-    if(xfce_desktop_entry_get_string(entry, "Terminal", TRUE, &term)) {
-        app_menu_item->needs_term = (*term == '1'
-                                     || !g_ascii_strcasecmp(term, "true"));
-        g_free(term);
-    }
-    
-    if(xfce_desktop_entry_get_string(entry, "StartupNotify", TRUE, &snotify)) {
-        app_menu_item->snotify = (*snotify == '1'
-                                  || !g_ascii_strcasecmp(snotify, "true"));
-        g_free(snotify);
-    }
-    
-    if(!xfce_desktop_entry_get_string(entry, "Exec", TRUE, &cmd)) {
-        gtk_widget_destroy(GTK_WIDGET(app_menu_item));
-        return NULL;
-    }
+  gchar *quoted;
 
-    /* remove quotes around the command (yes, people do that!) */
-    if(cmd[0] == '"') {
-        gint i;
-        
-        for(i = 1; cmd[i - 1] != '\0'; ++i) {
-            if (cmd[i] != '"')
-                cmd[i-1] = cmd[i];
-            else {
-                cmd[i-1] = cmd[i] = ' ';
-                break;
-            }
-        }
-    }
-
-    app_menu_item->command = xfce_expand_variables(cmd, NULL);
-    g_free(cmd);
-    
-    if(show_icon) {
-        xfce_desktop_entry_get_string(entry, "Icon", TRUE, &icon);
-        if(icon) {
-            xfdesktop_app_menu_item_set_icon_name(app_menu_item, icon);
-            g_free(icon);
-        }
-    }
-    
-    dfile = xfce_desktop_entry_get_file(entry);
-    if(dfile)
-        app_menu_item->dot_desktop_filename = g_strdup(dfile);
-    
-    return GTK_WIDGET(app_menu_item);
+  quoted = g_shell_quote(unquoted);
+  g_string_append(string, quoted);
+  g_free(quoted);
 }
-#endif
 
-/**
- * xfdesktop_app_menu_item_set_name:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @name: The name of the menu item the menu item.
- *
- * Sets @name as the displayed name of the #XfdesktopAppMenuItem.
- *
- * Since 4.1
- **/
-void
-xfdesktop_app_menu_item_set_name(XfdesktopAppMenuItem *app_menu_item,
-                                 const gchar *name)
+static gchar *
+xfdesktop_app_menu_item_command(XfdesktopAppMenuItem *app_menu_item)
 {
-    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
-    
-    if(app_menu_item->name)
-        g_free(app_menu_item->name);
-    
-    app_menu_item->name = g_strdup(name);
-    gtk_label_set_text(GTK_LABEL(app_menu_item->accel_label), name);
-}
+    GString *newstr;
+    const gchar *p;
+    const gchar *command;
+    const gchar *var;
+    gchar *uri, *filename;
 
-/**
- * xfdesktop_app_menu_item_set_icon_name:
- * @app_menu_item: an #XfdesktopAppMenuItem.
- * @filename: The filename of the icon.
- *
- * Sets the icon of the #XfdesktopAppMenuItem using the specified filename.  If
- * the filename doesn't have a full pathname, standard icon search paths
- * will be used.  If the filename doesn't have an extension, the best image
- * format found (if any) will be used.  If there is already an icon set, the
- * current one is freed, regardless if the icon is found or not.
- *
- * Since 4.1
- **/
-void
-xfdesktop_app_menu_item_set_icon_name(XfdesktopAppMenuItem *app_menu_item,
-                                      const gchar *filename)
-{
-    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
+    command = garcon_menu_item_get_command(app_menu_item->item);
+    if(command == NULL)
+        return NULL;
 
-    g_free(app_menu_item->icon_name);
-    app_menu_item->icon_name = NULL;
-    g_free(app_menu_item->icon_path);
-    app_menu_item->icon_path = NULL;
-
-    if(filename) {
-        if(g_path_is_absolute(filename))
-            app_menu_item->icon_path = g_strdup(filename);
-        else {
-            gchar *p, *q;
-            gsize len;
-
-            /* yes, there are really broken .desktop files out there
-             * messed up like this */
-
-            /* first make sure we aren't a weird relative path */
-            p = g_strrstr(filename, G_DIR_SEPARATOR_S);
-            if(p)
-                p++;
-            else
-                p = (gchar *)filename;
-
-            len = strlen(p);
-
-            /* now make sure we don't have an extension */
-            q = g_strrstr(p, ".");
-            if(q && (!strcmp(q, ".png") || !strcmp(q, ".svg")
-                     || !strcmp(q, ".jpg") || !strcmp(q, ".gif")
-                     || !strcmp(q, ".bmp")))
-            {
-                len -= strlen(q);
-            }
+    newstr = g_string_sized_new(100);
 
-            /* whatever's left... */
-            if(p[0] && len)
-                app_menu_item->icon_name = g_strndup(p, len);
-        }
-    }
+    for(p = command; *p; ++p) {
+        if('%' == *p) {
+            ++p;
+            switch(*p) {
+                /* we don't care about these since we aren't passing filenames */
+                case 'f':
+                case 'F':
+                case 'u':
+                case 'U':
+                /* these are all deprecated */
+                case 'd':
+                case 'D':
+                case 'n':
+                case 'N':
+                case 'v':
+                case 'm':
+                    break;
 
-    xfdesktop_app_menu_item_update_icon(app_menu_item);
-}
+                case 'i':
+                    var = garcon_menu_item_get_icon_name(app_menu_item->item);
+                    if(G_LIKELY(var)) {
+                        g_string_append(newstr, "--icon ");
+                        xfdesktop_app_menu_item_append_quote(newstr, var);
+                    }
+                    break;
 
-/**
- * xfdesktop_app_menu_item_set_command:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @command: The command to associate with the menu item.
- *
- * Sets @command as the command run when the #XfdesktopAppMenuItem is clicked.
- *
- * Since 4.1
- **/
-void
-xfdesktop_app_menu_item_set_command(XfdesktopAppMenuItem *app_menu_item,
-                                    const gchar *command)
-{
-    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
-    
-    if(app_menu_item->command)
-        g_free(app_menu_item->command);
+                case 'c':
+                    var = garcon_menu_item_get_name(app_menu_item->item);
+                    if(G_LIKELY(var))
+                        xfdesktop_app_menu_item_append_quote(newstr, var);
+                    break;
 
-    app_menu_item->command = xfce_expand_variables(command, NULL);
-}
+                case 'k':
+                    uri = garcon_menu_item_get_uri(app_menu_item->item);
+                    if(G_LIKELY(uri)) {
+                        filename = g_filename_from_uri(uri, NULL, NULL);
+                        xfdesktop_app_menu_item_append_quote(newstr, filename);
+                        g_free(filename);
+                    }
+                    g_free(uri);
+                    break;
 
-/**
- * xfdesktop_app_menu_item_set_needs_term:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @needs_term: TRUE if the application needs a terminal, FALSE if not.
- *
- * Sets whether or not the command executed by this #XfdesktopAppMenuItem requires
- * a terminal window to run.
- *
- * Since 4.1
- **/
-void
-xfdesktop_app_menu_item_set_needs_term(XfdesktopAppMenuItem *app_menu_item,
-                                       gboolean needs_term)
-{
-    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
-    
-    app_menu_item->needs_term = needs_term;
-}
+                case '%':
+                    g_string_append_c(newstr, '%');
+                    break;
 
-/**
- * xfdesktop_app_menu_item_set_startup_notification:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @snotify: TRUE if the application supports startup notification, FALSE if
- *           not.
- *
- * Sets whether or not the application supports startup notification.
- *
- * Since 4.1
- **/
-void
-xfdesktop_app_menu_item_set_startup_notification(XfdesktopAppMenuItem *app_menu_item,
-                                                 gboolean snotify)
-{
-    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
-    
-    app_menu_item->snotify = snotify;
-}
+                default:
+                    g_warning("Invalid field code in Exec line: %%%c", *p);
+                    break;
+            }
+        } else
+            g_string_append_c(newstr, *p);
+    }
 
-/**
- * xfdesktop_app_menu_item_get_name:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @returns: A name/label string.
- *
- * Returns the current name/label set for the #XfdesktopAppMenuItem, or NULL.
- *
- * Since 4.1
- **/
-G_CONST_RETURN gchar *
-xfdesktop_app_menu_item_get_name(XfdesktopAppMenuItem *app_menu_item)
-{
-    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), NULL);
-    
-    return app_menu_item->name;
+    return g_string_free(newstr, FALSE);
 }
 
-/**
- * xfdesktop_app_menu_item_get_icon_name:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @returns: An icon name string.
- *
- * Returns the current icon name set for the #XfdesktopAppMenuItem, or NULL.
- *
- * Since 4.1
- **/
-G_CONST_RETURN gchar *
-xfdesktop_app_menu_item_get_icon_name(XfdesktopAppMenuItem *app_menu_item)
+static void
+xfdesktop_app_menu_item_activate (XfdesktopAppMenuItem *app_menu_item)
 {
-    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), NULL);
-    
-    if(app_menu_item->icon_name)
-        return app_menu_item->icon_name;
-    else
-        return app_menu_item->icon_path;
+   gchar *command;
+   GError *error = NULL;
+
+   command = xfdesktop_app_menu_item_command(app_menu_item);
+   if (command == NULL)
+       return;
+
+   if(!xfce_spawn_command_line_on_screen(gtk_widget_get_screen(GTK_WIDGET(app_menu_item)),
+                                         command,
+                                         garcon_menu_item_requires_terminal(app_menu_item->item),
+                                         garcon_menu_item_supports_startup_notification(app_menu_item->item),
+                                         &error)) {
+        g_warning("XfdesktopAppMenuItem: unable to spawn %s: %s",
+                 command, error->message);
+        g_error_free(error);
+    }
 }
 
-/**
- * xfdesktop_app_menu_item_get_command:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @returns: A command string.
- *
- * Returns the current command set for the #XfdesktopAppMenuItem, or NULL.
- *
- * Since 4.1
- **/
-G_CONST_RETURN gchar *
-xfdesktop_app_menu_item_get_command(XfdesktopAppMenuItem *app_menu_item)
+GtkWidget *
+xfdesktop_app_menu_item_new (GarconMenuItem *item)
 {
-    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), NULL);
-    
-    return app_menu_item->command;
-}
+    g_return_val_if_fail(GARCON_IS_MENU_ITEM(item), NULL);
 
-/**
- * xfdesktop_app_menu_item_get_needs_term:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @returns: TRUE if the item will spawn a terminal, FALSE if not.
- *
- * Checks whether or not the command executed by this #XfdesktopAppMenuItem requires
- * a terminal window to run.
- *
- * Since 4.1
- **/
-gboolean
-xfdesktop_app_menu_item_get_needs_term(XfdesktopAppMenuItem *app_menu_item)
-{
-    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), FALSE);
-    
-    return app_menu_item->needs_term;
+    return g_object_new (XFDESKTOP_TYPE_APP_MENU_ITEM,
+                         "item", item, NULL);
 }
 
-/**
- * xfdesktop_app_menu_item_get_startup_notification:
- * @app_menu_item: An #XfdesktopAppMenuItem.
- * @returns: TRUE if the item supports startup notification, FALSE if not.
- *
- * Checks whether or not the command executed by this #XfdesktopAppMenuItem supports
- * startup notification.
- *
- * Since 4.1
- **/
-gboolean
-xfdesktop_app_menu_item_get_startup_notification(XfdesktopAppMenuItem *app_menu_item)
+
+void
+xfdesktop_app_menu_item_set_show_icon (gboolean show_icon)
 {
-    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), FALSE);
-    
-    return app_menu_item->snotify;
+    global_show_icons = show_icon;
 }
diff --git a/src/xfdesktop-app-menu-item.h b/src/xfdesktop-app-menu-item.h
index a6b11f3..32b62eb 100644
--- a/src/xfdesktop-app-menu-item.h
+++ b/src/xfdesktop-app-menu-item.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * A GtkImageMenuItem subclass that handles menu items that are
  * intended to represent launchable applications.
  *
@@ -24,6 +24,7 @@
 #define __XFDESKTOP_APP_MENU_ITEM_H__
 
 #include <glib-object.h>
+#include <garcon/garcon.h>
 
 G_BEGIN_DECLS
 
@@ -36,54 +37,11 @@ G_BEGIN_DECLS
 
 typedef struct _XfdesktopAppMenuItem       XfdesktopAppMenuItem;
 
-GType xfdesktop_app_menu_item_get_type                     (void) G_GNUC_CONST;
+GType      xfdesktop_app_menu_item_get_type      (void) G_GNUC_CONST;
 
-GtkWidget *xfdesktop_app_menu_item_new                     (void);
+GtkWidget *xfdesktop_app_menu_item_new           (GarconMenuItem *item);
 
-GtkWidget *xfdesktop_app_menu_item_new_with_label          (const gchar *label);
-
-GtkWidget *xfdesktop_app_menu_item_new_with_mnemonic       (const gchar *label);
-
-GtkWidget *xfdesktop_app_menu_item_new_with_command        (const gchar *label,
-                                                            const gchar *command);
-
-GtkWidget *xfdesktop_app_menu_item_new_full                (const gchar *label,
-                                                            const gchar *command,
-                                                            const gchar *icon_filename,
-                                                            gboolean needs_term,
-                                                            gboolean snotify);
-
-#if 0
-GtkWidget *xfdesktop_app_menu_item_new_from_desktop_entry  (XfceDesktopEntry *entry,
-                                                            gboolean show_icon);
-#endif
-
-void xfdesktop_app_menu_item_set_name                      (XfdesktopAppMenuItem *app_menu_item,
-                                                            const gchar *name);
-													   
-void xfdesktop_app_menu_item_set_icon_name                 (XfdesktopAppMenuItem *app_menu_item,
-                                                            const gchar *filename);
-													   
-void xfdesktop_app_menu_item_set_command                   (XfdesktopAppMenuItem *app_menu_item,
-                                                            const gchar *command);
-													   
-void xfdesktop_app_menu_item_set_needs_term                (XfdesktopAppMenuItem *app_menu_item,
-                                                            gboolean needs_term);
-													   
-void xfdesktop_app_menu_item_set_startup_notification      (XfdesktopAppMenuItem *app_menu_item,
-                                                            gboolean snotify);
-													   
-G_CONST_RETURN gchar *xfdesktop_app_menu_item_get_name     (XfdesktopAppMenuItem *app_menu_item);
-
-G_CONST_RETURN gchar *xfdesktop_app_menu_item_get_icon_name(XfdesktopAppMenuItem *app_menu_item);
-
-G_CONST_RETURN gchar *xfdesktop_app_menu_item_get_command  (XfdesktopAppMenuItem *app_menu_item);
-
-gboolean xfdesktop_app_menu_item_get_needs_term            (XfdesktopAppMenuItem *app_menu_item);
-
-gboolean xfdesktop_app_menu_item_get_startup_notification  (XfdesktopAppMenuItem *app_menu_item);
-
-void xfdesktop_app_menu_item_set_icon_theme_name           (const gchar *theme_name);
+void       xfdesktop_app_menu_item_set_show_icon (gboolean        show_icon);
 
 G_END_DECLS
 



More information about the Xfce4-commits mailing list