After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 603926 - Gtk::Border should be a wrapper around GtkBorder, not a typedef.
Gtk::Border should be a wrapper around GtkBorder, not a typedef.
Status: RESOLVED FIXED
Product: gtkmm
Classification: Bindings
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2009-12-06 21:10 UTC by Krzesimir Nowak
Modified: 2009-12-22 17:07 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test case (2.00 KB, text/x-c++src)
2009-12-06 21:10 UTC, Krzesimir Nowak
  Details
Patch adding Glib::Value specialization and other stuff. (4.88 KB, patch)
2009-12-10 14:50 UTC, Krzesimir Nowak
none Details | Review
Wraps GtkBorder in gtkmm3. (5.90 KB, patch)
2009-12-11 22:02 UTC, Krzesimir Nowak
none Details | Review
Reworked patch adding Glib::Value specialization and other stuff. (4.90 KB, patch)
2009-12-16 17:27 UTC, Krzesimir Nowak
none Details | Review
Updated reworked patch adding Glib::Value specialization and other stuff. (5.82 KB, patch)
2009-12-16 19:32 UTC, Krzesimir Nowak
none Details | Review
Reworked patch wrapping GtkBorder in gtkmm-3. (10.52 KB, patch)
2009-12-22 12:57 UTC, Krzesimir Nowak
none Details | Review

Description Krzesimir Nowak 2009-12-06 21:10:44 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
Comment 1 Murray Cumming 2009-12-10 11:17:21 UTC
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.
Comment 2 Krzesimir Nowak 2009-12-10 14:50:23 UTC
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.
Comment 3 Krzesimir Nowak 2009-12-10 21:19:20 UTC
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&.
Comment 4 Krzesimir Nowak 2009-12-11 22:02:30 UTC
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.
Comment 5 Krzesimir Nowak 2009-12-16 17:27:12 UTC
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.
Comment 6 Krzesimir Nowak 2009-12-16 19:32:37 UTC
Created attachment 149867 [details] [review]
Updated reworked patch adding Glib::Value specialization and other stuff.

Forgot to add border.h to vcprojs.
Comment 7 Murray Cumming 2009-12-17 10:17:47 UTC
> Updated reworked patch adding Glib::Value specialization and other stuff.

Looks good for master. Please commit and push if you have access rights.
Comment 8 Krzesimir Nowak 2009-12-17 21:31:10 UTC
Pushed to master.

What about patch for gtkmm-3maybe?
Comment 9 Murray Cumming 2009-12-21 11:34:00 UTC
Yes, it looks good. Please commit. Sorry for the delay.

But shouldn't it actually be used in more of the API?
Comment 10 Krzesimir Nowak 2009-12-22 12:57:10 UTC
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.
Comment 11 Murray Cumming 2009-12-22 13:32:02 UTC
It looks OK, but please add a comment saying why you had to hand-code the vfunc.
Comment 12 Krzesimir Nowak 2009-12-22 17:07:54 UTC
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.