Code freeze break request (gnome-panel)



Since nautilus now does some magic to display desktop files the right
way only if they are trusted, I had to update gnome-panel for two
things:

 + there's a right-click menu item in the applications menu to add a
   desktop file to the desktop. The desktop file should be made trusted
   automatically.

 + when saving a desktop file we edited, we need to mark the desktop
   file as trusted. The most important use case here is right-click on
   your desktop and select "Create launcher" (it launches
   gnome-desktop-item-edit which lives in gnome-panel).

The attached patch fixes those issues to make it just work. It's loosely
based on the code used in nautilus.

Vincent

-- 
Les gens heureux ne sont pas pressés.
Index: libpanel-util/panel-keyfile.c
===================================================================
--- libpanel-util/panel-keyfile.c	(révision 11567)
+++ libpanel-util/panel-keyfile.c	(copie de travail)
@@ -25,12 +25,15 @@
  */
 
 #include <string.h>
+#include <sys/stat.h>
 
 #include <glib.h>
 #include <gio/gio.h>
 
 #include "panel-keyfile.h"
 
+#define KEYFILE_TRUSTED_SHEBANG "#!/usr/bin/env xdg-open\n"
+
 GKeyFile *
 panel_key_file_new_desktop (void)
 {
@@ -45,6 +48,46 @@ panel_key_file_new_desktop (void)
 	return retval;
 }
 
+static void
+_panel_key_file_make_executable (const gchar *path)
+{
+	GFile     *file;
+	GFileInfo *info;
+	guint32    current_perms;
+	guint32    new_perms;
+
+	file = g_file_new_for_path (path);
+
+	info = g_file_query_info (file,
+				  G_FILE_ATTRIBUTE_STANDARD_TYPE","
+				  G_FILE_ATTRIBUTE_UNIX_MODE,
+				  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+				  NULL,
+				  NULL);
+
+	if (info == NULL) {
+		g_warning ("Cannot mark %s executable", path);
+		g_object_unref (file);
+		return;
+	}
+
+	if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE)) {
+		current_perms = g_file_info_get_attribute_uint32 (info,
+								  G_FILE_ATTRIBUTE_UNIX_MODE);
+		new_perms = current_perms | S_IXGRP | S_IXUSR | S_IXOTH;
+		if ((current_perms != new_perms) &&
+		    !g_file_set_attribute_uint32 (file,
+			    			  G_FILE_ATTRIBUTE_UNIX_MODE,
+						  new_perms,
+						  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+						  NULL, NULL))
+			g_warning ("Cannot mark %s executable", path);
+	}
+
+	g_object_unref (info);
+	g_object_unref (file);
+}
+
 //FIXME: kill this when bug #309224 is fixed
 gboolean
 panel_key_file_to_file (GKeyFile     *keyfile,
@@ -79,16 +122,36 @@ panel_key_file_to_file (GKeyFile     *ke
 		return FALSE;
 	}
 
+	if (!g_str_has_prefix (data, "#!")) {
+		gchar *new_data;
+		gsize  new_length;
+
+		new_length = length + strlen (KEYFILE_TRUSTED_SHEBANG);
+		new_data = g_malloc (new_length);
+
+		strcpy (new_data, KEYFILE_TRUSTED_SHEBANG);
+		memcpy (new_data + strlen (KEYFILE_TRUSTED_SHEBANG),
+			data, length);
+
+		g_free (data);
+		data = new_data;
+		length = new_length;
+	}
+
 	res = g_file_set_contents (filename, data, length, &write_error);
-	g_free (filename);
 
 	if (write_error) {
 		g_propagate_error (error, write_error);
 		g_free (data);
+		g_free (filename);
 		return FALSE;
 	}
 
 	g_free (data);
+
+	_panel_key_file_make_executable (filename);
+	g_free (filename);
+
 	return res;
 }
 
@@ -144,6 +207,30 @@ panel_key_file_load_from_uri (GKeyFile
 }
 
 gboolean
+panel_key_file_copy_and_mark_trusted (const char  *source_path,
+				      const char  *target_path,
+				      GError     **error)
+{
+	GKeyFile *key_file;
+	gboolean  res = FALSE;
+
+	key_file = g_key_file_new ();
+	res = g_key_file_load_from_file (key_file, source_path, 
+					 G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS,
+					 error);
+	if (!res) {
+		g_key_file_free (key_file);
+		return FALSE;
+	}
+
+	res = panel_key_file_to_file (key_file, target_path, error);
+
+	g_key_file_free (key_file);
+
+	return res;
+}
+
+gboolean
 panel_key_file_get_boolean (GKeyFile    *keyfile,
 			    const gchar *key,
 			    gboolean     default_value)
Index: libpanel-util/panel-keyfile.h
===================================================================
--- libpanel-util/panel-keyfile.h	(révision 11567)
+++ libpanel-util/panel-keyfile.h	(copie de travail)
@@ -41,6 +41,10 @@ gboolean panel_key_file_load_from_uri (G
 				       GKeyFileFlags   flags,
 				       GError        **error);
 
+gboolean panel_key_file_copy_and_mark_trusted (const char  *source_path,
+					       const char  *target_path,
+					       GError     **error);
+
 gboolean panel_key_file_get_boolean   (GKeyFile       *keyfile,
 				       const gchar    *key,
 				       gboolean        default_value);
Index: menu.c
===================================================================
--- menu.c	(révision 11567)
+++ menu.c	(copie de travail)
@@ -31,6 +31,8 @@
 #include <gdk/gdkkeysyms.h>
 #include <gconf/gconf-client.h>
 
+#include <libpanel-util/panel-keyfile.h>
+
 #include "launcher.h"
 #include "panel-util.h"
 #include "panel.h"
@@ -696,39 +698,38 @@ static void
 add_app_to_desktop (GtkWidget      *item,
 		    GMenuTreeEntry *entry)
 {
-	GFile *source;
-	GFile *target;
-	GError *error;
-	char *target_dir;
-	char *target_uri;
-	char *source_uri;
+	char       *source_uri;
+	const char *source;
+	char       *target_dir;
+	char       *target_uri;
+	char       *target;
+	GError     *error;
 
 	g_return_if_fail (entry != NULL);
 
-	source = g_file_new_for_path (gmenu_tree_entry_get_desktop_file_path (entry));
-
 	if (desktop_is_home_dir ()) {
 		target_dir = g_build_filename (g_get_home_dir (), NULL);
 	} else {
 		target_dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
 	}
 
-	source_uri = g_file_get_uri (source);
+	source = gmenu_tree_entry_get_desktop_file_path (entry);
+	source_uri = g_filename_to_uri (source, NULL, NULL);
+
 	target_uri = panel_make_unique_desktop_uri (target_dir, source_uri);
-	g_free (source_uri);
 	g_free (target_dir);
+	g_free (source_uri);
+
 	g_return_if_fail (target_uri != NULL);
 
-	target = g_file_new_for_uri (target_uri);
+	target = g_filename_from_uri (target_uri, NULL, NULL);
 	g_free (target_uri);
 
 	error = NULL;
-	g_file_copy (source, target, G_FILE_COPY_NONE,
-		     NULL, NULL, NULL, &error);
+	panel_key_file_copy_and_mark_trusted (source, target, &error);
+
+	g_free (target);
 
-	g_object_unref (source);
-	g_object_unref (target);
-	
 	if (error != NULL) {
 		g_warning ("Problem while copying launcher to desktop: %s",
 			   error->message);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]