Re: DnD semantics sensitive to order of GtkTargetEntry list?



    >> [
    >> ('STRING', 0, 0),
    >> ('text/plain', 0, 0),
    >> ('application/x-rootwin-drop', 0, 1)
    >> ]

    vs. 

    >> [
    >> ('text/plain, 0, 0),
    >> ('STRING', 0, 0),
    >> ('application/x-rootwin-drop', 0, 1)
    >> ]

    Havoc> STRING is the tranditional X text selection type. It's needed for
    Havoc> interoperation with some older clients.

    Havoc> The target list is in order of preference; so you should put the
    Havoc> types you prefer at the front.

Unfortunately, this doesn't explain why I'm having problems, since I'm
dragging from one GtkEntry to another within the same PyGtk2 script.  In
theory, I shouldn't need the STRING (or rootwin) selection type there at
all.  (I can get by without the rootwin element.)  This should have been
sufficient:

    [
    ('text/plain, 0, 0),
    ]

In case I'm barking up the wrong tree with the ordering of my target entry
list, I've appended the complete example.  As listed, it works.  If you
change the order of calls to dnd.add_dest_target from

    dnd.add_dest_target(s1_target)
    dnd.add_dest_target(s2_target)

to

    dnd.add_dest_target(s2_target)
    dnd.add_dest_target(s1_target)

or delete the add_dest_target call with s1_target as a parameter altogether,
it will fail to copy any text from source to dest.  When I run it and it
works, I get console output like so:

    source: <GtkEntry at 0x81fba40> [('STRING', 0, 0), ('text/plain', 0, 0)]
    dest: <GtkEntry at 0x81f8ed0> [('STRING', 0, 0), ('text/plain', 0, 0)]

    ('entry source', 'drag-begin')
    ('entry source', 'drag-motion')..........................
    ('entry dest', 'drag-motion')
    ('entry source', 'drag-leave')
    ('entry dest', 'drag-motion').....
    ('entry dest', 'drag-leave')
    ('entry source', 'drag-data-get')
    ('entry dest', 'drag-data-received')
    ('entry dest', 'drag-drop')
    ('entry source', 'drag-end')

(Each "." represents a repeat of the same signal caught by the same widget.)

When I run it and it fails, I get console output like so:

    source: <GtkEntry at 0x81fba48> [('STRING', 0, 0), ('text/plain', 0, 0)]
    dest: <GtkEntry at 0x81f8e78> [('text/plain', 0, 0), ('STRING', 0, 0)]

    ('entry source', 'drag-begin')
    ('entry source', 'drag-motion').......................
    ('entry dest', 'drag-motion')
    ('entry source', 'drag-leave')
    ('entry dest', 'drag-motion')..........
    ('entry dest', 'drag-leave')
    ('entry source', 'drag-data-get')
    ('entry dest', 'drag-drop')
    ('entry source', 'drag-end')

Note the absense of the destination widget getting a drag-data-received
signal. 

Any suggestions about what I might be doing wrong would be appreciated.  I'm
using Gtk, PyGtk, and friends from CVS, cvs up'd today.

Skip

-------------------------
#!/usr/bin/env python

import sys
import gtk, gobject

#gobject.debug("signals", gtk.TRUE)

class TargetEntry:
    TARGET_STRING = 0
    TARGET_ROOTWIN = 1
    
    def __init__(self, type, info):
        self.type = type
        self.flags = 0
        self.info = info

    def get_target(self):
        return (self.type, self.flags, self.info)

class DragNDrop:

    def __init__(self):
        self.source = None
        self.dest = None
        self.source_targets = []
        self.dest_targets = []
        self.last_signal = ()
        
    def add_source_target(self, target):
        self.source_targets.append(target)

    def add_dest_target(self, target):
        self.dest_targets.append(target)

    def get_dest_targets(self):
        return [x.get_target() for x in self.dest_targets]

    def get_source_targets(self):
        return [x.get_target() for x in self.source_targets]

    def note_signal(self, w, context, *args):
        sig = (w.get_name(), args[-1])
        if sig == self.last_signal:
            sys.stdout.write(".")
            sys.stdout.flush()
        else:
            sys.stdout.write("\n%s" % (sig,))
            sys.stdout.flush()
            self.last_signal = sig
        if args[-1] == "drag-end":
            sys.stdout.write("\n")
            
        return gtk.FALSE

    def establish_notify(self, w):
        for signal in ["drag-begin","drag-data-delete","drag-data-get",
                       "drag-data-received","drag-drop","drag-end",
                       "drag-leave","drag-motion"]:
            w.connect(signal, self.note_signal, signal)

    def add_source(self, source):
        print "source:", source, self.get_source_targets()
        source.drag_source_set(gtk.GDK.BUTTON1_MASK,
                               self.get_source_targets(),
                               (gtk.GDK.ACTION_DEFAULT|
                                gtk.GDK.ACTION_COPY))
        self.establish_notify(source)

    def add_destination(self, dest):
        print "dest:", dest, self.get_dest_targets()
        dest.drag_dest_set(gtk.GTK.DEST_DEFAULT_ALL,
                           self.get_dest_targets(),
                           (gtk.GDK.ACTION_DEFAULT|
                            gtk.GDK.ACTION_COPY))
        self.establish_notify(dest)
        
    def do_action(self):
        return

def main():
    win = gtk.GtkWindow()
    win.connect('destroy', gtk.mainquit)
    table = gtk.GtkTable(2,2, gtk.TRUE)
    win.add(table)

    dnd = DragNDrop()

    s1_target = TargetEntry('STRING', TargetEntry.TARGET_STRING)
    s2_target = TargetEntry("text/plain", TargetEntry.TARGET_STRING)

    dnd.add_source_target(s1_target)
    dnd.add_source_target(s2_target)

    dnd.add_dest_target(s1_target) 
    dnd.add_dest_target(s2_target)
   
    b = gtk.GtkEntry()
    b.set_text("drag me ...")
    b.set_name("entry source")
    dnd.add_source(b)
    table.attach(b, 0, 1, 0, 1)
    
    b = gtk.GtkEntry()
    b.set_text('... here ...')
    b.set_name("entry dest")
    dnd.add_destination(b)
    table.attach(b, 1, 2, 0, 1)

    b = gtk.GtkButton(label='Quit')
    b.connect("clicked", gtk.mainquit)
    b.set_name("quit button")
    table.attach(b, 0, 2, 1, 2)

    win.show_all()
    gtk.mainloop()
    
if __name__ == '__main__':
    main()




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