diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2010-11-12 15:16:09 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2010-11-12 15:16:19 +0000 |
commit | 0a9b67feb6b613d39e532718b7bc0dc10d1176ea (patch) | |
tree | 301e4d95b5b02684e4f9da1b5bfbc7dd3111a654 /main/xfdesktop | |
parent | 9633b9fef333808a46f32180a94022748a2a52b2 (diff) | |
download | aports-0a9b67feb6b613d39e532718b7bc0dc10d1176ea.tar.bz2 aports-0a9b67feb6b613d39e532718b7bc0dc10d1176ea.tar.xz |
main/xfdesktop: upgrade to 4.7.2
Diffstat (limited to 'main/xfdesktop')
-rw-r--r-- | main/xfdesktop/APKBUILD | 27 | ||||
-rw-r--r-- | main/xfdesktop/fix-crash.patch | 45 | ||||
-rw-r--r-- | main/xfdesktop/menu-item-monitor.patch | 1614 |
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 |