GNOME Bugzilla – Bug 627367
Overrides for PyGtk-like Drag and Drop handling
Last modified: 2011-03-01 01:48:33 UTC
In PyGtk nothing more than the following is required to allow a tree view to handle file drops: > view = gtk.TreeView() > > view.drag_dest_set( > gtk.DEST_DEFAULT_ALL, > [('text/uri-list', 0, 0)], > gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE > ) With PyGi the equivalent function seems to be Gtk.drag_dest_set() which yields the following attempt: > view = Gtk.TreeView() > target = Gtk.TargetEntry() > target.target = 'text/uri-list' > target.flags = 0 > target.info = 0 > > Gtk.drag_dest_set( > view, > Gtk.DestDefaults.ALL, > target, > 1, > Gdk.DragAction.COPY | Gdk.DragAction.MOVE > ) However, the assignment of the target to the respective struct member yields the following error: > RuntimeError: unable to set value for field Why does the assignment to "target" fail whereas "flags" and "info" are fine? The GTK docs describe the "targets" parameter of Gtk.drag_dest_set() as follows: > a pointer to an array of GtkTargetEntrys indicating the drop types that > this widget will accept, or NULL. However, there obviously are no pointers in Python. So how would one specify multiple targets here? Specify None upon Gtk.drag_dest_set() and separately modify the target list via Gtk.drag_dest_set_target_list()? This however also fails right at the Gtk.drag_dest_set() call with None as target and 0 as target count: > TypeError: argument 2: Must be Gtk.TargetEntry, not NoneType Simply specifying a list of targets also fails, no matter the content: > TypeError: argument 2: Must be Gtk.TargetEntry, not list Summarized I would like to request to add overrides to Gtk.py to port the PyGtk-like DnD handling. Due to that Gtk.TargetEntry could be dropped altogether again. This would most likely also include moving the various drag functions from module level to Gtk.Widget.
Override makes sense. As for the pointer, usually GI takes care of that by figuring out from the annotated data. We just added a patch to handle input arrays with a length parameter. I didn't really follow it. I think it was nud in #python on GIMPNet who wrote that patch. Not sure. I would ask there. If GTK3 is fixing the API we should wait until it is there. Right now we are only planning on supporting Python3/Gtk+3 for pygi, though I am really trying to keep Python 2 compat, keeping full Gtk+2 support is impossible due to a couple of key API's not being wrapable.
Gtk patch in bug https://bugzilla.gnome.org/show_bug.cgi?id=632095 allow us to set the target by boxing the struct and giving us a constructor. This will allow us to write a useful override here.
Created attachment 174815 [details] app testing DnD
I got the attached test working somewhat. It was a bit more involved than I thought with some patches to Gtk+ including annotation fixes and a new bindable API method. I'll post the link here when I submit it. It also involved a lot of hacking in PyGI core to support guchar arrays as python byte arrays (strings in Python 2). I'll post that soon. One thing that struck me was I couldn't drag and drop to or from external sources. I'm not a DnD expert but shouldn't this code allow me to do just that from firefox or gedit? Note this only binds gtk_tree_view_enable_model_drag_source and gtk_tree_view_enable_model_drag_dest. There are a couple of other DnD apis in TreeView that I didn't take a look at. Also icon view has some and then there are the base DnD APIs. I'll post my code in the morning.
Created attachment 174894 [details] [review] [gi] when encountering guint8 arrays treat them as byte arrays * In Python 2 this means returning a PyString object * In Python 3 we return a PyBytes object
Created attachment 174895 [details] [review] [gi] overrides for treeview Drag and Drop
This requires the latest Gtk HEAD and the patch from bug #635299
Mathias, can you provide me with an example app so I can further fix DnD functionality?
Closing this bug report as no further information has been provided. Please feel free to reopen this bug if you can provide the information asked for. Thanks!