Re: another dnd issue



Tim Janik <timj gtk org> writes:

> hi owen,
> 
> in a SAME_APP dnd scenario with two widgets foo and bar, that
> supports target types FOO and BAR and foo being ancestor
> of bar, dragging something of type FOO, 

OK, the thing to realize here is that whether a widget is (or subpart
of a widget) a drop site or not is supposed to be fixed and
independent of the drag target. If I try to drop something on the
trash can on my desktop, if it doesn't accept it, it should reject the
drop, not fall through and land on the desktop.

Roughly results in:
> 
> - data.callback = gtk_drag_dest_motion;
>   gtk_drag_find_widget (, &data);
>   // result: data.found == TRUE, info->widget == foo;

I don't believe this is the case; from gtk_drag_dest_motion():

  if (site->flags & GTK_DEST_DEFAULT_MOTION)
    {
      [...]

      if (action && gtk_drag_dest_find_target (widget, context, NULL))
	{
	  if (!site->have_drag)
	    {
	      site->have_drag = TRUE;
	      if (site->flags & GTK_DEST_DEFAULT_HIGHLIGHT)
		gtk_drag_highlight (widget);
	    }
	  
	  gdk_drag_status (context, action, time);
	}
      else
	{
	  gdk_drag_status (context, 0, time);
	  return TRUE;
	}

So,it returns TRUE if it's a drop target and no match was
found, not false.

Maybe you didn't supply GTK_DRAG_DEFAULT_MOTION and 
your ::drag_motion handler returned a result that depended on
the drag type instead of whether the drop location was
a drop site or not?
> 
> - data.callback = gtk_drag_dest_drop;
p>   gtk_drag_find_widget (, &data);
>   // result: data.found == TRUE, info->widget == bar;
>   // gtk_drag_dest_drop() has already called gtk_drag_finish()
> 
> gtk_drag_dest_motion() works correctly here, foo is able to accept
> the FOO-type target. however gtk_drag_dest_drop() prematurely aborts
> when checking bar prior to foo due to the following code portion in
> gtk_drag_dest_drop():
 
> // widget = bar;
>       if (site->flags & GTK_DEST_DEFAULT_DROP)
>         {
>           GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
> 
>           if (target == GDK_NONE)
>             {
>               gtk_drag_finish (context, FALSE, FALSE, time);
>               return TRUE;
>             }
>           else
>             gtk_drag_get_data (widget, context, target, time);
>         }
> 
>       gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_drop",
>                                context, x, y, time, &retval);
> 
>       return (site->flags & GTK_DEST_DEFAULT_DROP) ? TRUE : retval;
>     }

This code is just like gtk_drag_dest_motion, and is, I believe
correct.

Regards,
                                        Owen



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