require 'gtk3'

class SrcWindow < Gtk::Window

  # ========================================================================= #
  # === initialize
  # ========================================================================= #
  def initialize
    super('Source Window')
    @label = Gtk::Label.new('Start the drag action here!')
    add(@label)
    set_default_size(125, 125)
    # ======================================================================= #
    # Set the drag-source:
    # ======================================================================= #
    drag_source_set(Gdk::ModifierType::BUTTON1_MASK |
                    Gdk::ModifierType::BUTTON2_MASK,
                    [['test', Gtk::TargetFlags::SAME_APP, 12345]],
                    Gdk::DragAction::COPY |
                    Gdk::DragAction::MOVE)
    signal_connect('drag-data-get') { |widget, context, selection_data, info, time|
      selection_data.set(Gdk::Selection::TYPE_STRING, 'hoge.txt')
    }
    run
  end

  # ========================================================================= #
  # === run
  # ========================================================================= #
  def run
    move(0, 0)
  end

end

class DropWindow < Gtk::Window

  alias e puts

  # ========================================================================= #
  # === initialize
  # ========================================================================= #
  def initialize
    super('Dest Window')

    @label = Gtk::Label.new('Drop here!')
    add(@label)
    set_default_size(250, 250)
    drag_dest_set(Gtk::DestDefaults::MOTION |
                  Gtk::DestDefaults::HIGHLIGHT,
                  [['test', :same_app, 12345]],
                  Gdk::DragAction::COPY |
                  Gdk::DragAction::MOVE)

    signal_connect(:drag_data_received) { |widget, context, x, y, selection_data, info, time|
      e 'A drop event occurred.'
      @label.set_text('Drop more onto me!!! I am hungry!')
      # pp context.targets
      context.targets.each { |target|
        pp target.name
        if target.name == 'test' ||
           selection_data.type == Gdk::Selection::TYPE_STRING
          puts selection_data.data
        end
      }
    }
    # This is the drop-event.
    signal_connect(:drag_drop) { |widget, context, x, y, time|
      widget.drag_get_data(context, context.targets[0], time)
    }
    run
  end

  # ========================================================================= #
  # === run
  # ========================================================================= #
  def run
    move(125, 125)
  end

end

win1 = SrcWindow.new
win1.move(0, 0)
win2 = DropWindow.new
win2.move(135, 0)

win1.show_all.signal_connect(:destroy) { Gtk.main_quit }
win2.show_all.signal_connect(:destroy) { Gtk.main_quit }

Gtk.main