jun7 / rox-filer

ROX file manager
24 stars 6 forks source link

Support .hidden file #221

Closed JakeSFR closed 3 years ago

JakeSFR commented 3 years ago

There's this annoying thing about Wine that some of the installed apps (games) add new folders, like "My Games" to $HOME, what increases the clutter and annoys me.

I was thinking what could we do about it and remembered that some file managers (now probably all that use g_file_info_get_is_hidden) support the '.hidden' file. Not sure if you're familiar with that thing? You can create a list of items you don't want to be displayed in a given directory and file manager treats them as hidden DOTfiles.

Luckily, it turned out that there's no need to implement the whole thing from square one, because it is already supported by GIO since 2.36.

It adds some overhead, not huge, but noticeable, while opening a directory with many files (thousands), so I made it optional. The slowdown is only slightly bigger than in e.g. SpaceFM.

Here's how the patch looks like:

diff -ur rox-filer_old/ROX-Filer/Options.xml rox-filer_new/ROX-Filer/Options.xml
--- rox-filer_old/ROX-Filer/Options.xml 2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/Options.xml 2021-09-09 23:37:12.775709611 +0200
@@ -65,6 +65,8 @@
    </vbox></hbox>
    <toggle name='display_show_hidden' label='Show hidden files'>
        If this is on then files whose names start with a dot are shown too, otherwise they are hidden.</toggle>
+   <toggle name='enable_dot_hidden_file' label='Enable .hidden file'>
+       If this is on then, in addition to files whose names start with a dot, also items listed in ".hidden" file will be treated as hidden.</toggle>
    <spacer/>
    <numentry name='huge_size' label='Huge Icons size:' unit='pixels' min='64' max='1024' width='4'>
        Resolution depends on 'Thumbnails->Cache File Size'.</numentry>
diff -ur rox-filer_old/ROX-Filer/src/display.c rox-filer_new/ROX-Filer/src/display.c
--- rox-filer_old/ROX-Filer/src/display.c   2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/src/display.c   2021-09-09 23:43:50.382750474 +0200
@@ -67,6 +67,7 @@
 Option o_small_width;
 Option o_max_length;
 Option o_display_show_hidden;
+Option o_enable_dot_hidden_file;
 Option o_display_show_thumbs;
 Option o_display_show_dir_thumbs;
 Option o_display_show_headers;
@@ -113,6 +114,7 @@
               "display_inherit_options", FALSE);
    option_add_int(&o_display_sort_by, "display_sort_by", SORT_NAME);
    option_add_int(&o_display_show_hidden, "display_show_hidden", TRUE);
+   option_add_int(&o_enable_dot_hidden_file, "enable_dot_hidden_file", FALSE);
    option_add_int(&o_xattr_show, "xattr_show", TRUE);
    option_add_string(&o_time_format, "time_format", COMPACT_TIME_FORMAT);
    option_add_int(&o_huge_size, "huge_size", HUGE_SIZE);
diff -ur rox-filer_old/ROX-Filer/src/display.h rox-filer_new/ROX-Filer/src/display.h
--- rox-filer_old/ROX-Filer/src/display.h   2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/src/display.h   2021-09-09 23:36:59.981708296 +0200
@@ -31,6 +31,7 @@
 extern Option o_display_dirs_first;
 extern Option o_display_inherit_options, o_display_sort_by;
 extern Option o_display_size, o_display_details, o_display_show_hidden;
+extern Option o_enable_dot_hidden_file;
 extern Option o_display_show_headers, o_display_show_full_type;
 extern Option o_display_show_thumbs;
 extern Option o_display_show_dir_thumbs;
diff -ur rox-filer_old/ROX-Filer/src/filer.c rox-filer_new/ROX-Filer/src/filer.c
--- rox-filer_old/ROX-Filer/src/filer.c 2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/src/filer.c 2021-09-09 23:39:30.986723815 +0200
@@ -3942,6 +3942,31 @@
    if(item->leafname[0]=='.')
        return TRUE;

+   /* Additional method, using GIO, to support '.hidden' file,
+    * which contains a list of items to hide in a given directory
+   */
+   if (o_enable_dot_hidden_file.int_value) {
+       gchar       *path;
+       GFile       *file = NULL;
+       GFileInfo   *info = NULL;
+       GError      *error = NULL;
+       
+       path = g_build_filename(dir, item->leafname, NULL);
+       file = g_file_new_for_path(path);
+       info = g_file_query_info (file,
+               G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
+               G_FILE_QUERY_INFO_NONE,
+               NULL, &error);
+       
+       if ((!error) && (g_file_info_get_is_hidden(info))) {
+           return TRUE;
+       }
+       
+       if (info) g_object_unref(info);
+       g_object_unref(file);
+       g_free(path);
+   }
+
    /*** Test disabled for now.  The flags aren't set on the first pass...
     */
 #if 0

It works, however it would be much better to execute the above block of code only if the '.hidden' file actually exists in current directory. It would remove the overhead completely for directories without that file. Not sure how to do it, though... Maybe some global variable, like gboolean dot_hidden_file_exists would do the trick? It would be set to either TRUE or FALSE right after entering a new directory, but before iterating through items, and then we could check it later in 'is_hidden()' with e.g.:

if ((o_enable_dot_hidden_file.int_value) && (dot_hidden_file_exists == TRUE)) {
...
}

Anyway, what do you think about this idea at all?

JakeSFR commented 3 years ago

Oh, I just realized that if this:

if ((!error) && (g_file_info_get_is_hidden(info))) {
    return TRUE;
}

returns TRUE, the stuff here:

if (info) g_object_unref(info);
g_object_unref(file);
g_free(path);

isn't freed.

Fixed patch:

diff -ur rox-filer_old/ROX-Filer/Options.xml rox-filer_new/ROX-Filer/Options.xml
--- rox-filer_old/ROX-Filer/Options.xml 2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/Options.xml 2021-09-10 13:29:48.284425701 +0200
@@ -65,6 +65,8 @@
    </vbox></hbox>
    <toggle name='display_show_hidden' label='Show hidden files'>
        If this is on then files whose names start with a dot are shown too, otherwise they are hidden.</toggle>
+   <toggle name='enable_dot_hidden_file' label='Enable .hidden file'>
+       If this is on then, in addition to files whose names start with a dot, also items listed in ".hidden" file will be treated as hidden.</toggle>
    <spacer/>
    <numentry name='huge_size' label='Huge Icons size:' unit='pixels' min='64' max='1024' width='4'>
        Resolution depends on 'Thumbnails->Cache File Size'.</numentry>
diff -ur rox-filer_old/ROX-Filer/src/display.c rox-filer_new/ROX-Filer/src/display.c
--- rox-filer_old/ROX-Filer/src/display.c   2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/src/display.c   2021-09-10 13:29:48.285425701 +0200
@@ -67,6 +67,7 @@
 Option o_small_width;
 Option o_max_length;
 Option o_display_show_hidden;
+Option o_enable_dot_hidden_file;
 Option o_display_show_thumbs;
 Option o_display_show_dir_thumbs;
 Option o_display_show_headers;
@@ -113,6 +114,7 @@
               "display_inherit_options", FALSE);
    option_add_int(&o_display_sort_by, "display_sort_by", SORT_NAME);
    option_add_int(&o_display_show_hidden, "display_show_hidden", TRUE);
+   option_add_int(&o_enable_dot_hidden_file, "enable_dot_hidden_file", FALSE);
    option_add_int(&o_xattr_show, "xattr_show", TRUE);
    option_add_string(&o_time_format, "time_format", COMPACT_TIME_FORMAT);
    option_add_int(&o_huge_size, "huge_size", HUGE_SIZE);
diff -ur rox-filer_old/ROX-Filer/src/display.h rox-filer_new/ROX-Filer/src/display.h
--- rox-filer_old/ROX-Filer/src/display.h   2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/src/display.h   2021-09-10 13:29:48.285425701 +0200
@@ -31,6 +31,7 @@
 extern Option o_display_dirs_first;
 extern Option o_display_inherit_options, o_display_sort_by;
 extern Option o_display_size, o_display_details, o_display_show_hidden;
+extern Option o_enable_dot_hidden_file;
 extern Option o_display_show_headers, o_display_show_full_type;
 extern Option o_display_show_thumbs;
 extern Option o_display_show_dir_thumbs;
diff -ur rox-filer_old/ROX-Filer/src/filer.c rox-filer_new/ROX-Filer/src/filer.c
--- rox-filer_old/ROX-Filer/src/filer.c 2021-05-20 05:26:09.000000000 +0200
+++ rox-filer_new/ROX-Filer/src/filer.c 2021-09-10 13:30:40.179429737 +0200
@@ -3942,6 +3942,34 @@
    if(item->leafname[0]=='.')
        return TRUE;

+   /* Additional method, using GIO, to support '.hidden' file,
+    * which contains a list of items to hide in a given directory
+   */
+   if (o_enable_dot_hidden_file.int_value) {
+       gchar       *path;
+       GFile       *file = NULL;
+       GFileInfo   *info = NULL;
+       GError      *error = NULL;
+       gboolean    file_hidden = FALSE;
+       
+       path = g_build_filename(dir, item->leafname, NULL);
+       file = g_file_new_for_path(path);
+       info = g_file_query_info (file,
+               G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
+               G_FILE_QUERY_INFO_NONE,
+               NULL, &error);
+       
+       if ((!error) && (g_file_info_get_is_hidden(info))) {
+           file_hidden = TRUE;
+       }
+       
+       if (info) g_object_unref(info);
+       g_object_unref(file);
+       g_free(path);
+       
+       return file_hidden;
+   }
+
    /*** Test disabled for now.  The flags aren't set on the first pass...
     */
 #if 0
jun7 commented 3 years ago

Very interesting! I will pull it when you make PR.

jun7 commented 3 years ago

BTW the middle button assign of the Home button is for the clutter of the $HOME. I have thowed $HOME already. so I'm happy to hear that others hate the clutter too.

JakeSFR commented 3 years ago

Very interesting! I will pull it when you make PR.

Ok, done: https://github.com/jun7/rox-filer/pull/222

BTW the middle button assign of the Home button is for the clutter of the $HOME. I have thowed $HOME already. so I'm happy to hear that others hate the clutter too.

Oh, I didn't even notice that it switches to the first bookmark, nice.

Thanks!