GNOME Bugzilla – Bug 756072
TreeView Drag and Drop broken when using TreeDragSource/TreeDragDest: SelectionData not passed back up signal chain
Last modified: 2018-01-10 20:51:28 UTC
I've been trying to get drag/drop with a TreeView working by only using the 'high-level' API, but after playing with this for awhile and stepping through it using GDB it appears that the SelectionData object that the TreeModel is receiving is different from the object that the TreeView is processing, so when I set a URI in the SelectionData it isn't passed on, and thus the drag_data_received function never gets called. I've created a sample program that demonstrates this behavior, and contains some (currently disabled) code that is useful in showing what's happening. https://gist.github.com/virtuald/c03602dc7218ca0ecd3c
I've added a vala example (courtesy of @sjohannes) which is mostly the same as the python version, except that it actually works. Definitely seems to be a python-specific bindings problem.
Appears to be a duplicate of https://bugzilla.gnome.org/show_bug.cgi?id=737587 ?
After some contemplatation and a bit more work than I expected, I have a hacked up version of the original code that works: https://gist.github.com/virtuald/c03602dc7218ca0ecd3c#file-treetest_hack-py Basically, this hacky solution uses ctypes + gobject introspection to find the correct drag_data_get vfunction in the class, and put our own ctypes callback function that can access the selection data directly instead of using the one that pygobject would install (that won't work correctly). When it gets called, it uses the private qdata to get a pointer to the python wrapper, and calls the python object's drag_data_get vfunc with a wrapper around the selection data that allows the python function to directly modify the selection data. This allows the python program to utilize the high level DnD API. Yes, this workaround is probably a bad idea. However, rewriting hundreds of lines of tricky DnD code seems worse to me. I would love feedback on this approach, or better ways to go about this that aren't quite as hacky. I'm also open to helping figure out how to integrate it into PyGObject, or to help find/test a proper fix. However, I suspect a proper fix will be quite problematic, because of the reasons listed in 737587.
Ok, I've pushed an improved version of the hacky version now that features different forms of hacking -- but I think it's more likely to be stable: - Converts all callback arguments to wrapped python objects via GObject.GValue - Copies all of the selection data back to the callback's caller - Don't actually have to rename the virtual function In particular, realizing that GValue can be used to convert raw pointers to arbitrary objects in python was a great find. :)
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pygobject/issues/104.