For the aspiring gtkmm 4 application developer, is Inkscape a good reference for CMake goo? Or is there another, more 'modern' example?
perhaps cc @bugaevc
For the aspiring gtkmm 4 application developer, is Inkscape a good reference for CMake goo? Or is there another, more 'modern' example?
perhaps cc @bugaevc
@akaster hey. So back when I was building a gtkmm project with CMake, I used something much simpler, just looking up gtkmm through pkg_check_modules and linking to the imported target. But, I wasn't trying to do all of this "build a version from source if not new enough". Which I understand the appeal of, and it's nice when Meson does that for subprojects, without you having to write tons of logic on your side to get it.
But also, I no longer have to use gtkmm
peel is now public, and it comes with some CMake integration (which I've even written the docs for: https://bugaevc.pages.gitlab.gnome.org/peel/using-peel-with-cmake.html). Which is imperfect by the way, and improvements welcome.
@bugaevc following up on this old post, why does peel not call object constructors?
That feels ... c++-hostile, at the very least. I saw in the README/docs and some issues that the goal of peel is to be as faithful to GTK as possible, but ... maybe I'm missing something.
Is it truly not possible to
```
auto* p = g_object_new(...)
new (p) MyClass; // call c++-generated constructor
static_cast<MyClass*>(p)->init();
```
?
The documentation I saw that suggested doing
```
void
MyClass::init()
{
new (&m_vec) std::vector<int>{};
...
}
```
feels like a bridge too far in being C-like.
I would expect a C++ library to either call my class's constructors, or enforce that all 'classes' are trivially constructible, to avoid foot-guns/awkward situations like that.
@akaster hey, so, the overall reason is that GObject construction and C++ construction work differently enough that it's not worth to try and make them work in tandem. I have thought about this a lot, because it would be really nice if it just worked (like it does with destruction), but ultimately decided that's not worth it. That is true of many many "core" aspects of peel (like this one): the design has been thought over excessively, even though you might not immediately like the result.
If you want some more details: consider that the C++ constructor expects to initialize all the memory the instance occupies, including that of the parent class subobject, whereas in reality the parent class data will be initialized by the actual parent type's initializer, and C++ has to keep its hands off that memory. Also that GTypeInstance initialization happens in turns, from the root type (GObject) down to the concrete type, and at each turn the object's dynamic type is set to that type being initialized — so e.g. if a vfunc gets called at this point, it'd be that class'es vfunc implementation (C++ also does a similar thing with its virtual classes); and GTK makes serious use of this (Gtk.Widget.init_template() works with the current type of the object) — you can't really make this work if the initialization is driven from the C++ side.
We also cannot require that the class is trivially constructible, exactly because it might not be, you may want to do some initialization. Using e.g. a RefPtr (which defaults to nullptr, and doesn't have to be explicitly initialized in fields of GObject) would instantly kill trivial constructibility too; but this is something we want to encourage, and so make simple, not prohibitively complicated. Also we delete the default constructor for classes, so people don't accidentally try to stack allocate them; trivial constructibility requirement wouldn't work with that either.
In my experience using peel, it ends up not actually being much trouble, especially if you mostly use peel's own types which come with a promise that zero-initialization is fine. For the occasional STL type, yes, you have to call the constructor explicitly. This became even more true once I stopped using std::string in favor of peel::String; now it's mostly vectors that remain.
So are/were you considering peel for some project? What are you trying to do?
@bugaevc @bugaevc Thanks for the details! The intialization order of parent classes definitely makes it hard to do what c++ wants to do...
> So are/were you considering peel for some project? What are you trying to do?
I'm reviving my efforts to create a GTK4 UI for Ladybird. Last summer/fall I had scaffolding in place, but now I'm actually implementing the UI itself.
(Side note on that: the adoption of librsvg by gtk and the move of librsvg from C to rust caused problems for vcpkg that have taken a lot more effort than I hoped to resolve... and I still need a final review from vcpkg on that)
I was looking at the 'gotchas' in the peel documentation and ran across the constructor issue, and the 'weak ptr in lambda' issue and found them particularly unfortunate. I'm unsure how to create a 'proper GTK app' in C++, but looking at the Qt and AppKit UIs we already have, meshing our C++ ViewImplementation and C++-like UI concepts feels like there would be a lot of friction. Especially if we try to keep the UI components 'feeling' like Ladybird/Serenity C++. Adopting an entirely different style for one component is a bit of a non-goal as it would require contributors to gain extra knowledge from... somewhere in order to hack on the UI layer.
@akaster so my impression of vcpkg was that it's a mess that's best avoided... but as for librsvg, the news is https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/9333
Generally it would make sense to expect contributors to an application to be fluent in the framework the application is written in (be it GTK with peel, AppKit, Win32, Android, whatever); in other words to have experience writing proper idiomatic applications using that framework. And they would have to have learned that from some resources external to the project indeed.
But yeah, I can see your point & why peel could be problematic for that use case of yours. If you decide that gtkmm (or plain C, or whatever) fits better, I could help you with that too.