TreeDragSource data_get location

View: New views
9 Messages — Rating Filter:   Alert me  

TreeDragSource data_get location

by Kevin Ryde :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm tinkering with a DRAG_DATA_GET in a custom treemodel implementing
TreeDragSource and though to fill the Gtk2::SelectionData using one of
my sub-objects (or it if possible, and myself if not).

Could the drag_data_get method take a selectiondata object which to
write to, instead of always making a new one?  Per below, umm err tested
only a little bit.



--- GtkTreeDnd.xs 12 Jul 2005 08:39:21 +1000 1.9
+++ GtkTreeDnd.xs 09 Jul 2008 09:04:59 +1000
@@ -136,20 +136,29 @@
  GtkTreeDragSource *drag_source
  GtkTreePath *path
 
+=for apidoc
+Get selection data from a drag source.  The data is written to
+$selection_data, or if $selection_data is not given then to a newly
+created Gtk2::SelectionData object.  On success the return is the
+given or new object, or on failure the return is undef.
+=cut
 ### gboolean gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data)
-GtkSelectionData_copy *
-gtk_tree_drag_source_drag_data_get (drag_source, path)
- GtkTreeDragSource *drag_source
- GtkTreePath *path
+void
+gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data = NULL)
     PREINIT:
- GtkSelectionData selection_data;
-    CODE:
- if (!gtk_tree_drag_source_drag_data_get (drag_source, path,
-                                         &selection_data))
- XSRETURN_UNDEF;
- RETVAL = &selection_data;
-    OUTPUT:
- RETVAL
+ SV *ret = &PL_sv_undef;
+    PPCODE:
+ if (selection_data) {
+ if (gtk_tree_drag_source_drag_data_get (drag_source, path,
+                                        selection_data))
+ ret = ST(2);
+ } else {
+ GtkSelectionData new_selection_data;
+ if (gtk_tree_drag_source_drag_data_get (drag_source, path,
+                                        &new_selection_data))
+ ret = sv_2mortal (newSVGtkSelectionData_copy (&new_selection_data));
+ }
+ PUSHs (ret);
 
 MODULE = Gtk2::TreeDnd PACKAGE = Gtk2::TreeDragDest PREFIX = gtk_tree_drag_dest_
 


_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Kevin Ryde :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Actually, I think it's necessary to clear a newly created
GtkSelectionData struct to zeros too (something I didn't change).

Program below gets a segv from the current code.  I think the "data"
pointer in a GtkSelectionData is a malloced block or NULL.
gtk_selection_data_set() does g_free() on the old before copying and
storing the new.

Dunno if anything special should be initialized in the other fields, I
couldn't find the actual code within gtk that does a normal call out to
a treesource *drag_data_get() interface func.




package MyObject;
use strict;
use warnings;
use Gtk2;

use Glib::Object::Subclass
  Glib::Object::,
  interfaces => [ 'Gtk2::TreeModel',
                  'Gtk2::TreeDragSource' ];

sub DRAG_DATA_GET {
  my ($self, $path, $sel) = @_;
  my $target = Gtk2::Gdk::Atom->intern ('UTF8_STRING');
  my $text = 'hello world';
  $sel->set ($target, 8, $text);
  return 1;
}

package Main;
use strict;
use warnings;

my $obj = MyObject->new;
my $path = Gtk2::TreePath->new_from_indices (0);
my $sel = $obj->drag_data_get ($path);

print $sel,"\n";
exit 0;




--- GtkTreeDnd.xs 12 Jul 2005 08:39:21 +1000 1.9
+++ GtkTreeDnd.xs 13 Jul 2008 20:21:24 +1000
@@ -136,20 +136,32 @@
  GtkTreeDragSource *drag_source
  GtkTreePath *path
 
+=for apidoc
+Get selection data from a drag source.  The data is written to
+$selection_data, or if $selection_data is not given then to a newly
+created Gtk2::SelectionData object.  On success the return is the
+given or new object, or on failure the return is undef.
+=cut
 ### gboolean gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data)
-GtkSelectionData_copy *
-gtk_tree_drag_source_drag_data_get (drag_source, path)
- GtkTreeDragSource *drag_source
- GtkTreePath *path
+void
+gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data = NULL)
     PREINIT:
- GtkSelectionData selection_data;
-    CODE:
- if (!gtk_tree_drag_source_drag_data_get (drag_source, path,
-                                         &selection_data))
- XSRETURN_UNDEF;
- RETVAL = &selection_data;
-    OUTPUT:
- RETVAL
+ SV *ret = &PL_sv_undef;
+    PPCODE:
+ if (selection_data) {
+ if (gtk_tree_drag_source_drag_data_get (drag_source, path,
+                                        selection_data))
+ ret = ST(2);
+ } else {
+ GtkSelectionData new_selection_data;
+ memset (&new_selection_data, '\0', sizeof(new_selection_data));
+ new_selection_data.target
+  = gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW");
+ if (gtk_tree_drag_source_drag_data_get (drag_source, path,
+                                        &new_selection_data))
+ ret = sv_2mortal (newSVGtkSelectionData_copy (&new_selection_data));
+ }
+ PUSHs (ret);
 
 MODULE = Gtk2::TreeDnd PACKAGE = Gtk2::TreeDragDest PREFIX = gtk_tree_drag_dest_
 


_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Torsten Schoenfeld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Kevin Ryde wrote:
> Actually, I think it's necessary to clear a newly created
> GtkSelectionData struct to zeros too (something I didn't change).

Yeah, I think the current code is completely broken.

> Program below gets a segv from the current code.  I think the "data"
> pointer in a GtkSelectionData is a malloced block or NULL.
> gtk_selection_data_set() does g_free() on the old before copying and
> storing the new.
>
> Dunno if anything special should be initialized in the other fields, I
> couldn't find the actual code within gtk that does a normal call out to
> a treesource *drag_data_get() interface func.

I found one instance in gtk/gtkdnd.c, gtk_drag_drop().  It does the following
to initialize the data:

      selection_data.selection = GDK_NONE;
      selection_data.target = pair->target;
      selection_data.data = NULL;
      selection_data.length = -1;

pair->target is a GdkAtom.

It's not obvious to me what the default for the target should be.  You chose
the atom for GTK_TREE_MODEL_ROW -- why?

Is there a way to automatically test this stuff?  Ross once wrote an attempt,
t/GtkTreeView-Dnd.t.  But it's not run by default since he saw no way to
synthesize the necessary events.

--
Bye,
-Torsten
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Kevin Ryde :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Torsten Schoenfeld <kaffeetisch@...> writes:
>
> It's not obvious to me what the default for the target should be.  You chose
> the atom for GTK_TREE_MODEL_ROW -- why?

With an eye on gtk_tree_set_row_drag_data() which looks like it refuses
to act on a selection data of any other target value.  Makes you wonder
if it ought to allow NULL or NONE or whatever at least ... (a matter for
gtk of course).

> I found one instance in gtk/gtkdnd.c, gtk_drag_drop().  It does the following
> to initialize the data:
>
>       selection_data.selection = GDK_NONE;
>       selection_data.target = pair->target;
>       selection_data.data = NULL;
>       selection_data.length = -1;

Maybe that's all there is.  I was expecting to see someone storing
GTK_TREE_MODEL_ROW into target, which is what you get in the callback,
and makes gtk_tree_set_row_drag_data work.  Perhaps that happens
indirectly iterating through the "target list" built from row_targets[]
array in gtktreeview.c.

(I'm pretty fuzzy on the dnd.  At the X level it's pretty awful but
nearly understandable.  By the time gtk half buries it under two levels
of abstraction it's pretty hopeless :-)

> Is there a way to automatically test this stuff?  Ross once wrote an attempt,
> t/GtkTreeView-Dnd.t.  But it's not run by default since he saw no way to
> synthesize the necessary events.

I guess that'd be the way, a bit like hard work though.
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Torsten Schoenfeld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Kevin Ryde wrote:
> Torsten Schoenfeld <kaffeetisch@...> writes:
>> It's not obvious to me what the default for the target should be.  You chose
>> the atom for GTK_TREE_MODEL_ROW -- why?
>
> With an eye on gtk_tree_set_row_drag_data() which looks like it refuses
> to act on a selection data of any other target value.  Makes you wonder
> if it ought to allow NULL or NONE or whatever at least ... (a matter for
> gtk of course).

OK, when you add

        new_selection_data.length = -1;

to the "else" branch, the patch looks good to me.

muppet?

--
Bye,
-Torsten
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Kevin Ryde :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Torsten Schoenfeld <kaffeetisch@...> writes:
>
> new_selection_data.length = -1;

Looks likely.

But I don't know now if I'm at all sure what a constructed SelectionData
ought to look like there.  Maybe forcing GTK_TREE_MODEL_ROW is the wrong
thing.  It could be very unhelpful if you're trying to return a text
string from a row.  Or maybe that doesn't work with GtkTreeView anyway.

In any case it's the first bit asking data_get to operate on a given
SelectionData which was the bit I was interested in.  It has none of
those constructor questions, if you want to take that bit alone, for
now.
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Torsten Schoenfeld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Kevin Ryde wrote:
> I'm tinkering with a DRAG_DATA_GET in a custom treemodel implementing
> TreeDragSource and though to fill the Gtk2::SelectionData using one of
> my sub-objects (or it if possible, and myself if not).
>
> Could the drag_data_get method take a selectiondata object which to
> write to, instead of always making a new one?

After some frustrating hours of reading code and documentation, I'm now
convinced that it doesn't actually make sense to call
Gtk2::TreeDragSouce->drag_data_get without a selection data argument.  The
method is supposed to fill in the selection data *for the target type specified
in the selection data*.  So I think we should apply your patch and actually
deprecate the old calling semantics.

Relatedly: We don't offer any way to construct a Gtk2::SelectionData.  So right
now, you can only meaningfully call things like
Gtk2::TreeDragSouce->drag_data_get when you already have a selection data object
that you perhaps modify and then pass on.  The typical use case seems to be
this: In your drag-motion handler, you need access to the actual selection data
to decide whether a drop is possible.  So you call gtk_drag_get_data which asks
the source for the selection data and then calls your drag-data-received
handler.  There, you have the selection data and can make a decision.

But does this cover all use cases?  Or does it make sense to want to call, say,
Gtk2::TreeDragSouce->drag_data_get to get the selection data for a specific
target type -- without having been passed an existing selection data object from
somewhere?  If so, we'd need to provide Gtk2::SelectionData->new.

It sucks that we don't have tests for all this tree view drag'n'drop stuff.  I
looked into making t/GtkTreeView-Dnd.t non-interactive -- but quickly gave up.
Synthesizing the necessary events seems like hard work.  Can you think of a
walkable way?

--
Bye,
-Torsten
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Torsten Schoenfeld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Torsten Schoenfeld wrote:

> After some frustrating hours of reading code and documentation, I'm now
> convinced that it doesn't actually make sense to call
> Gtk2::TreeDragSouce->drag_data_get without a selection data argument.  The
> method is supposed to fill in the selection data *for the target type specified
> in the selection data*.  So I think we should apply your patch and actually
> deprecate the old calling semantics.

Patch committed.

--
Bye,
-Torsten
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: TreeDragSource data_get location

by Kevin Ryde :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Torsten Schoenfeld <kaffeetisch@...> writes:
>
> Relatedly: We don't offer any way to construct a Gtk2::SelectionData.

I noticed that, but wasn't sure what it should look like.  It sounds
like a good idea though.

> The typical use case seems to be this: In your drag-motion handler,
> you need access to the actual selection data to decide whether a drop
> is possible.

I guess that's what tree drags do: get the data and ask
row_drop_possible how it feels about receiving that.

> Or does it make sense to want to call, say,
> Gtk2::TreeDragSouce->drag_data_get to get the selection data for a specific
> target type -- without having been passed an existing selection data
> object from somewhere?

You could conceive of that for a faked-up drag as a generic data move,
though sounds a little nasty.

As for the type, I couldn't see any of the tree stuff operating on
anything except its same-client-only "row" type.  There's a fixme in
gtkliststore.c since you could helpfully drag and drop text on a model
with a single column of text.  But perhaps gtk itself ought to take the
lead on anything in that area.

> Can you think of a walkable way?

Me?  Nope.  Just from using the TreeView drags it has a feel of "hover
to activate".  If that's so then trying to exercise the whole lot could
mean some very icky timers as well as events.
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
LightInTheBox - Buy quality products at wholesale price