Continuing on the path to fixing GtkEntry, I discovered that I really wasn't happy with the way GtkEntry interacts with GtkEditable. The implementation of things like selections is split about 50-50 between GtkEditable and GtkEntry; but a) GtkEditable can't be fixed because changing that would break widgets deriving from GtkEditable, such as GtkText, GtkSCText, (there are about 5 others in GNOME CVS.) b) GtkEntry has to continue to be a GtkEditable because there is a lot of code out there that uses GtkEditable function calls on GtkEntry. The solution I found was to use the new interfaces functionality in GObject. We turn GtkEditable into an interface, so code such as: gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1) continues to work, but GtkEntry doesn't need to share any code with GtkEditable. The only code that needs to be changed is code such as: GTK_EDITABLE (entry)->current_pos which needs to be changed to; gtk_editable_get_position (GTK_EDITABLE (entry)); The implementation that is currently in GtkEditable moves to a new GtkOldEditable class. Fixing up legacy widgets such as GtkText becomes 99% just mechanical substitution. The GtkEditable interface is then exported by both GtkEntry and GtkOldEditable. It can also, in the future, be exported by objects such as GtkTextView or GtkTextBuffer, which wasn't previously possible; a fairly common request was to have editable widgets that were derived from GtkContainer. A possibly odd thing about GtkEditable is that to conform to the GtkEditable interface, you need to not just export the vtable in the GObject manner, you also need to have a 'editable' argument and ::cut_clipboard, ::copy_clipboard, and ::paste_clipboard action signals. I've appended gtkeditable.[ch] below and also gtkoldeditable.[ch] as an example of a class exporting GtkEditable. I'd appreciate if Tim in particular would take a look at this and see if it matches his imagination for how the interfaces would be used. Notes on GInterface (in addition to the previous comment that interfaces vtables should simply be initialized in the class_init function): - The GInterfaceInfo argument g_type_add_interface_static needs to be const. - There clearly needs to be G_TYPE_INSTANCE_GET_IFACE macro to simplify: #define GTK_EDITABLE_GET_IFACE(obj) \ ((GtkEditableIface *)g_type_interface_peek (((GTypeInstance *)GTK_EDITABLE (obj))->g_class, \ GTK_TYPE_EDITABLE)) Other than that, the interface stuff seemed to work flawlessly. Regards, Owen
Attachment:
gtkeditable.c
Description: Binary data
Attachment:
gtkeditable.h
Description: Binary data
Attachment:
gtkoldeditable.c
Description: Binary data
Attachment:
gtkoldeditable.h
Description: Binary data