[Xfce4-commits] r25677 - in libxfcegui4/branches/xfce_4_4: . libxfcegui4

Brian Tarricone kelnos at xfce.org
Sat May 5 20:03:02 CEST 2007


Author: kelnos
Date: 2007-05-05 18:03:02 +0000 (Sat, 05 May 2007)
New Revision: 25677

Modified:
   libxfcegui4/branches/xfce_4_4/NEWS
   libxfcegui4/branches/xfce_4_4/libxfcegui4/xfce-appmenuitem.c
Log:
properly parse and handle %- 'field codes' in exec lines from desktop files
(bug 3106)


Modified: libxfcegui4/branches/xfce_4_4/NEWS
===================================================================
--- libxfcegui4/branches/xfce_4_4/NEWS	2007-05-05 14:55:58 UTC (rev 25676)
+++ libxfcegui4/branches/xfce_4_4/NEWS	2007-05-05 18:03:02 UTC (rev 25677)
@@ -2,6 +2,7 @@
 =====
 - Allocate a copy of passed cliend id, program name and working directory
   in session management, in case the application frees the data.
+- Properly deal with %-starting 'field codes' in commands from .desktop files
 
 4.4.1
 =====

Modified: libxfcegui4/branches/xfce_4_4/libxfcegui4/xfce-appmenuitem.c
===================================================================
--- libxfcegui4/branches/xfce_4_4/libxfcegui4/xfce-appmenuitem.c	2007-05-05 14:55:58 UTC (rev 25676)
+++ libxfcegui4/branches/xfce_4_4/libxfcegui4/xfce-appmenuitem.c	2007-05-05 18:03:02 UTC (rev 25677)
@@ -45,6 +45,9 @@
     gchar *icon_name;
     gchar *icon_path;
     gboolean icon_set;
+    
+    gchar *command_expanded;
+    gchar *dot_desktop_filename;
 };
 
 enum {
@@ -92,6 +95,88 @@
 }
 
 static void
+_expand_percent_vars(XfceAppMenuItem *app_menu_item)
+{
+    GString *newstr;
+    gchar *p;
+    
+    g_return_if_fail(app_menu_item->priv->command);
+    
+    newstr = g_string_sized_new(strlen(app_menu_item->priv->command) + 1);
+    
+    for(p = app_menu_item->priv->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->priv->icon_name)) {
+                        gchar *str = g_shell_quote(app_menu_item->priv->icon_name);
+                        g_string_append(newstr, "--icon ");
+                        g_string_append(newstr, str);
+                        g_free(str);
+                    }
+                    break;
+                
+                case 'c':
+                    if(G_LIKELY(app_menu_item->priv->name)) {
+                        gchar *name_locale, *str;
+                        gsize bread = 0;
+                        GError *error = NULL;
+                        
+                        name_locale = g_locale_from_utf8(app_menu_item->priv->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 %d: %s",
+                                      bread, error->message);
+                        }
+                    }
+                    break;
+                
+                case 'k':
+                    if(app_menu_item->priv->dot_desktop_filename) {
+                        gchar *str = g_shell_quote(app_menu_item->priv->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->priv->command_expanded = newstr->str;
+    g_string_free(newstr, FALSE);
+}
+
+static void
 _command_activate_cb(GtkMenuItem *menu_item, gpointer user_data)
 {
     XfceAppMenuItem *app_menu_item = XFCE_APP_MENU_ITEM(menu_item);
@@ -99,12 +184,23 @@
     
     g_return_if_fail(app_menu_item && app_menu_item->priv->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->priv->command_expanded)
+        _expand_percent_vars(app_menu_item);
+    
     gscreen = gtk_widget_get_screen(GTK_WIDGET(menu_item));
-    if(!xfce_exec_on_screen(gscreen, app_menu_item->priv->command,    app_menu_item->priv->needs_term,
-            app_menu_item->priv->snotify, NULL))
+    if(!xfce_exec_on_screen(gscreen, app_menu_item->priv->command_expanded,
+                            app_menu_item->priv->needs_term,
+                            app_menu_item->priv->snotify, NULL))
     {
         g_warning("XfceAppMenuItem: unable to spawn %s\n",
-                app_menu_item->priv->command);
+                  app_menu_item->priv->command_expanded);
     }
 }
 
@@ -252,6 +348,8 @@
     g_free(app_menu_item->priv->command);
     g_free(app_menu_item->priv->icon_name);
     g_free(app_menu_item->priv->icon_path);
+    g_free(app_menu_item->priv->command_expanded);
+    g_free(app_menu_item->priv->dot_desktop_filename);
     
     G_OBJECT_CLASS(xfce_app_menu_item_parent_class)->finalize(object);
 }
@@ -435,7 +533,8 @@
     XfceAppMenuItem *app_menu_item;
     GtkWidget *accel_label;
     gchar *name = NULL, *cmd = NULL, *icon = NULL, *snotify = NULL;
-    gchar *onlyshowin = NULL, *categories = NULL, *term = NULL, *p;
+    gchar *onlyshowin = NULL, *categories = NULL, *term = NULL;
+    const gchar *dfile;
     
     g_return_val_if_fail(XFCE_IS_DESKTOP_ENTRY(entry), NULL);
     
@@ -520,12 +619,6 @@
         gtk_widget_destroy(GTK_WIDGET(app_menu_item));
         return NULL;
     }
-    
-    /* naive approach to sanitising these */
-    if((p=strchr(cmd, '%'))) {
-        if((p=strchr(cmd, ' ')))
-            *p = 0;
-    }    
 
     /* remove quotes around the command (yes, people do that!) */
     if(cmd[0] == '"') {
@@ -552,6 +645,10 @@
         }
     }
     
+    dfile = xfce_desktop_entry_get_file(entry);
+    if(dfile)
+        app_menu_item->priv->dot_desktop_filename = g_strdup(dfile);
+    
     return GTK_WIDGET(app_menu_item);
 }
 



More information about the Xfce4-commits mailing list