I need to know which filenames (file extension) are being dragged before dropping. This is obviously possible with “drag-data-get”. However, a source widget is required for this. I don’t have that, because the drag begins outside the App (from the File Explorer)
Is there a way here ?
I was able to implement this in WinApi and Cocoa, but not in GTK3.
For this purpose, you can use drag-data-received signal that is emitted on the target application (i.e. the one that gets data).
By using the pointer to GtkSelectionData, you can get all the necessary data with functions gtk_selection_data_***, e.g. gtk_selection_data_get_uris for file paths/names.
Yes, this signal provides the necessary informations, but only when the “drop” occurs. Can I trigger this signal manually before the user releases the mouse button? I use openGL, depending on the file suffix, to display different many drop zones. Only then should the user release the mouse button over one of these drop zones.
Yes, this is possible. See the description of the “drag-motion” signal. In short, you call gtk_drag_get_data that triggers the “drag-data-received” signal.
“gtk_drag_get_data” calls the “drag-data-received” signal and i get needed informations, but the drag finishes as expected.
using gtk_drag_finish (context, FALSE, FALSE, time); or gdk_drag_status(context, (GdkDragAction)0, time);
freeze the dragging operation.
need to kill the drag source (file explorer) to continue.
How can I undo “drag-data-received” event after I have analyzed the dragged files from GtkSelectionData*
It seems that something in your code prevents the system working properly. You call
gtk_drag_get_data only once and not every time “drag-motion” is emitted? You call
gdk_drag_status in “drag-data-received”?
Read the description of
gtk_drag_dest_set that gives you a hint which values are to be set if you want to analyze drop data. The second parameter by this function probably should be 0.
The DnD API in GTK3 is sophisticated and powerful but writing event handlers for it can be tricky, especially if you want to implement a special task. Among other things, the interaction of your code and default event handlers can be hard to design. Blocking/freezing can occur, but after some tries you can get the intended effect.
gtk_drag_get_dataonly once and not every time “drag-motion” is emitted?
I need “drag-motion” to permanently transmit the coordinates to openGL for the purpose of hilighting the drop zones when mouse is over. Yes “gtk_drag_get_data” is called only once when “drag-motion” is called first time of each new dragNdrop operation.
Thanks, it works if only “GTK_DEST_DEFAULT_MOTION” is set in “gtk_drag_dest_set”.
The “drop” can now be detected by the signal “drag-drop” instead of “drag-data-received”
Maybe this should be solved more comfortably in GTK. “drag-data-get” signal should be available even if no source widget exists.
That’s not how drag and drop works. The data is retrieved from the source when the drop is complete, as it can happen across process boundaries and the data can be arbitrarily complex—it can be a simple blob of binary data like a UTF-8 encoded string, or it could be megabytes of image data, or a complete serialisation of a complex widget state. It would be incredibly expensive to just call “drag-data-get” at every motion.
In any case, GTK3 won’t ever change its behaviour: it’s API and feature frozen. In GTK4, the negotiation is done based on MIME types and object types, and it uses event controllers that give you access to the drop target through crossing signals. See the drag and drop tutorial and the reference for the drop target and the drag source controllers.
Sure, the data should not be sent with every “drag-motion” signal, but once for each DnD operation via a separate signal, but at least before the drop.
At the moment, however, I don’t see any other way to achieve this in GTK3, hence this workaroud.
so much to do, I have to take my time to transfer everything to GTK4.
By the way, “drag-motion” consumes a lot of resources. The openGL animation starts to stutter as long as the mouse is moved with something dragged. I know that there are no more changes for GTK3 and I just hope that there is no issue in GTK4. For comparison, WinAPI and Cocoa do not cause openGL stutter when mouse is moved with some dragged files.
The openGL programming is identical for all UI toolkits.
It is complicate to say something substantial about your implementation without seeing the code. Here only three points:
(1) check it again whether your code requests the drop data really only once per entering the drop area and not every time the “drag-motion” signal is emitted,
(2) try to avoid GTK_DEST_DEFAULT_MOTION (among other things, unset the drag settings of a destination/target widget, just in case, with
(3) your “drag-motion” event handler should return
TRUE in order to prevent the default handler to be invoked.
If as a response to the “drag-motion” signal, your own event handler only sends coordinates x, y (and nothing more happens), then this cannot be the cause of the high CPU consumption.