[baobab/gnome-3-34] Query filesystem usage asynchronously



commit 2c5c08910fde2d27321c8002728d727bf5ecb6c6
Author: Stefano Facchini <stefano facchini gmail com>
Date:   Wed May 27 10:31:09 2020 +0200

    Query filesystem usage asynchronously
    
    Remote mounts could be slow to report the information, blocking the UI.

 src/baobab-location-list.vala | 25 ++++--------
 src/baobab-location.vala      | 88 +++++++++++++++++++++++++------------------
 src/baobab-window.vala        |  2 +-
 3 files changed, 60 insertions(+), 55 deletions(-)
---
diff --git a/src/baobab-location-list.vala b/src/baobab-location-list.vala
index 344cc7f..89cac3c 100644
--- a/src/baobab-location-list.vala
+++ b/src/baobab-location-list.vala
@@ -39,11 +39,7 @@ namespace Baobab {
 
         public LocationRow (Location l) {
             location = l;
-            update ();
-        }
 
-        public void update () {
-            location.get_fs_usage ();
             image.gicon = location.icon;
 
             var escaped = GLib.Markup.escape_text (location.name, -1);
@@ -51,7 +47,7 @@ namespace Baobab {
 
             path_label.hide();
             if (location.file != null) {
-                path_label.label = GLib.Markup.escape_text (location.file.get_parse_name (), -1);
+                path_label.label = Markup.escape_text (location.file.get_parse_name (), -1);
                 path_label.show();
             }
 
@@ -60,8 +56,13 @@ namespace Baobab {
             // more important
             path_label.ellipsize = location.is_remote ? Pango.EllipsizeMode.END : Pango.EllipsizeMode.START;
 
+            update_fs_usage_info ();
+            location.changed.connect (() => { update_fs_usage_info (); });
+        }
+
+        void update_fs_usage_info () {
             total_size_label.hide();
-            if (location.is_volume || location.is_main_volume) {
+            if (location.volume != null || location.mount != null || location.is_main_volume) {
                 if (location.size != null) {
                     total_size_label.label = _("%s Total").printf (format_size (location.size));
                     total_size_label.show();
@@ -82,7 +83,7 @@ namespace Baobab {
                     // useful for some remote mounts where we don't know the
                     // size but do have a usage figure
                     available_label.label = _("%s Used").printf (format_size (location.used));
-                } else if (location.mount == null && location.volume.can_mount ()) {
+                } else if (location.volume != null && location.mount == null && location.volume.can_mount 
()) {
                     available_label.label = _("Unmounted");
                 }
             }
@@ -122,19 +123,9 @@ namespace Baobab {
             remote_list_box.set_header_func (update_header);
             remote_list_box.row_activated.connect (row_activated);
 
-            Timeout.add_seconds(3, (() => {
-                update_existing ();
-                return Source.CONTINUE;
-            }));
-
             populate ();
         }
 
-        void update_existing () {
-            local_list_box.foreach ((widget) => { ((LocationRow)widget).update (); });
-            remote_list_box.foreach ((widget) => { ((LocationRow)widget).update (); });
-        }
-
         bool already_present (File file) {
             foreach (var l in locations) {
                 if (l.file != null && l.file.equal (file)) {
diff --git a/src/baobab-location.vala b/src/baobab-location.vala
index 085225d..433c8a6 100644
--- a/src/baobab-location.vala
+++ b/src/baobab-location.vala
@@ -31,7 +31,6 @@ namespace Baobab {
         public string name { get; private set; }
         public File? file { get; private set; }
         public FileInfo? info { get; private set; }
-        public bool is_volume { get; private set; default = true; }
 
         public uint64? size { get; private set; }
         public uint64? used { get; private set; }
@@ -47,6 +46,10 @@ namespace Baobab {
 
         public Scanner? scanner { get; private set; }
 
+        public signal void changed ();
+
+        private bool querying_fs = false;
+
         private const string FS_ATTRIBUTES =
             FileAttribute.FILESYSTEM_SIZE + "," +
             FileAttribute.FILESYSTEM_USED;
@@ -75,13 +78,13 @@ namespace Baobab {
         }
 
         public Location.for_home_folder () {
-            is_volume = false;
             file = File.new_for_path (GLib.Environment.get_home_dir ());
             get_file_info ();
-            get_fs_usage ();
 
             make_this_home_location ();
 
+            start_fs_usage_timeout ();
+
             scanner = new Scanner (file, ScanFlags.EXCLUDE_MOUNTS);
         }
 
@@ -118,27 +121,21 @@ namespace Baobab {
             icon = new ThemedIcon.with_default_fallbacks ("drive-harddisk-system");
             is_main_volume = true;
 
-            get_fs_usage ();
+            start_fs_usage_timeout ();
 
             scanner = new Scanner (file, ScanFlags.EXCLUDE_MOUNTS);
         }
 
         public Location.for_recent_info (Gtk.RecentInfo recent_info) {
-            is_volume = false; // we assume recent locations are just folders
             is_recent = true;
             file = File.new_for_uri (recent_info.get_uri ());
             name = recent_info.get_display_name ();
             icon = recent_info.get_gicon ();
 
-            if (recent_info.is_local ()) {
-                get_fs_usage ();
-            }
-
             scanner = new Scanner (file, ScanFlags.EXCLUDE_MOUNTS);
         }
 
         public Location.for_file (File file_, ScanFlags flags) {
-            is_volume = false;
             file = file_;
             get_file_info ();
 
@@ -150,8 +147,6 @@ namespace Baobab {
                 icon = null;
             }
 
-            get_fs_usage ();
-
             scanner = new Scanner (file, flags);
         }
 
@@ -187,7 +182,7 @@ namespace Baobab {
                 make_this_home_location ();
             }
 
-            get_fs_usage ();
+            start_fs_usage_timeout ();
 
             scanner = new Scanner (file, ScanFlags.EXCLUDE_MOUNTS);
         }
@@ -200,34 +195,53 @@ namespace Baobab {
             }
         }
 
-        public void get_fs_usage () {
-            if (file == null) {
+        void start_fs_usage_timeout () {
+            queue_query_fs_usage ();
+            Timeout.add_seconds(2, (() => {
+                queue_query_fs_usage ();
+                return Source.CONTINUE;
+            }));
+        }
+
+        void queue_query_fs_usage () {
+            if (querying_fs || file == null) {
                 return;
             }
 
-            size = null;
-            used = null;
-            reserved = null;
-            try {
-                var info = file.query_filesystem_info (FS_ATTRIBUTES, null);
-                if (info.has_attribute (FileAttribute.FILESYSTEM_SIZE)) {
-                    size = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_SIZE);
-                }
-                if (info.has_attribute (FileAttribute.FILESYSTEM_USED)) {
-                    used = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_USED);
-                }
-                if (size != null && used != null && info.has_attribute (FileAttribute.FILESYSTEM_FREE)) {
-                    var free = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_FREE);
-                    reserved = size - free - used;
-                }
-            } catch (Error e) {
-            }
-            // this can happen sometimes with remote mounts. The result, if
-            // unchecked, is a uint64 underflow and the drive being presented
-            // with 18.4 EB free
-            if (size != null && used != null && used > size) {
+            querying_fs = true;
+
+            file.query_filesystem_info_async (FS_ATTRIBUTES, Priority.DEFAULT, null, (obj, res) => {
+                querying_fs = false;
+
                 size = null;
-            }
+                used = null;
+                reserved = null;
+
+                try {
+                    var info = file.query_filesystem_info_async.end (res);
+                    if (info.has_attribute (FileAttribute.FILESYSTEM_SIZE)) {
+                        size = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_SIZE);
+                    }
+                    if (info.has_attribute (FileAttribute.FILESYSTEM_USED)) {
+                        used = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_USED);
+                    }
+                    if (size != null && used != null && info.has_attribute (FileAttribute.FILESYSTEM_FREE)) {
+                        var free = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_FREE);
+                        reserved = size - free - used;
+                    }
+
+                    // this can happen sometimes with remote mounts. The result, if
+                    // unchecked, is a uint64 underflow and the drive being presented
+                    // with 18.4 EB free
+                    if (size != null && used != null && used > size) {
+                        size = null;
+                    }
+
+                    changed ();
+                } catch (Error e) {
+                }
+
+            });
         }
 
         public async void mount_volume () throws Error {
diff --git a/src/baobab-window.vala b/src/baobab-window.vala
index c91bf46..f6da4cb 100644
--- a/src/baobab-window.vala
+++ b/src/baobab-window.vala
@@ -250,7 +250,7 @@ namespace Baobab {
         void on_scan_location_activate (Location location) {
             set_active_location (location);
 
-            if (location.is_volume) {
+            if (location.volume != null) {
                 location.mount_volume.begin ((location_, res) => {
                     try {
                         location.mount_volume.end (res);


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