[console] tab: Convert dnd file URIs to shell quoted strings



commit ad6719a553f4e822b16c454e5d24dc0ae47eeb59
Author: Colin Kinloch <colin kinlo ch>
Date:   Sat Mar 26 01:12:42 2022 +0000

    tab: Convert dnd file URIs to shell quoted strings
    
    Fix: https://gitlab.gnome.org/GNOME/console/-/issues/122

 src/kgx-tab.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 1 deletion(-)
---
diff --git a/src/kgx-tab.c b/src/kgx-tab.c
index 5bc4f84..bc182e5 100644
--- a/src/kgx-tab.c
+++ b/src/kgx-tab.c
@@ -838,6 +838,7 @@ kgx_tab_init (KgxTab *self)
 
   gtk_drag_dest_set (GTK_WIDGET (self), GTK_DEST_DEFAULT_ALL, NULL, 0,
                      GDK_ACTION_COPY);
+  gtk_drag_dest_add_uri_targets (GTK_WIDGET (self));
   gtk_drag_dest_add_text_targets (GTK_WIDGET (self));
 }
 
@@ -1223,21 +1224,96 @@ kgx_tab_get_children (KgxTab *self)
 }
 
 
+/**
+ * terminal_util_transform_uris_to_quoted_fuse_paths:
+ * @uris:
+ *
+ * Transforms those URIs in @uris to shell-quoted paths that point to
+ * GIO fuse paths.
+ */
+static void
+terminal_util_transform_uris_to_quoted_fuse_paths (GStrv uris)
+{
+  guint i;
+
+  if (!uris)
+    return;
+
+  for (i = 0; uris[i]; ++i)
+    {
+      g_autoptr (GFile) file = NULL;
+      g_autofree char *path = NULL;
+
+      file = g_file_new_for_uri (uris[i]);
+
+      path = g_file_get_path (file);
+      if (path)
+        {
+          char *quoted;
+
+          quoted = g_shell_quote (path);
+          g_free (uris[i]);
+
+          uris[i] = quoted;
+        }
+    }
+}
+
+
+static char *
+terminal_util_concat_uris (GStrv uris,
+                           gsize *length)
+{
+  GString *string;
+  gsize len;
+  guint i;
+
+  len = 0;
+  for (i = 0; uris[i]; ++i)
+    len += strlen (uris[i]) + 1;
+
+  if (length)
+    *length = len;
+
+  string = g_string_sized_new (len + 1);
+  for (i = 0; uris[i]; ++i)
+    {
+      g_string_append (string, uris[i]);
+      g_string_append_c (string, ' ');
+    }
+
+  return g_string_free (string, FALSE);
+}
+
 void
 kgx_tab_accept_drop (KgxTab           *self,
                      GtkSelectionData *selection_data)
 {
   KgxTabPrivate *priv;
+  GdkAtom selection_data_target;
   g_autofree char *text = NULL;
 
   g_return_if_fail (KGX_IS_TAB (self));
 
   priv = kgx_tab_get_instance_private (self);
 
+  selection_data_target = gtk_selection_data_get_target (selection_data);
+
   if (gtk_selection_data_get_length (selection_data) < 0)
     return;
 
-  text = (char *) gtk_selection_data_get_text (selection_data);
+  if (gtk_targets_include_uri (&selection_data_target, 1))
+  {
+    g_auto (GStrv) uris = NULL;
+
+    uris = gtk_selection_data_get_uris (selection_data);
+
+    terminal_util_transform_uris_to_quoted_fuse_paths (uris);
+
+    text = terminal_util_concat_uris (uris, NULL);
+  }
+  else
+    text = (char *) gtk_selection_data_get_text (selection_data);
 
   if (priv->terminal)
     kgx_terminal_accept_paste (KGX_TERMINAL (priv->terminal), text);


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