Index: gtkfilesystemgnomevfs.c
===================================================================
RCS file: /cvs/gnome/libgnomeui/file-chooser/gtkfilesystemgnomevfs.c,v
retrieving revision 1.86
diff -u -p -r1.86 gtkfilesystemgnomevfs.c
--- gtkfilesystemgnomevfs.c	3 Dec 2006 21:15:27 -0000	1.86
+++ gtkfilesystemgnomevfs.c	4 Dec 2006 09:14:31 -0000
@@ -102,6 +102,7 @@ profile_log (const char *func, int inden
 
 #define BOOKMARKS_FILENAME ".gtk-bookmarks"
 #define BOOKMARKS_TMP_FILENAME ".gtk-bookmarks-XXXXXX"
+#define HIDDEN_FILENAME ".hidden"
 
 #define DESKTOP_GROUP "Desktop Entry"
 
@@ -188,6 +189,7 @@ struct _GtkFileFolderGnomeVFS
 
   guint is_afs_or_net : 1;
   guint finished_loading : 1;
+  guint have_hidden : 1;
 };
 
 typedef struct _FolderChild FolderChild;
@@ -388,6 +390,12 @@ static FolderChild *lookup_folder_child 
 static FolderChild *lookup_folder_child_from_uri (GtkFileFolder     *folder,
 						  const char        *uri);
 
+static gboolean get_is_hidden_for_file (const char *filename,
+                                        const char *basename);
+static gboolean file_is_hidden (GtkFileFolderUnix *folder_unix,
+                                const char        *basename);
+static void     fill_in_hidden    (GtkFileFolderUnix  *folder_unix);
+
 static GObjectClass *system_parent_class;
 static GObjectClass *folder_parent_class;
 static GObjectClass *handle_parent_class;
@@ -1009,6 +1017,7 @@ struct GetFolderData
   GnomeVFSURI *uri;
   char *vfs_uri;
   GtkFileInfoType types;
+  gboolean hidden;
 };
 
 static void
@@ -1292,6 +1301,7 @@ gtk_file_system_gnome_vfs_get_folder (Gt
       op_data->folder_vfs = folder_vfs;
       op_data->callback = callback;
       op_data->callback_data = data;
+      op_data->hidden = FALSE;
 
       queue_vfs_idle_callback (system_vfs, get_folder_cached_callback, op_data);
 
@@ -1345,6 +1355,7 @@ gtk_file_system_gnome_vfs_get_folder (Gt
   op_data->callback = callback;
   op_data->callback_data = data;
   op_data->parent_folder = parent_folder;
+  op_data->hidden = FALSE;
   if (vfs_info)
     {
       op_data->file_info = gnome_vfs_file_info_new ();
@@ -3487,6 +3498,110 @@ has_valid_scheme (const char *uri)
   return *p == ':';
 }
 
+static gchar **
+read_hidden_file (const char *dirname)
+{
+  gchar **lines = NULL;
+  gchar *contents;
+  gchar *hidden_file;
+
+  hidden_file = g_build_filename (dirname, HIDDEN_FILENAME, NULL);
+
+  if (g_file_get_contents (hidden_file, &contents, NULL, NULL))
+    {
+      lines = g_strsplit (contents, "\n", -1);
+      g_free (contents);
+    }
+
+  g_free (hidden_file);
+
+  return lines;
+}
+
+static void
+fill_in_hidden (GtkFileFolderUnix *folder_unix)
+{
+  gchar **lines;
+
+  if (folder_unix->have_hidden)
+    return;
+
+  lines = read_hidden_file (folder_unix->filename);
+
+  if (lines)
+    {
+      int i;
+
+      for (i = 0; lines[i]; i++)
+        {
+          if (lines[i][0])
+            {
+              struct stat_info_entry *entry;
+
+              entry = g_hash_table_lookup (folder_unix->stat_info, lines[i]);
+              if (entry != NULL)
+                entry->hidden = TRUE;
+            }
+        }
+
+      g_strfreev (lines);
+    }
+
+  folder_unix->have_hidden = TRUE;
+}
+
+static gboolean
+get_is_hidden_for_file (const char *filename,
+                        const char *basename)
+{
+  gchar *dirname;
+  gchar **lines;
+  gboolean hidden = FALSE;
+
+  dirname = g_path_get_dirname (filename);
+  lines = read_hidden_file (dirname);
+  g_free (dirname);
+
+  if (lines)
+    {
+      int i;
+
+      for (i = 0; lines[i]; i++)
+        {
+          if (lines[i][0] && strcmp (lines[i], basename) == 0)
+            {
+              hidden = TRUE;
+              break;
+            }
+        }
+
+      g_strfreev (lines);
+    }
+
+  return hidden;
+}
+
+static gboolean
+file_is_hidden (GtkFileFolderUnix *folder_unix,
+                const char        *basename)
+{
+ struct stat_info_entry *entry;
+
+  if (basename[0] == '.' || basename[strlen (basename) - 1] == '~')
+    return TRUE;
+
+  if (folder_unix->have_stat)
+    {
+      fill_in_hidden (folder_unix);
+
+      entry = g_hash_table_lookup (folder_unix->stat_info, basename);
+
+      if (entry)
+        return entry->hidden;
+    }
+
+  return FALSE;
+}
 
 /*
  * GtkFileSystemHandleGnomeVFS
