Re: GTK TreeView control in Windows (DND issue)

I found out what's going wrong here.  I don't quite understand why it's going wrong but i do know where it's going wrong.  Do any GTK+ devs come onto this forum?  If so, they might be able to chip in with some information that will help to get this fixed.  Although I'm a competent programmer I'm not a GTK expert so this will probably need someone with a better understanding of GTK+.  I wouldn't want to fix the problem for Windows, only to screw it up on the other platforms.  Sorry if this gets long-winded (which it will) but let's start by re-capping:-

On 13 Sep 2011, at 11:18, John Emmas wrote:

> What I did notice though is that [..] there's a problem with the context action.  In function 'gtk_drag_button_release_cb()' (gtkdnd.c) there's a section that looks like this:-
> if ((info->context->action != 0) && (info->context->dest_window != NULL))
> {
>        gtk_drag_end (info, event->time);
>        gtk_drag_drop (info, event->time);
> }
> else
> {
>        gtk_drag_cancel (info, GTK_DRAG_RESULT_NO_TARGET, event->time);
> }
> Normally, 'info->context->action' would be whatever action you'd set it to (GDK_ACTION_MOVE / GDK_ACTION_COPY / GDK_ACTION_ASK etc).  But by the time the code reaches that point the action data seems to have gotten lost somewhere.  For a TreeView control (in gtk-win32)  'info->context->action' is always zero.  Consequently, the rest of the process always fails and 'gtk_drag_cancel()' gets called.   This is what's aborting the drop part.

I managed to find out why 'info->context->action' is always zero.  It's initialized to zero when the context first gets created (as are most of its fields) but later, when you drag a source on top of a drop destination, a drag event handler gets called.  The actual function is '_gtk_drag_dest_handle_event()'.  At this stage, the type of event is GDK_DRAG_MOTION.  The event handler sets up a data object and callback function for the DRAG_MOTION event:-

GtkDragFindData data;
data.callback = (event->type == GDK_DRAG_MOTION) ? gtk_drag_dest_motion : gtk_drag_dest_drop;

Very shortly afterwards the motion callback function gets invoked.  It's this function which sets 'context->action' to whatever is appropriate for source and destination, as well as doing various other important things to prepare for dropping.  However...  for a TreeView control, the gtk_drag_dest_motion() callback never gets called.  I haven't been able to test this in Linux (i.e. to check that it should be getting called) but I assume it should because there's no way the rest of the process could work if it doesn't.

So why doesn't it get called in gtk-win32...?  A couple of lines after the above code, we see this call:-

gtk_drag_find_widget (toplevel, &data);

and it's that function which invokes the callback.  Inside that function, the relevant code looks like this:-

if (!data->found && g_object_get_data (G_OBJECT (widget), "gtk-drag-dest"))
      data->found = data->callback (widget, data->context,
            data->x - x_offset - allocation_to_window_x,
            data->y - y_offset - allocation_to_window_y, data->time);

Initially of course, 'data->found' is zero - so as long as 'g_object_get_data()' returns successfully, the callback function should get invoked.  Where it all goes wrong is that 'g_object_get_data() doesn't return successfully.  It returns NULL.  Here's the function that's failing:-

g_object_get_data (GObject *object, const gchar *key)
GQuark quark;

      g_return_Val_if_fail (G_IS_OBJECT (object), NULL);
      g_return_Val_if_fail (key != NULL, NULL);

      quark = g_quark_try_string (key);

      return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;

In gtk-win32, when 'key' == "gtk-drag-dest" (and the drag destination is a TreeView) 'g_datalist_id_get_data()' returns NULL.  This is where my understanding of GTK comes to a halt.  Obviously there's some kind of data list which is supposed to contain some data relating to the quark.  The quark (apparently) has a valid value but the data isn't there.

Presumably, datalists are generic containers which contain different kinds of data in different circumstances.  So I'd need to liaise with someone who'd know what kind of data the list should contain.  Hopefully, somewhone who might be able to make a guess at why it isn't there.  Anyone know how to proceed from here...?


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]