This weekend, I was working on making some improvements to #GtkEntry, and was forceably reminded how lousy the selection handling interfaces in GTK+ are. The main problems are: - All notification is done by emitting signals on some #GtkWidget, which is not necessarily natural. Not only do we need a #GtkWidget, but the #GtkWidget has to have a window. This does not mix well with creating editable canvas items, etc. - The simple operation of supplying or receiving text becomes horribly complex because we have to try targets, fall back to others, convert the results into the appropriate form, etc. - Timestamps have to be provided in all the interfaces, but you don't always have a good timestamp to use, and mixing real timestamps with GDK_CURRENT_TIME can produce odd bugs if not done carefully. - Text cut to the clipboard disappears with the cutting widget. - I'm about the only person who can figure out how it all works So, I came up with a new, improved interface to the selection mechanism, #GtkClipboard. You can see the API docs for this interface at: http://people.redhat.com/tmp/rdp-2.0/gtk/gtk-storing-data-on-clipboards.html I've attached the header file, implementation and diffs to other parts of GTK+ below. I've also added various functions for converting text from the standard X property types to and from UTF-8 to GDK, and extended the GtkSelection interface a bit. The highlights of #GtkClipboard are: - A #GtkClipboard represents a single selection (CLIPBOARD, PRIMARY, etc.) - The contents of the selection can be provided either as just the data (gtk_clipboard_set_text()), or as callbacks. The callbacks can combined with with either user data or an owner object -- two variants taking callbacks are provided, that are convenient in different circumstances, as described in the HTML docs. I don't like having both, but don't see an way to get the same level of convenience. - The contents of the clipboard can be requested either as text or as generic data. Requests can either be a) delayed with a callback or b) with a recursive main loop. - Timestamps are omitted from the interface, and instead GTK+ figures out good timestamps for itself. These are determined as: - the time from the event currently being dispatched, if any. - Otherwise, the current server time. But, to avoid the problem where a request with a real timestamp follows a request from the same process with a timestamp of GDK_CURRENT_TIME, and is reject because it is out of date, the timestamps are forced to be non-descending from the single process. I can't come up with any non-artificial situations where the timestamps generated this way are worse than having the client pass the timestamps in, and they will frequently be better. (more than half the time, people were just using GDK_CURRENT_TIME anyways.) Plus, it simpifies the interfaces. Suggestions are invited. I think if you look at how much shorter gtktextbuffer.c gets, you will inevitably agree that this is an improvement, but it may be possible to do even better. Regards, Owen
Attachment:
gtkclipboard.h
Description: Binary data
Attachment:
gtkclipboard.c
Description: Binary data
Attachment:
diff
Description: Binary data