GNOME Bugzilla – Bug 775348
gtkmm4: Can't use signal_draw() in Widget
Last modified: 2017-02-15 10:14:22 UTC
Because of the way gtk+4 renders widgets, Gtk::Widget can't wrap the draw signal. See get_render_mode() in gtkwidget.c. For most users this is no problem. Drawing in Gtk::DrawingArea is now made with a draw function instead of signal_draw(). Most other widgets are drawn by C code in gtk+. The exception is custom widgets, usually derived directly from Gtk::Widget. See e.g. the custom widget example in the gtkmm tutorial, https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/custom/custom_widget The template class WidgetWithDraw fixes this problem, unfortunately in a rather complicated way. The good thing with this fix is that it does not require any modification in gtk+. I have suggested such a modification. See gtk+ bug 774778. If it's accepted by the gtk+ developers, the necessary modifications in gtkmm would be only minor. If not, we probably have to do something more complicated in gtkmm, like WidgetWithDraw.
Created attachment 340984 [details] [review] patch: Add template class Gtk::WidgetWithDraw (gtkmm)
Created attachment 340985 [details] [review] patch: Glib::Class: Add register_derived_type() with extra_prefix (glibmm)
Created attachment 340986 [details] [review] patch: Custom widget example: Use Gtk::WidgetWithDraw (gtkmm-documentation)
Created attachment 344162 [details] [review] patch: Add template class Gtk::WidgetCustomDraw (gtkmm) This patch adds WidgetCustomDraw for rendering with signal_draw() and WidgetCustomSnapshot for rendering with snapshot_vfunc(). This could probably be easier done if we could find a general way for users of glibmm and gtkmm to add code to the class init function. Such additions can be useful for instance for adding calls to gtk_widget_class_set_css_name().
Created attachment 344163 [details] [review] patch: custom_widget example: Use Gtk::WidgetCustomDraw and WidgetCustomSnapshot (gtkmm-documentation) The custom widget example draws two similar custom widgets, one using signal_draw(), the other using snapshot_vfunc().
Created attachment 344548 [details] [review] patch: Object construction: Add custom class init and instance init functions (glibmm) Here's a new and better alternative. Make it possible to include additions to the class init function when a named custom type is created. This can be useful not only for WidgetCustomDraw and WidgetCustomSnapshot.
Created attachment 344549 [details] [review] patch: Add Gtk::WidgetCustomDraw and WidgetCustomSnapshot (gtkmm) This version of WidgetCustomDraw and WidgetCustomSnapshot requires the glibmm patch in comment 6.
Created attachment 344550 [details] [review] patch: custom_widget example: Use Gtk::WidgetCustomDraw and WidgetCustomSnapshot (gtkmm-documentation) This version of the custom widget example requires the patches in comments 6 and 7. It shows how to write simple custom class init and instance init functions.
IMO the patches in comments 6-8 are a fairly good fix of the problem with signal_draw() and snapshot_vfunc(). (GtkWidget checks which one is most overridden.) Unless someone can suggest a better fix, or persuade the gtk+ developers to change GtkWidget, I'll soon push those patches, and close the gtk+ bug 774778 with resolution Notabug. The glibmm patch in comment 6 is useful anyway, because it makes it possible for custom widgets to add code to the class-init function and to add an instance-init function.
I have pushed the patches in comments 6-8 with minor improvements of the documentation of the new classes. In the custom_widget example in the tutorial I swapped MyWidget and MyWidget2, meaning that MyWidget now uses snapshot_vfunc() and MyWidget2 uses on_draw().