Drag and Drop, try 1



MIME-attached is a gzip'd (it's 40K uncompressed, I don't like to fill
people's mailboxes up) patch for my first try at drag and drop support,
for 0.99.10.

Documentation so far:
	- Accepting drops is not very hard. You add a signal handler for
	a "drop_notify_event" to a widget. The signal handler should have
	a prototype like:
		void drop_signal(GtkWidget *widget, GdkEventDrop *what);
	In the GdkEventDrop structure, there are 'data', 'datanumbytes',
	and 'datatype' elements. Only one that needs explaining is
	'datatype', which comes from <gdk/gdktypes.h> and tells you
	whether you have raw data, text, a file, files, MIME data, etc.
	being dropped. You must free the 'data' after you are done with
	it.
	BTW only widgets which have their own ->window element set up
	can do drag and drop.

	- Allowing drags is much more hairy. After creating the widget,
	it has to be realized (i.e. its ->window element created), after
	which you can do
		gtk_widget_set_dnd_data(widget,
			gint dnd_enable /*{FALSE,TRUE} */,
			GdkDropType dnd_type, /* See gdk/gdktypes.h */
			gpointer dnd_data  /* You do not have to keep this
					      around after doing the set,
					      a copy of it is saved with
					      the widget */,
			guint32 dnd_datanumbytes /* Number of bytes in data */,
			GdkCursorType dnd_cursor /* Cursor to change to
						    when dragging this widget */
			);
	The best way to do things IMHO is to set_dnd_data with
	dnd_enable = TRUE, but passing GDK_DNDTYPE_NOTDND,
	NULL, and 0 in for the type/data/datanumbytes. Then you
	can set your signal handler on the widget for the
	"drag_begin_notify_event" and set the correct data as each
	drag occurs.

Bugs/Todo:
	- Drag cursor doesn't get set correctly the first time the
	  widget is dragged.
	- A widget shouldn't have to be realized to set_dnd_data on it.
	- Separate set_dnd_data into set_dnd_data and set_dnd_options
	  functions.
	- Would be nice to add drag & drop to different widgets -
	  i.e. be able to drag a color from the color selector to anywhere
	  in your application.
	- Feedback on the implementation needed. There *have* to be
	  mistakes I made that are yours to correct ;-) Please let me know
	  when you find something.
	- A DRAG_ACCEPTED_NOTIFY_EVENT would be very useful especially
	  for file managers where you need to know the outcome, however
	  OffiX does not provide this in the protocol. A PROPERTY_NOTIFY
	  should be generated when the receiving application receives &
	  deletes the dndselection property through which data is passed,
	  but the receiving application sometimes does a read without
	  delete, and even if it did it wouldn't let you know if the
	  application had actually accepted. (see below)
	- Add Motif drag & drop (a much more robust protocol than OffiX)
	  (see below)
Soapbox:
	The types made available by the OffiX protocol are not going
	to suffice for a lot of the applications needed. I
	would like to suggest always using a GDK_DNDTYPE_MIME, and
	then following the standard HTTP header convention. So for
	dragging an image, you could do something like
Content-type: image/gif

[imagedatahere]
	This will add a little bit of parsing to your apps, but allow
	for a lot more flexibility (you don't need a Content-length:
	header, just subtract strlen(line1) + 1 from total length).

	I'm hoping to get Motif DND protocol docs and implement that.
	KDE uses Offix protocol version 0 as a base and then adds
	DndEnter and DndLeave events, making it Yet Another protocol to
	support.
	(this implementation is vanilla OffiX protocol version 1).

	There are problems with supporting multiple drop protocols, namely
	that you might get drops in three different protocols from another
	gtk application, and think that you had got 3 separate drop
	events.

That's my blathering, now do your thing ;-)
-- Elliot					http://www.redhat.com/
How do you explain school to a higher intelligence?
                -- Elliot, "E.T."

gtk-dnd9.patch.gz



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