GNOME Bugzilla – Bug 603926
Gtk::Border should be a wrapper around GtkBorder, not a typedef.
Last modified: 2009-12-22 17:07:54 UTC
Created attachment 149212 [details] Test case GtkBorder is a boxed type - it has its own copy, free and get_type functions, so it should be wrapped by _CLASS_BOXEDTYPE. For now, there is a problem to get style properties of type GtkBorder with C++ API, more elaborate on it is on gtkmm-list [1]. Such change would break API, so I think that it could be targeted for gtkmm-3.0. I'm attaching a test case - style properties are gotten after clicking a button. For Gdk::Color is ok, fails for Gtk::Border. Both C and C++ versions of getting style properties are provided. [1] http://mail.gnome.org/archives/gtkmm-list/2009-December/msg00030.html
From the email: " When trying to get a style property via Gtk::Widget::get_style_property() Glib::Value<> is involved." and " The above fails to Gtk::Border - instead of using Glib::Value_Boxed specialization it uses generic template, which creates new GType and type name when calling Glib::Value<Gtk::Border>::value_type(). In the end Gtk warns about unability to copy between 'GtkBorder' and 'glibmm__CustomBoxed_10_GtkBorder'," A patch for the gtkmm3-maybe branch would be very welcome, please. You might even be able to fix this in the master (gtkmm 2.x) branch by adding a Glib::Value specialization for GtkBorder.
Created attachment 149518 [details] [review] Patch adding Glib::Value specialization and other stuff. Here is the patch for gtkmm 2.x. Patched gtkmm compiles and testcase from my post works now. In short: I moved a typedef to separate header and there I wrote Glib::Value specialization. Also, typedef from entry.hg is removed and inclusion of border.h is added to both entry.hg and range.hg. In the latter I changed get_range_border to use Gtk::Border* instead of GtkBorder* and added conversions for it. I'll look at gtkmm3.
I have a problem with getting patch for gtkmm3-maybe done. Gtk::Border is used explicitly in only two places - Gtk::Entry's (get|set)_inner_border() methods and Gtk::Range's get_range_border vfunc. Problem is with this vfunc - I'll try to describe it as clear as possible. There are several functions: void Gtk::Range::get_range_border_vfunc(Gtk::Border& border) - our virtual method. void Gtk::Range_Class::get_range_border_vfunc_callback(GtkRange* range, GtkBorder* border) - generated internal callback, which calls our virtual method or original C function or nothing. void (*GtkRangeClass::get_range_border)(GtkRange* range, GtkBorder* border) - a pointer to function in GtkRangeClass. Generated internal callback is assigned to it. From the name of vfunc we can deduce it is a getter, that is - it stores some data in passed border parameter. And here is the catch - generated internal callback receives C structs and have to convert them into C++ classes, because it calls our virtual method. When converting GtkBorder into Gtk::Border (which is now a wrapper around C struct, not a typedef), a copy of GtkBorder is passed to our virtual method, so a copy is modified, not GtkBorder passed to generated internal callback. In the end - border passed to generated internal callback is left unchanged. I'll paste a part of a code of generated internal callback (cut here and there): void Range_Class::get_range_border_vfunc_callback(GtkRange* self, GtkBorder* border) { try { // Call the virtual member method, which derived classes might override. obj->get_range_border_vfunc(Glib::wrap(border)); return; } } Ends with compilation error - it wants Gtk::Border&, but has Gtk::Border. Replacing it with: obj->get_range_border_vfunc(Gtk::Border(border)); won't work, because constructor makes a copy. Solution would be wrapping vfunc by hand and in try catch block have something like this: Gtk::Border cxx_border(border); obj->get_range_border_vfunc(cxx_border); border = *(cxx_border.gobj()); return; Is it possible? Or, simpler but less satisfactory, is to make our virtual method taking GtkBorder* instead of Gtk::Border&.
Created attachment 149612 [details] [review] Wraps GtkBorder in gtkmm3. I attached a patch for gtkmm-3maybe. I left virtual method in range.hg untouched, only added a comment with number of this bug.
Created attachment 149858 [details] [review] Reworked patch adding Glib::Value specialization and other stuff. Ping. I reworked a patch to be appliable against master. Also added missing `typedef Gtk::Border CppType' in Glib::Value specialization.
Created attachment 149867 [details] [review] Updated reworked patch adding Glib::Value specialization and other stuff. Forgot to add border.h to vcprojs.
> Updated reworked patch adding Glib::Value specialization and other stuff. Looks good for master. Please commit and push if you have access rights.
Pushed to master. What about patch for gtkmm-3maybe?
Yes, it looks good. Please commit. Sorry for the delay. But shouldn't it actually be used in more of the API?
Created attachment 150228 [details] [review] Reworked patch wrapping GtkBorder in gtkmm-3. (In reply to comment #9) >Yes, it looks good. Please commit. Sorry for the delay. I am not committing this, because I studied gmmproc for a while and decided to wrap range's vfunc by hand to make it use Gtk::Border. So I am attaching a new patch - it applies to tip of gtkmm-3maybe branch and compiles. Since I am using m4 voodoo there, I would like to have it reviewed first before I push this. > But shouldn't it actually be used in more of the API? Nope - only Range and Entry use Border explicitly - most of Border's usage sits in style properties.
It looks OK, but please add a comment saying why you had to hand-code the vfunc.
Commented and pushed to master. While adding a comment I thought it maybe would be nice if prototype of get_range_border were: virtual Gtk::Border Gtk::Range::get_range_border() const; But this can be done some other time, before gtkmm-3 will be released though.