drag-data-get signal fired twice python gtk3

Viewed 232

I want the source to be the destination too. I implemented the signals below but the drag-data-get signal fires twice. The second time the data variable(in on_drag_data_get) is being populated with the autoselected ListStore item.

class DragSource(Gtk.TreeView):
    def __init__(self):
        Gtk.TreeView.__init__(self)

        model = Gtk.ListStore(str)
        self.set_model(model)
        self.add_item("Item 1")
        self.add_item("Item 2")
        self.add_item("Item 3")

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Backlog", renderer, text=0)
        self.append_column(column)

        self.enable_model_drag_source(
            Gdk.ModifierType.BUTTON1_MASK, [], DRAG_ACTION)
        self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)

        self.connect("drag-data-get", self.on_drag_data_get)
        self.connect("drag-data-received", self.on_drag_data_received)

    def on_drag_data_get(self, widget, drag_context, data, info, time):
        print("fired")
        model, iter = self.get_selection().get_selected()
        text = model.get_value(iter, 0)
        data.set_text(text, -1)

    def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
        text = data.get_text()
        self.add_item(text)
        print("Received text: %s" % text)


    def add_item(self, text):
        self.get_model().append([text])
2 Answers

replace

self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)

with

dnd_list = [Gtk.TargetEntry.new("text/uri-list", 0, 80)]
self.drag_dest_set_target_list(dnd_list)

I had same problem, signal handler will be called twice,

to fix this you have to stop event propagation by returning True from your callbacks, e.g. on_drag_data_get and on_drag_data_received

minimal show case:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

def on_click(*args, **kwargs):
    print('clicked')
    return True  # to prevent event from propagation and stop event from being fired twice

win = Gtk.Window()
win.connect('button-press-event', on_click)
win.show_all()
Gtk.main()

credit to this comment

Related