aboutsummaryrefslogtreecommitdiffstats
path: root/main/xfdesktop
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2010-11-12 15:16:09 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2010-11-12 15:16:19 +0000
commit0a9b67feb6b613d39e532718b7bc0dc10d1176ea (patch)
tree301e4d95b5b02684e4f9da1b5bfbc7dd3111a654 /main/xfdesktop
parent9633b9fef333808a46f32180a94022748a2a52b2 (diff)
downloadaports-0a9b67feb6b613d39e532718b7bc0dc10d1176ea.tar.bz2
aports-0a9b67feb6b613d39e532718b7bc0dc10d1176ea.tar.xz
main/xfdesktop: upgrade to 4.7.2
Diffstat (limited to 'main/xfdesktop')
-rw-r--r--main/xfdesktop/APKBUILD27
-rw-r--r--main/xfdesktop/fix-crash.patch45
-rw-r--r--main/xfdesktop/menu-item-monitor.patch1614
3 files changed, 1678 insertions, 8 deletions
diff --git a/main/xfdesktop/APKBUILD b/main/xfdesktop/APKBUILD
index 5374a44795..6fdec39dd7 100644
--- a/main/xfdesktop/APKBUILD
+++ b/main/xfdesktop/APKBUILD
@@ -1,20 +1,29 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=xfdesktop
-pkgver=4.6.2
+pkgver=4.7.2
pkgrel=0
pkgdesc="A desktop manager for Xfce"
url="http://www.xfce.org/"
license="GPL-2"
-subpackages="$pkgname-dev $pkgname-doc"
+subpackages="$pkgname-doc"
depends="hicolor-icon-theme"
-makedepends="pkgconfig libxfce4menu-dev thunar-dev intltool gettext-dev
- libiconv-dev libxfce4util-dev gtk+-dev libxfcegui4-dev libwnck-dev
- libglade-dev xfce4-panel-dev libsm-dev libice-dev expat-dev
- e2fsprogs-dev"
+makedepends="garcon-dev thunar-dev libxfce4ui-dev libwnck-dev libnotify-dev
+ exo-dev"
install=
-source="http://archive.xfce.org/src/xfce/$pkgname/4.6/$pkgname-$pkgver.tar.bz2"
+source="http://archive.xfce.org/src/xfce/$pkgname/${pkgver%.*}/$pkgname-$pkgver.tar.bz2
+ menu-item-monitor.patch
+ fix-crash.patch"
_builddir="$srcdir"/$pkgname-$pkgver
+prepare() {
+ cd "$_builddir"
+ for i in $source; do
+ case $i in
+ *.patch) patch -p1 -i "$srcdir"/$i || return 1;;
+ esac
+ done
+}
+
build() {
cd "$_builddir"
./configure --prefix=/usr \
@@ -30,4 +39,6 @@ package() {
make DESTDIR="$pkgdir" install || return 1
}
-md5sums="e800ea9fee7a5c5eaf2ae96e23a83e3a xfdesktop-4.6.2.tar.bz2"
+md5sums="88d10a7775f65a007639f921c5c8f13a xfdesktop-4.7.2.tar.bz2
+80888519567088ada69ef24953e3b81c menu-item-monitor.patch
+ba3b359ab312e6e75882c22f2f3d4a1a fix-crash.patch"
diff --git a/main/xfdesktop/fix-crash.patch b/main/xfdesktop/fix-crash.patch
new file mode 100644
index 0000000000..f59ca0e7da
--- /dev/null
+++ b/main/xfdesktop/fix-crash.patch
@@ -0,0 +1,45 @@
+From 1e6d4b150de2288f4ae60e0e20e3c663dc6233aa Mon Sep 17 00:00:00 2001
+From: Jannis Pohlmann <jannis@xfce.org>
+Date: Mon, 08 Nov 2010 10:50:50 +0000
+Subject: Fix a crash due to accessing the wrong variable when adding menu items.
+
+---
+diff --git a/NEWS b/NEWS
+index eeb944c..3ba1e4e 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,3 +1,10 @@
++Xfdesktop 4.7.x
++---------------
++
++ * Fix a crash caused by accessing the wrong variable when adding
++ items to the right-click menu.
++
++
+ Xfdesktop 4.7.2
+ ---------------
+
+diff --git a/src/xfdesktop-app-menu-item.c b/src/xfdesktop-app-menu-item.c
+index 0bfddb9..e10696a 100644
+--- a/src/xfdesktop-app-menu-item.c
++++ b/src/xfdesktop-app-menu-item.c
+@@ -173,7 +173,7 @@ xfdesktop_app_menu_item_set_icon(XfdesktopAppMenuItem *app_menu_item)
+ GdkPixbuf *pixbuf = NULL;
+ GtkWidget *image;
+ GtkIconTheme *icon_theme;
+- gchar *p, *name;
++ gchar *p, *name = NULL;
+ gchar *filename;
+
+ icon_name = garcon_menu_item_get_icon_name(app_menu_item->item);
+@@ -199,7 +199,7 @@ xfdesktop_app_menu_item_set_icon(XfdesktopAppMenuItem *app_menu_item)
+
+ /* maybe they point to a file in the pixbufs folder */
+ if (G_UNLIKELY(pixbuf == NULL)) {
+- filename = g_build_filename("pixmaps", name, NULL);
++ filename = g_build_filename("pixmaps", icon_name, NULL);
+ name = xfce_resource_lookup(XFCE_RESOURCE_DATA, filename);
+ g_free(filename);
+
+--
+cgit v0.8.3.4
diff --git a/main/xfdesktop/menu-item-monitor.patch b/main/xfdesktop/menu-item-monitor.patch
new file mode 100644
index 0000000000..b7dc4577d7
--- /dev/null
+++ b/main/xfdesktop/menu-item-monitor.patch
@@ -0,0 +1,1614 @@
+From 8efb089a60786d99fee1fdb7e7ae880d53bcc20b Mon Sep 17 00:00:00 2001
+From: Nick Schermer <nick@xfce.org>
+Date: Fri, 05 Nov 2010 15:56:02 +0000
+Subject: 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.
+---
+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@users.sourceforge.net)
+ * 2003 Biju Chacko (botsie@users.sourceforge.net)
+ * 2004 Danny Milosavljevic <danny.milo@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
+
+--
+cgit v0.8.3.4