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

User directories integration - request for help



The basic user directories stuff discussed on fedora-desktop-list has
now landed in rawhide (install the xdg-user-dirs and xdg-user-dirs-gtk
packages to get it). I've created patches to the core desktop packages
that needed it (nautilus, gnome-panel, gnome-user-share) to make it
work. However, to fully make use of this we need to patch a bunch of
applications to take advantage of this new feature.

The directories availible are:
DESKTOP: the standard desktop dir
DOWNLOAD: default location for downloads
TEMPLATES: used by nautilus for templates
PUBLICSHARE: This is ~/Public as used by gnome-user-share
DOCUMENTS: default location for "documents"
MUSIC: default location for music
PICTURES: default location for pictures
VIDEOS: default location for movies

The most common thing these are used for is for the default location of
the file selector, or as a default for some setting (like download
directory). I'd like to point out that the *best* default location for a
file selector is whatever it was last time you opened it, so this should
be used for the default default location.

The xdg-user-dirs sources contains a file called xdg-user-dir-lookup.c
which has a very simple implementation of looking up user directories.
It has no dependencies and a liberal license (MIT) and was made to be
easily copied into apps for easy patchmaking. 

I've attached an example patch that i did for gftp to show how adding
integration to an application can look.

Now I'd like to get some help with integrating this into the rest of our
applications from package maintainers and the community in general. Both
with patching and ideas of what can be done.

Here is an initial list of stuff we should try to do:

firefox/epiphany/any browser: default download directory

abiword, OOo, other word processors: Default to DOCUMENTS directory 
(OOo is being worked on atm)

bittorrent: default download directory

rhythmbox: use MUSIC directory as default in file selector and maybe as
the standard library location

totem: use VIDEOS as default in file selector

eog/gthumb/f-spot: PICTURES as default for file selector

Any other ideas?

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl redhat com    alla lysator liu se 
He's a jaded alcoholic romance novelist from the 'hood. She's a radical 
antique-collecting nun from Mars. They fight crime! 
--- gftp-2.0.18/src/gtk/gftp-gtk.c.user-dirs	2007-03-15 10:30:40.000000000 +0100
+++ gftp-2.0.18/src/gtk/gftp-gtk.c	2007-03-15 10:32:00.000000000 +0100
@@ -1264,11 +1264,130 @@
   return (0);
 }
 
+static char *
+xdg_user_dir_lookup (const char *type)
+{
+  FILE *file;
+  char *home_dir, *config_home, *config_file;
+  char buffer[512];
+  char *user_dir;
+  char *p, *d;
+  int len;
+  int relative;
+  
+  home_dir = getenv ("HOME");
+
+  if (home_dir == NULL)
+    return strdup ("/tmp");
+
+  config_home = getenv ("XDG_CONFIG_HOME");
+  if (config_home == NULL || config_home[0] == 0)
+    {
+      config_file = malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
+      strcpy (config_file, home_dir);
+      strcat (config_file, "/.config/user-dirs.dirs");
+    }
+  else
+    {
+      config_file = malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
+      strcpy (config_file, config_home);
+      strcat (config_file, "/user-dirs.dirs");
+    }
+
+  file = fopen (config_file, "r");
+  free (config_file);
+  if (file == NULL)
+    goto error;
+
+  user_dir = NULL;
+  while (fgets (buffer, sizeof (buffer), file))
+    {
+      /* Remove newline at end */
+      len = strlen (buffer);
+      if (len > 0 && buffer[len-1] == '\n')
+	buffer[len-1] = 0;
+      
+      p = buffer;
+      while (*p == ' ' || *p == '\t')
+	p++;
+      
+      if (strncmp (p, "XDG_", 4) != 0)
+	continue;
+      p += 4;
+      if (strncmp (p, type, strlen (type)) != 0)
+	continue;
+      p += strlen (type);
+      if (strncmp (p, "_DIR", 4) != 0)
+	continue;
+      p += 4;
+
+      while (*p == ' ' || *p == '\t')
+	p++;
+
+      if (*p != '=')
+	continue;
+      p++;
+      
+      while (*p == ' ' || *p == '\t')
+	p++;
+
+      if (*p != '"')
+	continue;
+      p++;
+      
+      relative = 0;
+      if (strncmp (p, "$HOME/", 6) == 0)
+	{
+	  p += 6;
+	  relative = 1;
+	}
+      else if (*p != '/')
+	continue;
+      
+      if (relative)
+	{
+	  user_dir = malloc (strlen (home_dir) + 1 + strlen (p) + 1);
+	  strcpy (user_dir, home_dir);
+	  strcat (user_dir, "/");
+	}
+      else
+	{
+	  user_dir = malloc (strlen (p) + 1);
+	  *user_dir = 0;
+	}
+      
+      d = user_dir + strlen (user_dir);
+      while (*p && *p != '"')
+	{
+	  if ((*p == '\\') && (*(p+1) != 0))
+	    p++;
+	  *d++ = *p++;
+	}
+      *d = 0;
+    }  
+  fclose (file);
+
+  if (user_dir)
+    return user_dir;
+
+ error:
+  /* Special case desktop for historical compatibility */
+  if (strcmp (type, "DESKTOP") == 0)
+    {
+      user_dir = malloc (strlen (home_dir) + strlen ("/Desktop") + 1);
+      strcpy (user_dir, home_dir);
+      strcat (user_dir, "/Desktop");
+      return user_dir;
+    }
+  else
+    return strdup (home_dir);
+}
 
 int
 main (int argc, char **argv)
 {
   GtkWidget *window, *ui;
+  char *cwd, *download;
 
   /* We override the read color functions because we are using a GdkColor 
      structures to store the color. If I put this in lib/config_file.c, then 
@@ -1287,6 +1406,19 @@
   gtk_set_locale ();
   gtk_init (&argc, &argv);
 
+  cwd = g_get_current_dir ();
+  if (strcmp (cwd, g_get_home_dir ()) == 0)
+    {
+      /* We're launched from the home dir, probably started from the UI, default
+	 to the download directory */
+
+      download = xdg_user_dir_lookup ("DOWNLOAD");
+      chdir (download); /* Ignore errors */
+      free (download);
+    }
+  g_free (cwd);
+
+  
   graphic_hash_table = g_hash_table_new (string_hash_function,
                                          string_hash_compare);
 

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