[Lazarus] GTK2: Drag files to other applications (to the file manager, Thunar, Nautilus, etc)

Bernd prof7bit at gmail.com
Sun Aug 19 19:03:20 CEST 2012


Hello,

I am trying to get drag and drop to work but I am not an expert with
all this low level GTK2 api. In the end I want to be able to drag
files from my application to the file manager. My application is
displaying a list of items (that represent files) in the scrollbox (I
have essentially emulated a custom drawn listview for my needs from
scratch) and then the user should be able to drag from the scrollbox
to the file manager or to the desktop and this other application shold
then behave as if files were dropped.

For this purpose I have started a new empty project to play with the
gtk2 API (and maybe later do the same also for windows once I have
worked out how this goes). This is what I have so far (and it is NOT
working):


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    ScrollBox1: TScrollBox;
    procedure FormCreate(Sender: TObject);
    procedure SetupDragDrop;
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation
uses
  glib2, gtk2, gdk2;
{$R *.lfm}

{ TForm1 }

procedure drag_begin(para1: TGtkSignalFuncProc); cdecl;
begin
  writeln('drag_begin');
end;

procedure drag_end(para1: TGtkSignalFuncProc); cdecl;
begin
  writeln('drag_end');
end;

procedure drag_data_get(para1: TGtkSignalFuncProc); cdecl;
begin
  writeln('drag_data_get');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetupDragDrop;
end;

procedure TForm1.SetupDragDrop;
var
  Widget: PGtkWidget;
  TargetEntry: TGtkTargetEntry;
begin
  // is it ok to assume that the handle is the PGtkWidget?

  // none of them seem to work :-(
  //Widget := PGtkWidget(Form1.Handle);
  //Widget := PGtkWidget(Button1.Handle);
  Widget := PGtkWidget(ScrollBox1.Handle);

  with TargetEntry do begin
    target := 'what do i have to put here for dragging files?';
    info := 0; // <-- what is this?
    flags := 0; // <-- maybe the wrong flags?
  end;

  // is this correct?
  gtk_drag_source_set(Widget, GDK_BUTTON1_MASK, @TargetEntry, 1,
GDK_ACTION_COPY);

  // or is the way I connect the signals wrong?
  g_signal_connect(Widget, 'drag-begin', @drag_begin, nil);
  g_signal_connect(Widget, 'drag-end', @drag_end, nil);
  g_signal_connect(Widget, 'drag-data-get', @drag_end, nil);

  // what else is missing? None of my callbacks will ever be called :-(
end;

end.

Its a simple empty application with just a button and a TScrollBox
(ideally I want to have the scrollbox as drag source, some GTK
tutorials use buttons in their examples as drag source so I assume at
least with the button it should work once I get it working at all?

Unfortunately the above code does not seem to do anything at all. None
of the callbacks are called, the cursor does not change when I attempt
to drag, I assume I am missing something esential. It would be nice if
someone could help me modify the above at least to the point where at
least *something* will happen and maybe also answer some of the
questions embedded in the code, maybe then I can figure out the rest
on my own.

Bernd




More information about the Lazarus mailing list