file: get filesystem type asynchronously

We were peeking the filesystem type synchronously since nautilus
was checking for some file infos that are only required once
synchronously. However the call for the filesystem is usually slow
which makes nautilus main thread hang.

To avoid I/O in the main thread, make the filesystem type request
asynchronously and part of all the others attributes for the file.

https://bugzilla.gnome.org/show_bug.cgi?id=756280
parent 55e1b80a
......@@ -3951,6 +3951,7 @@ got_filesystem_info (FilesystemInfoState *state, GFileInfo *info)
{
NautilusDirectory *directory;
NautilusFile *file;
char *filesystem_type;
/* careful here, info may be NULL */
......@@ -3967,6 +3968,11 @@ got_filesystem_info (FilesystemInfoState *state, GFileInfo *info)
g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW);
file->details->filesystem_readonly =
g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
filesystem_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
if (g_strcmp0 (eel_ref_str_peek (file->details->filesystem_type), filesystem_type) != 0) {
eel_ref_str_unref (file->details->filesystem_type);
file->details->filesystem_type = eel_ref_str_get_unique (filesystem_type);
}
}
nautilus_directory_async_state_changed (directory);
......@@ -4038,7 +4044,8 @@ filesystem_info_start (NautilusDirectory *directory,
g_file_query_filesystem_info_async (location,
G_FILE_ATTRIBUTE_FILESYSTEM_READONLY ","
G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW,
G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW ","
G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
G_PRIORITY_DEFAULT,
state->cancellable,
query_filesystem_info_callback,
......
......@@ -601,55 +601,19 @@ nautilus_directory_is_in_recent (NautilusDirectory *directory)
return g_file_has_uri_scheme (directory->details->location, "recent");
}
static const gchar * const remote_types[] = {
"afp",
"google-drive",
"sftp",
"webdav",
"ftp",
"nfs",
"cifs",
NULL
};
gboolean
nautilus_directory_is_remote (NautilusDirectory *directory)
{
GFileInfo *info;
NautilusFile *file;
gboolean is_remote;
GError *error = NULL;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (NAUTILUS_IS_DIRECTORY (directory));
if (directory->details->location == NULL) {
return FALSE;
}
info = g_file_query_filesystem_info (directory->details->location, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
NULL, &error);
if (error) {
/* Custom schemas like x-nautilus-desktop or other-locations:///
* should not yell warnings */
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
g_warning ("Can't peek the uri: %s filesystem type with error: %s",
g_file_get_uri (directory->details->location), error->message);
}
g_clear_error (&error);
if (info) {
const gchar *type;
type = g_file_info_get_attribute_string (info, "filesystem::type");
if (type != NULL)
is_remote = g_strv_contains (remote_types, type);
else
is_remote = FALSE;
g_object_unref (info);
} else {
is_remote = FALSE;
}
file = nautilus_directory_get_corresponding_file (directory);
is_remote = nautilus_file_is_remote (file);
nautilus_file_unref (file);
return is_remote;
return is_remote;
}
gboolean
......
......@@ -203,6 +203,7 @@ struct NautilusFileDetails
eel_boolean_bit filesystem_readonly : 1;
eel_boolean_bit filesystem_use_preview : 2; /* GFilesystemPreviewType */
eel_boolean_bit filesystem_info_is_up_to_date : 1;
eel_ref_str filesystem_type;
time_t trash_time; /* 0 is unknown */
......
......@@ -837,6 +837,8 @@ finalize (GObject *object)
}
eel_ref_str_unref (file->details->filesystem_id);
eel_ref_str_unref (file->details->filesystem_type);
file->details->filesystem_type = NULL;
g_free (file->details->trash_orig_path);
g_list_free_full (file->details->mime_list, g_free);
......@@ -4057,6 +4059,27 @@ nautilus_file_get_filesystem_use_preview (NautilusFile *file)
return use_preview;
}
char *
nautilus_file_get_filesystem_type (NautilusFile *file)
{
NautilusFile *parent;
char *filesystem_type = NULL;
g_assert (NAUTILUS_IS_FILE (file));
if (nautilus_file_is_directory (file)) {
filesystem_type = g_strdup (eel_ref_str_peek (file->details->filesystem_type));
} else {
parent = nautilus_file_get_parent (file);
if (parent != NULL) {
filesystem_type = g_strdup (eel_ref_str_peek (parent->details->filesystem_type));
nautilus_file_unref (parent);
}
}
return filesystem_type;
}
gboolean
nautilus_file_should_show_thumbnail (NautilusFile *file)
{
......@@ -7003,25 +7026,36 @@ nautilus_file_is_in_recent (NautilusFile *file)
return nautilus_directory_is_in_recent (file->details->directory);
}
static const gchar * const remote_types[] = {
"afp",
"google-drive",
"sftp",
"webdav",
"ftp",
"nfs",
"cifs",
NULL
};
/**
* nautilus_file_is_remote
*
* Check if this file is a file in Network.
*
* Check if this file is a file in a remote filesystem.
* @file: NautilusFile representing the file in question.
*
* Returns: TRUE if @file is in Network.
*
* Returns: TRUE if @file is in a remote filesystem.
*
**/
gboolean
nautilus_file_is_remote (NautilusFile *file)
{
g_assert (NAUTILUS_IS_FILE (file));
char *filesystem_type;
g_assert (NAUTILUS_IS_FILE (file));
if (nautilus_file_is_directory (file))
return nautilus_directory_is_remote (nautilus_directory_get_for_file (file));
else
return nautilus_directory_is_remote (file->details->directory);
filesystem_type = nautilus_file_get_filesystem_type (file);
return filesystem_type != NULL && g_strv_contains (remote_types, filesystem_type);
}
/**
......
......@@ -218,6 +218,8 @@ GFilesystemPreviewType nautilus_file_get_filesystem_use_preview (Nautilu
char * nautilus_file_get_filesystem_id (NautilusFile *file);
char * nautilus_file_get_filesystem_type (NautilusFile *file);
NautilusFile * nautilus_file_get_trash_original_file (NautilusFile *file);
/* Permissions. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment