Blob Blame History Raw
From 4eaecde496bdff18eedbd82bd94f2fc67e9d6dff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 9 Sep 2017 09:32:40 +0200
Subject: [PATCH 3/5] file-operations: Let file/directory creation work on
 Google Drive Immediately check the volatility of the newly created file or
 directory and switch to using the "real" persistent URI. The following
 operations are affected:   - creating new directories   - creating new files
 from templates   - dragging & dropping text to create new files   - copying
 and moving of files and directories

The Google Drive backend doesn't support creating symbolic links so we
ignore that case.

https://bugzilla.gnome.org/show_bug.cgi?id=751481
---
 configure.ac                           |   2 +-
 libnemo-private/nemo-file-operations.c | 175 +++++++++++++++++++++++++++++----
 2 files changed, 159 insertions(+), 18 deletions(-)

diff --git a/configure.ac b/configure.ac
index 805b11c22..a87ba29ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ(2.54)
 
 dnl ===========================================================================
 
-m4_define(glib_minver,                 2.37.3)
+m4_define(glib_minver,                 2.45.7)
 m4_define(cinnamon_desktop_minver,     2.6.1)
 m4_define(pango_minver,                1.28.3)
 m4_define(gtk_minver,                  3.9.10)
diff --git a/libnemo-private/nemo-file-operations.c b/libnemo-private/nemo-file-operations.c
index 06bf7959d..7d86a695c 100644
--- a/libnemo-private/nemo-file-operations.c
+++ b/libnemo-private/nemo-file-operations.c
@@ -3536,6 +3536,82 @@ is_dir (GFile *file)
 	return res;
 }
 
+static GFile*
+map_possibly_volatile_file_to_real (GFile *volatile_file,
+				    GCancellable *cancellable,
+				    GError **error)
+{
+	GFile *real_file = NULL;
+	GFileInfo *info = NULL;
+
+	info = g_file_query_info (volatile_file,
+				  G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","
+				  G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE","
+				  G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
+				  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+				  cancellable,
+				  error);
+	if (info == NULL) {
+		return NULL;
+	} else {
+		gboolean is_volatile;
+
+		is_volatile = g_file_info_get_attribute_boolean (info,
+								 G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE);
+		if (is_volatile) {
+			const gchar *target;
+
+			target = g_file_info_get_symlink_target (info);
+			real_file = g_file_resolve_relative_path (volatile_file, target);
+		}
+	}
+
+	g_object_unref (info);
+
+	if (real_file == NULL)
+		real_file = g_object_ref (volatile_file);
+
+	return real_file;
+}
+
+static GFile*
+map_possibly_volatile_file_to_real_on_write (GFile *volatile_file,
+					     GFileOutputStream *stream,
+					     GCancellable *cancellable,
+					     GError **error)
+{
+	GFile *real_file = NULL;
+	GFileInfo *info = NULL;
+
+	info = g_file_output_stream_query_info (stream,
+						G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","
+						G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE","
+						G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
+						cancellable,
+						error);
+	if (info == NULL) {
+		return NULL;
+	} else {
+		gboolean is_volatile;
+
+		is_volatile = g_file_info_get_attribute_boolean (info,
+								 G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE);
+		if (is_volatile) {
+			const gchar *target;
+
+			target = g_file_info_get_symlink_target (info);
+			real_file = g_file_resolve_relative_path (volatile_file, target);
+		}
+	}
+
+	g_object_unref (info);
+
+	if (real_file == NULL)
+		real_file = g_object_ref (volatile_file);
+
+	return real_file;
+}
+
 static void copy_move_file (CopyMoveJob *job,
 			    GFile *src,
 			    GFile *dest_dir,
@@ -3568,6 +3644,7 @@ create_dest_dir (CommonJob *job,
 	char *primary, *secondary, *details;
 	int response;
 	gboolean handled_invalid_filename;
+	gboolean res;
 
 	handled_invalid_filename = *dest_fs_type != NULL;
 
@@ -3576,7 +3653,21 @@ create_dest_dir (CommonJob *job,
 	   copying the attributes, because we need to be sure we can write to it */
 	
 	error = NULL;
-	if (!g_file_make_directory (*dest, job->cancellable, &error)) {
+	res = g_file_make_directory (*dest, job->cancellable, &error);
+
+	if (res) {
+		GFile *real;
+
+		real = map_possibly_volatile_file_to_real (*dest, job->cancellable, &error);
+		if (real == NULL) {
+			res = FALSE;
+		} else {
+			g_object_unref (*dest);
+			*dest = real;
+		}
+	}
+
+	if (!res) {
 		if (IS_IO_ERROR (error, CANCELLED)) {
 			g_error_free (error);
 			return CREATE_DEST_DIR_FAILED;
@@ -4387,6 +4478,18 @@ copy_move_file (CopyMoveJob *copy_job,
 	}
 	
 	if (res) {
+		GFile *real;
+
+		real = map_possibly_volatile_file_to_real (dest, job->cancellable, &error);
+		if (real == NULL) {
+			res = FALSE;
+		} else {
+			g_object_unref (dest);
+			dest = real;
+		}
+	}
+
+	if (res) {
 		transfer_info->num_files ++;
 		report_copy_progress (copy_job, source_info, transfer_info);
 
@@ -6228,6 +6331,18 @@ create_job (GIOSchedulerJob *io_job,
 					     common->cancellable,
 					     &error);
 
+		if (res) {
+			GFile *real;
+
+			real = map_possibly_volatile_file_to_real (dest, common->cancellable, &error);
+			if (real == NULL) {
+				res = FALSE;
+			} else {
+				g_object_unref (dest);
+				dest = real;
+			}
+		}
+
 		if (res && common->undo_info != NULL) {
 			nemo_file_undo_info_create_set_data (NEMO_FILE_UNDO_INFO_CREATE (common->undo_info),
 								 dest, NULL, 0);
@@ -6242,6 +6357,18 @@ create_job (GIOSchedulerJob *io_job,
 					   NULL, NULL,
 					   &error);
 
+			if (res) {
+				GFile *real;
+
+				real = map_possibly_volatile_file_to_real (dest, common->cancellable, &error);
+				if (real == NULL) {
+					res = FALSE;
+				} else {
+					g_object_unref (dest);
+					dest = real;
+				}
+			}
+
 			if (res && common->undo_info != NULL) {
 				gchar *uri;
 
@@ -6265,24 +6392,38 @@ create_job (GIOSchedulerJob *io_job,
 					     common->cancellable,
 					     &error);
 			if (out) {
-				res = g_output_stream_write_all (G_OUTPUT_STREAM (out),
-								 data, length,
-								 NULL,
-								 common->cancellable,
-								 &error);
-				if (res) {
-					res = g_output_stream_close (G_OUTPUT_STREAM (out),
-								     common->cancellable,
-								     &error);
-
-					if (res && common->undo_info != NULL) {
-						nemo_file_undo_info_create_set_data (NEMO_FILE_UNDO_INFO_CREATE (common->undo_info),
-											 dest, data, length);
+				GFile *real;
+
+				real = map_possibly_volatile_file_to_real_on_write (dest,
+										    out,
+										    common->cancellable,
+										    &error);
+				if (real == NULL) {
+					res = FALSE;
+					g_object_unref (out);
+				} else {
+					g_object_unref (dest);
+					dest = real;
+
+					res = g_output_stream_write_all (G_OUTPUT_STREAM (out),
+									 data, length,
+									 NULL,
+									 common->cancellable,
+									 &error);
+					if (res) {
+						res = g_output_stream_close (G_OUTPUT_STREAM (out),
+									     common->cancellable,
+									     &error);
+
+						if (res && common->undo_info != NULL) {
+							nemo_file_undo_info_create_set_data (NEMO_FILE_UNDO_INFO_CREATE (common->undo_info),
+												 dest, data, length);
+						}
 					}
-				}
 
-				/* This will close if the write failed and we didn't close */
-				g_object_unref (out);
+					/* This will close if the write failed and we didn't close */
+					g_object_unref (out);
+				}
 			} else {
 				res = FALSE;
 			}

From aea38dc263cd33b87a2044347a27692f0b6d80db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 9 Sep 2017 09:38:15 +0200
Subject: [PATCH 4/5] Do not set an activation URI for files in Trash
 https://bugzilla.gnome.org/show_bug.cgi?id=689248

---
 libnemo-private/nemo-file.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libnemo-private/nemo-file.c b/libnemo-private/nemo-file.c
index 012e25780..62945f04f 100644
--- a/libnemo-private/nemo-file.c
+++ b/libnemo-private/nemo-file.c
@@ -2224,7 +2224,8 @@ update_info_internal (NemoFile *file,
 	}
 	file->details->type = file_type;
 
-	if (!file->details->got_custom_activation_uri) {
+	if (!file->details->got_custom_activation_uri &&
+	    !nemo_file_is_in_trash (file)) {
 		activation_uri = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
 		if (activation_uri == NULL) {
 			if (file->details->activation_uri) {
@@ -2235,7 +2236,7 @@ update_info_internal (NemoFile *file,
 		} else {
 			old_activation_uri = file->details->activation_uri;
 			file->details->activation_uri = g_strdup (activation_uri);
-			
+
 			if (old_activation_uri) {
 				if (strcmp (old_activation_uri,
 					    file->details->activation_uri) != 0) {

From f2ad4a52947c53107f6017db0db79553175d3582 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 9 Sep 2017 09:46:40 +0200
Subject: [PATCH 5/5] file: Set activation URI for certain files only Drag&drop
 of native Google Drive files doesn't work correctly, because target path is
 used, which causes requests for HTTP backend and fails. The activation URI is
 used for drag&drop since some time ago. Recently, this behavior has been
 disabled for trash locations. This behavior seems to make sense for recent
 locations in order to allow dropping in applications, which are not based on
 GLib/GIO. It also makes sense for afpbrowse, dnssd, network, and smbbrowse
 backends when mounting and bookmarking. Let's set the activation URI only for
 the mentioned. This change should not affect nautilus links (i.e. desktop
 files and symlinks), which are handled by different codepath, it should
 affectonly certain GVfs backends.

https://bugzilla.gnome.org/show_bug.cgi?id=768168
---
 libnemo-private/nemo-file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libnemo-private/nemo-file.c b/libnemo-private/nemo-file.c
index 62945f04f..88d8ee27b 100644
--- a/libnemo-private/nemo-file.c
+++ b/libnemo-private/nemo-file.c
@@ -2225,7 +2225,8 @@ update_info_internal (NemoFile *file,
 	file->details->type = file_type;
 
 	if (!file->details->got_custom_activation_uri &&
-	    !nemo_file_is_in_trash (file)) {
+           (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL) ||
+            nemo_file_is_in_recent (file))) {
 		activation_uri = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
 		if (activation_uri == NULL) {
 			if (file->details->activation_uri) {