简体   繁体   中英

Is it possible to drag data from a gtk app to other application under Windows? Like File Explorer?

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.

I've been looking through the gtk sources and docs myself and I think I found the answer.

For starters, the docs state that the OLE2 drag and drop protocol is not implemented. This would be required to drag and drop between applications on Windows.

So why then can my gtk app receive files but not send them under Windows? The docs state that the WM_DROPFILES protocol is supported, I can confirm this protocol is chosen by calling gdk_drag_context_get_protocol on the context in my drop receive callback.

So if I would like to support this in my own app, I would have to use WM_DROPFILES for sending data (I don't think this can be done throught the gtk library). Or I would need to implement my own OLE2 drag and drop separately from gtk.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM