Closed clayrisser closed 6 months ago
After doing more research and running the examples, it seems that virtual functions only work directly on a Gtk.Widget
. They are not working for other gtk widgets (for example I'm not able to override virtual functions for a Gtk.Button
).
@romgrk ???
While I was able to get the gtk-4-custom-widget.js
example to work on linux (again only with Gtk.Widget
), it doesn't work on OSX.
It gives a bus error
on OSX.
I think it has something to do with the fact that most of the new gtk 4 widgets are using layouts, so the measure
virtual function is actually in the layout. I tried testing this by using a FixedWidget and changing it's layout to use a custom FixedLayout and then overrode the measure virtual function in FixedLayout, but that didn't seem to work.
Do you have an example?
And did you call gi.registerClass(CustomButton)
? It's required to create a new GObject, which is how virtual functions are able to work. There isn't a way to avoid the runtime call, because V8 doesn't provide a hook or callback for us to know when a new class is derived from an existing GObject class.
Relevant doc section: https://github.com/romgrk/node-gtk/blob/master/doc/index.md#inheritance
I did that though. I"m setting
static GTypeName = 'FixedLayout'
and adding
gi.registerClass(FixedLayout)
I'm trying to set the measure virtual function but it won't work.
Do you have a code example that doesn't work? Is gtk-4-custom-widget.js
representative of what you're trying to do?
Yes, here is an example below. I'm using gi.registerClass()
. The measure
virtual function should be overloaded in the CustomFixedLayout
(which should log "measure"), but when you run it, the measure function is not overloaded.
/*
* test-gtk-4.js
*/
const gi = require("../lib");
const GLib = gi.require("GLib", "2.0");
const Gtk = gi.require("Gtk", "4.0");
Gtk.init();
class CustomFixedLayout extends Gtk.FixedLayout {
static GTypeName = "CustomFixedLayout";
measure(orientation, forSize) {
console.log("measure");
return super.measure(orientation, forSize);
}
}
class CustomFixed extends Gtk.Fixed {
static GTypeName = "CustomFixed";
constructor() {
super();
this.setLayoutManager(new CustomFixedLayout());
}
}
gi.registerClass(CustomFixedLayout);
gi.registerClass(CustomFixed);
/* Setup & start the application */
const loop = GLib.MainLoop.new(null, false);
const app = new Gtk.Application("com.github.romgrk.node-gtk.demo", 0);
app.on("activate", onActivate);
const status = app.run();
function onActivate() {
const window = new Gtk.ApplicationWindow(app);
window.on("close-request", onQuit);
const cssProvider = new Gtk.CssProvider();
const customFixedCss = `
#custom-fixed {
background-color: red;
}
`;
const customFixed = new CustomFixed();
customFixed.setName("custom-fixed");
cssProvider.loadFromData(customFixedCss, customFixedCss.length);
customFixed
.getStyleContext()
.addProvider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
window.setChild(customFixed);
window.present();
gi.startLoop();
loop.run();
}
function onQuit() {
loop.quit();
app.quit();
return false;
}
The vfunc issue should be dealt with in #355. Your code example still doesn't run, but it's missing a parameter, widget
:
measure(widget, orientation, forSize) {
console.log("measure");
return super.measure(widget, orientation, forSize);
}
Note that this will cause a stack overflow, because for some reason super.measure
calls measure
. To be honest vfuncs is the last thing I implemented and one aspect of GIR I don't understand very well, so I don't know what's going on behind the scenes. If you absolutely need access to the virtual measure
implemented by GtkFixedLayout
, I could try to allocate some time soon to make things work.
I will need it to work because I'm adding Flex layout support with yoga, and I need to use measure to make it work.
Any eta for the #355 PR?
How to override vfuncs?