I'm currently trying to make an application in gtk+3 for managing files. The goal is to have a file manager that is specialized in my own workflow, since I find Windows File Explorer for example too generic.
GTK of course supports drag and drop functionality, these are the things already set up and working:
- A file listview as drag source, encodes selected files into a file uri list on "drag-get"
- A drop target within the same app right next to the file listview for testing purposes. Prints drag data to std::cout.
- Dropping from the file listview shows the file-uri's in the output window, so this is OK
- Dropping from Windows File Explorer shows the file-uri's in the output windows as well! So OK
But as the title suggests, dragging from my file listview and dropping into Windows File Explorer or any other application for that matter won't work, the mouse cursor keeps showing a 'blocked' symbol.
I also want to support Linux. So I've tried this in a Manjaro vm that runs KDE Plasma. And dropping into the Dolphin file manager works fine.
On Windows, after some searching, I figured it was a security issue. Maybe Windows doesn't allow 'untrusted' apps to drag and drop between other applications. But I made a release build, signed it with a trusted self-signed certificate and put my application it in C:\Program Files. From there I run it, but it still does not work.
This is the code that sets the selection data
#define _BYTE 8
static void
drag_data_get_handl
(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
guint target_type, guint time, gpointer user_data)
{
const auto* unmarshalledUserdata = static_cast<DragAndDrop::GetDragData_Userdata*>(user_data);
const gchar *name = gtk_widget_get_name (widget);
const auto string_data = unmarshalledUserdata == nullptr ? "": unmarshalledUserdata->GetData();
g_print ("%s: drag_data_get_handl\n", name);
g_assert (selection_data != NULL);
g_print (" Sending ");
switch (target_type)
{
/* case TARGET_SOME_OBJECT:
* Serialize the object and send as a string of bytes.
* Pixbufs, (UTF-8) text, and URIs have their own convenience
* setter functions */
case TARGET_STRING:
g_print ("string: %s", string_data.c_str());
gtk_selection_data_set
(
selection_data,
gtk_selection_data_get_target(selection_data),
_BYTE,
(guchar*) string_data.c_str(), //for example file:///C:/Projects/tabspls_build_msvc/TabsPlsMain/TabsPlsMain.sln
static_cast<gint>(string_data.size())
);
break;
default:
/* Default to some a safe target instead of fail. */
g_assert_not_reached ();
}
g_print (".\n");
}
I don't know if this is necessary, but the entire project can be found on github. This links to the revision that I am currently writing about.