Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drag and drop files #11

Open
alastairpotts opened this issue Sep 20, 2016 · 19 comments
Open

Drag and drop files #11

alastairpotts opened this issue Sep 20, 2016 · 19 comments

Comments

@alastairpotts
Copy link

Hi Christian,

Again, thanks so much for creating fsearch.

In Search Everything, I could drag files out of the window into a folder or into a download box in my browsers. This was pretty useful (as I only really use fsearch/SE for navigating my files system) for attaching files for emails etc.

No idea how difficult it may be to implement, but it is a minor suggestion.

Kind regards,
Alastair

@cboxdoerfer
Copy link
Owner

Hi,
drang and drop support is already on the road map, you can have a look at it here: https://github.com/cboxdoerfer/fsearch/wiki/Roadmap

@wonder75
Copy link

Hey, thank you for writing fsearch. I don't have much hope, because this issue is so old. This is the nicest search i ever found on linux and i tried many different ones, but missing drang and drop is a show stopper. For example it's impossible to quickly enqueue mp3 files or drag and drop a file into another application of interest.

@cboxdoerfer
Copy link
Owner

@wonder75: Just implemented initial support for drag and drop. Currently only one item can be dragged at a time and I have to figure out how to support whole selections instead.

output

@petric3
Copy link

petric3 commented Jan 19, 2020

Have updated the fsearch from the PPA specified in <>Code but the drag and drop still does not work for me. I use Ubuntu 18.04, tried it also on Mint 19.3, it's no positive result either.

@musictrivianut
Copy link

Know this issue is marked as closed, but I just installed fsearch and the drag and drop function is also not working for me. Ubuntu 18.04 here as well, so maybe it's a thing?

@AtilioA
Copy link
Contributor

AtilioA commented Jul 26, 2020

@musictrivianut I don't think this has been implemented yet.

@msys-morita
Copy link

msys-morita commented Jul 28, 2020

@wonder75: Just implemented initial support for drag and drop. Currently only one item can be dragged at a time and I have to figure out how to support whole selections instead.

I have been using Fsearch for a long time. I am grateful.
We've been waiting for this drag&drop feature for a long time, but with Linuxmint 19.3 it's not yet functional today.

@slrslr
Copy link

slrslr commented Jun 25, 2022

Can this be priority please? @cboxdoerfer @weblate @Vistaus @napcok @ersen0 @veksha ... It seems to be 6 years old and the most wanted feature:
https://github.com/cboxdoerfer/fsearch/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc

@cboxdoerfer
Copy link
Owner

cboxdoerfer commented Jun 25, 2022

@slrslr Like I said this feature is planned for the 0.4 release, which won't be released soon, since I only have limited time to work on FSearch and it's not the most important feature for me at the moment.

0.2 will probably land in August this year, as it's mostly done, 0.3 (which adds the most requested feature (monitoring of file/folder changes)) will be another big release which will take quite some work and I don't think it'll be ready in 2022. So 0.4 with drag-and-drop support most likely won't happen before 2023.

However, if someone else wants to work on that, I'll gladly accept pull requests.

@veksha
Copy link
Contributor

veksha commented Jul 21, 2022

@wonder75: Just implemented initial support for drag and drop. Currently only one item can be dragged at a time and I have to figure out how to support whole selections instead.

Hello, @cboxdoerfer. Where can we get this code? thanks.

@cboxdoerfer
Copy link
Owner

Hello, @cboxdoerfer. Where can we get this code? thanks.

I only have it in a local branch. But unfortunately it's not really useful anymore, because it was relying on the old GtkTreeView and it's not compatible with the new custom listview which is now used instead.

@Nekkowe
Copy link

Nekkowe commented May 19, 2024

Does the custom listview make drag-and-drop impossible, or is this still on the road map?

(I know it's still on the list, but not whether that's up-to-date in itself.)

@oxysoft
Copy link

oxysoft commented Sep 1, 2024

I see that this issue is 8 years old and is still open - also wondering why. This is so crucial, I may actually embed the entire codebase soon in Claude Sonnet 3.5 and see if I can guide it through the implementation, or get it to figure out the mysterious obstacles involved here.

@cboxdoerfer
Copy link
Owner

I see that this issue is 8 years old and is still open - also wondering why. This is so crucial, I may actually embed the entire codebase soon in Claude Sonnet 3.5 and see if I can guide it through the implementation, or get it to figure out the mysterious obstacles involved here.

There are no mysterious obstacles to implement this; it's actually quite straight forward. The only reason this feature hasn't been implemented yet, is because no one bothered to work on it.

Like I said earlier, for me it's not a high priority or crucial in any way, but I'll gladly accept PRs or offer guidance if someone wants to help out.

@porridgewithraisins
Copy link
Contributor

porridgewithraisins commented Sep 30, 2024

@cboxdoerfer I can work on this -- How exactly would it work? IIUIC, we need to make each result in the list view into a drag source? and then add the file URI to that drag source, right?

Edit: How would you deal with it for multiple selections? Since this is possible right now in fsearch?

@cboxdoerfer
Copy link
Owner

@porridgewithraisins,

I can work on this -- How exactly would it work? IIUIC, we need to make each result in the list view into a drag source? and then add the file URI to that drag source, right?

Edit: How would you deal with it for multiple selections? Since this is possible right now in fsearch?

Awesome. Yes, in the drag_data_get signal handler you should be able to simply add the URIs with gtk_selection_data_set_uris, that's basically how we handle multiple selections as well: just add all selected entries.

If you need any help, let me know.

@porridgewithraisins
Copy link
Contributor

porridgewithraisins commented Dec 18, 2024

Hi, I am working on this now.

I have a rough implementation below (so ignore formatting, error handling etc etc). It just adds a drag-data-get handler to the existing bin_drag gesture.

  • For now, I am just copying the concatenated text of the selection for easier debugging.
  • I am not sure how to make this play well with the rubberband selection. I ran into issues implementing this as it's own gesture, so I am simply using the existing bin drag gesture for this. In the case of a single item for example, we don't want to do rubber-band selection and want to start dragging it with the icon right away.
  • If I call drag_begin in the drag-start handler, it seems to cancel the rubber band selection somehow, so I am calling it in the drag-end handler.
  • It is kind of janky.

Am I doing something fundamentally wrong? Should I be setting up a separate gesture for this?

Just registering the list view as a drag source with gtk_drag_source_set() and implementing drag_data_get doesn't work because whatever button mask you give it, it globally captures drags for, and the rubber band selection stops working.

diff --git a/src/fsearch_list_view.c b/src/fsearch_list_view.c
index b295713..b2643fc 100644
--- a/src/fsearch_list_view.c
+++ b/src/fsearch_list_view.c
@@ -862,31 +862,47 @@ on_fsearch_list_view_multi_press_gesture_released(GtkGestureMultiPress *gesture,
     }
 }
 
 static void
 on_fsearch_list_view_bin_drag_gesture_end(GtkGestureDrag *gesture,
                                           gdouble offset_x,
                                           gdouble offset_y,
                                           FsearchListView *view) {
     //  GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
     if (view->bin_drag_mode) {
+        double drag_distance = hypot(view->x_bin_drag_offset, view->y_bin_drag_offset);
+        double coordinate_x = view->x_bin_drag_started + offset_x, coordinate_y = view->y_bin_drag_started + offset_y;
+        printf("Drag details: %d, %d, %d, %d, %f\n", view->x_bin_drag_started, view->x_bin_drag_offset, view->y_bin_drag_started, view->y_bin_drag_offset, drag_distance);
         view->bin_drag_mode = FALSE;
         view->rubberband_state = RUBBERBAND_SELECT_INACTIVE;
         view->x_bin_drag_started = -1;
         view->y_bin_drag_started = -1;
         view->x_bin_drag_offset = -1;
         view->y_bin_drag_offset = -1;
         view->rubberband_start_idx = UNSET_ROW;
         view->rubberband_end_idx = UNSET_ROW;
         view->rubberband_extend = FALSE;
         view->rubberband_modify = FALSE;
+        GtkTargetEntry targets[] = {
+            { "text/plain", 0, 0 },
+            { "text/uri-list", 0, 1 }
+        };
         gtk_widget_queue_draw(GTK_WIDGET(view));
+        gtk_drag_begin_with_coordinates(
+            GTK_WIDGET(view),
+            gtk_target_list_new(targets, G_N_ELEMENTS(targets)),
+            GDK_ACTION_COPY,
+            GDK_BUTTON_PRIMARY,
+            gtk_get_current_event(),
+            coordinate_x,
+            coordinate_y
+        );
     }
 }
 
 static int
 cmp_row_idx(int i1, int i2) {
     g_assert(i1 != UNSET_ROW);
     g_assert(i2 != UNSET_ROW);
 
     if (i1 == i2) {
         return 0;
@@ -1100,20 +1116,45 @@ on_fsearch_list_view_bin_drag_gesture_begin(GtkGestureDrag *gesture,
 
         view->x_bin_drag_started = start_x + get_hscroll_pos(view);
         view->y_bin_drag_started = start_y + get_vscroll_pos(view) - view->header_height;
         view->bin_drag_mode = TRUE;
         view->rubberband_state = RUBBERBAND_SELECT_WAITING;
         fsearch_list_view_get_selection_modifiers(view, &view->rubberband_modify, &view->rubberband_extend);
         gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
     }
 }
 
+static gchar *
+fsearch_list_view_get_selection_text(FsearchListView *view) {
+    GString *selection = g_string_new("");
+    for (int i = 0; i < view->num_rows; i++) {
+        if (view->is_selected_func(i, view->selection_user_data)) {
+            g_string_append_printf(selection, "Row %d\n", i);
+        }
+    }
+    return g_string_free(selection, FALSE);
+}
+
+static void
+on_drag_data_get(GtkWidget *widget,
+                                GdkDragContext *context,
+                                GtkSelectionData *selection_data,
+                                guint info,
+                                guint32 time,
+                                gpointer user_data) {
+    FsearchListView *view = FSEARCH_LIST_VIEW(widget);
+    gchar *selection_text = fsearch_list_view_get_selection_text(view);
+    printf("Selection text: %s\n", selection_text);
+    gtk_selection_data_set_text(selection_data, selection_text, -1);
+    g_free(selection_text);
+}
+
 static void
 on_fsearch_list_view_header_drag_gesture_end(GtkGestureDrag *gesture,
                                              gdouble offset_x,
                                              gdouble offset_y,
                                              FsearchListView *view) {
     // GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
     if (view->col_resize_mode) {
         view->col_resize_mode = FALSE;
         view->drag_column_pos = -1;
     }
@@ -1949,20 +1990,21 @@ fsearch_list_view_init(FsearchListView *view) {
                      view);
     g_signal_connect(view->multi_press_gesture,
                      "released",
                      G_CALLBACK(on_fsearch_list_view_multi_press_gesture_released),
                      view);
 
     view->bin_drag_gesture = gtk_gesture_drag_new(GTK_WIDGET(view));
     g_signal_connect(view->bin_drag_gesture, "drag-begin", G_CALLBACK(on_fsearch_list_view_bin_drag_gesture_begin), view);
     g_signal_connect(view->bin_drag_gesture, "drag-update", G_CALLBACK(on_fsearch_list_view_bin_drag_gesture_update), view);
     g_signal_connect(view->bin_drag_gesture, "drag-end", G_CALLBACK(on_fsearch_list_view_bin_drag_gesture_end), view);
+    g_signal_connect(view, "drag-data-get", G_CALLBACK(on_drag_data_get), view);
 
     view->header_drag_gesture = gtk_gesture_drag_new(GTK_WIDGET(view));
     g_signal_connect(view->header_drag_gesture,
                      "drag-begin",
                      G_CALLBACK(on_fsearch_list_view_header_drag_gesture_begin),
                      view);
     g_signal_connect(view->header_drag_gesture,
                      "drag-update",
                      G_CALLBACK(on_fsearch_list_view_header_drag_gesture_update),
                      view);
@@ -2350,11 +2392,11 @@ fsearch_list_view_column_new(int type,
     col->type = type;
     col->name = g_strdup(name ? name : "");
     col->alignment = alignment;
     col->ellipsize_mode = ellipsize_mode;
     col->width = width;
     col->expand = expand;
     col->visible = visible;
     col->ref_count = 1;
 
     return col;
-}
+}
\ No newline at end of file

@porridgewithraisins
Copy link
Contributor

#592

here's the PR with the URI bit implemented. it still has the issue with the drag and drop not being quite like it is in other apps, can you check what I'm doing wrong there?

Also check if it's ok code architecture wise

@zeating
Copy link

zeating commented Feb 2, 2025

cant drag and drop in arch linux kde

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests