Location of dropped files

Im successfully able to implement drag and drop out of my app and into a file manager. But what I’d like to know is the destination paths. To clarify further, if i drag file(s), for example /tmp/foo.txt out of my app and into a file manager at /foo/bar/bazz/, I would like to know where the paths were placed. Is this not possible? (i am on gtk3)

ok, after a lot of searching, i discovered XDS! It’s confusing that this exists and that it’s so complex just to do such a simple thing as get the dropped destination of the file. Is this the solution for my problem? It’s not clear to me how this API works. I’ve got something like this, but i never get the file path of where the file is dropped, only the file name which I already knew…

enum {                                                    
  DRAG_INFO_TEXT,                                         
  DRAG_INFO_XDS,                                          
};                                                        
                                                          
#define MAX_URI_LEN 4096                                  
#define XDS_ATOM gdk_atom_intern("XdndDirectSave0", FALSE)
#define TEXT_ATOM gdk_atom_intern("text/plain", FALSE)    
                                                          
static GtkTargetEntry droppableTypes[] = {                
  { (char*) "text/uri-list", 0, 0 },                      
  { (char*) "XdndDirectSave0", 0, DRAG_INFO_XDS }         
};

gtk_drag_source_set(                                     
  window,                                               
  (GdkModifierType)(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK),
  droppableTypes,                                        
  G_N_ELEMENTS(droppableTypes),                          
  GDK_ACTION_COPY                                        
);                                                       

g_signal_connect(
  G_OBJECT(widget), 
  "drag-begin", 
  G_CALLBACK(+[](GtkWidget *widget, GdkDragContext *context, gpointer arg) {
    auto *w = static_cast<Window*>(arg);
    std::string tmpFile(std::to_string(rand64() + ".download"); 

    gdk_property_change(                                                
      GDK_WINDOW(gtk_widget_get_window(w->window)),                     
      XDS_ATOM,                                                         
      TEXT_ATOM,                                                        
      8,                                                                
      GDK_PROP_MODE_REPLACE,                                            
      (guchar*) tmpFile.c_str(),                                        
      tmpFile.size()                                                    
    );                                                                  
  }),
  this
);

g_signal_connect(                       
  G_OBJECT(widget),                    
  "drag-data-get",                      
  G_CALLBACK(+[](                       
    GtkWidget *widget,                      
    GdkDragContext *context,            
    GtkSelectionData *data,             
    guint info,                         
    guint time,                         
    gpointer arg)                       
  {                                     
    auto *w = static_cast<Window*>(arg);
    gchar* value = NULL;
    gint len;

    gdk_property_get(                              
      GDK_WINDOW(gtk_widget_get_window(w->window)),
      XDS_ATOM,                                    
      TEXT_ATOM,                                   
      0,                                           
      MAX_URI_LEN,                                 
      FALSE,                                       
      NULL,                                        
      NULL,                                        
      &len,                                        
      (unsigned char **) &value                     
    );                                             
    // after the drop, value prints just the filename, not the path. not very useful
  }),
  this
);

Is X11 specific and I’m not sure many things ever implemented it

Two things:

  1. That’s actually quite a complex thing your trying to do
  2. It’s X11

what is the idiomatic GTK solution for getting the path at the dropped location? I found this diagram (I noticed there are some typos in it). Are the destination paths added to the context object in the drag-data-received phase on the destination side? I guess they would be added by whoever implemented the desktop dnd or the file manager dnd code?

I noticed the GdkDrop api, looks like @ebassi worked on it. Does this api provide a way to get the location of the dropped files?

I did not work on the GdkDrop API, and tagging random people just because they appear in the Git history is considered rude.

There is not protocol that communicates back to the source of the operation what the destination has done with it, as far as I know.

Your username and avatar show up next to lines in git blame. Issuing a lesson in etiquette based on this seems detrimental to community building. Anyway, thanks for the heads up.

The line you’re referring to is a documentation commit, not anything to do with the API.

If you are concerned about community building, the best way to do that would be to consider what help you can bring to the community and how you can help others; do not assume any other community members are here on-call just to answer anyone’s questions, even if they have done so in the past.

I’m assuming that someone who wrote and committed the documentation might be familiar enough with the mater and be interested in discussing, especially with potential contributors or maintainers. wfiw, i would definitely classify documentation as “work”. All communities work a little differently, that’s fine.

I can understand making that assumption, but unfortunately that is not a safe assumption as it is not always the case.

Anyway, to try to help provide some clarification for your questions, for sandboxed apps in Wayland I don’t expect there is any reasonable way to do this as the location of a dropped file outside a sandbox is not meaningful to an app inside a sandbox. The idiomatic way to do it in X11 would be to implement XDS yourself.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.