Open daym opened 4 years ago
It also happens with examples/editor.scm
from master.
And the "notify" signal (in glib) is the following:
gobject_signals[NOTIFY] =
g_signal_new (g_intern_static_string ("notify"),
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GObjectClass, notify),
NULL, NULL,
NULL,
G_TYPE_NONE,
1, G_TYPE_PARAM);
(especially note G_TYPE_PARAM
here)
Should be fine; documentation states that G_VALUE_HOLDS_PARAM
would be fine with receiving an item that's derived from GParam, too.
I think GParamObject
is supposed to house a reference-counted GObject
. I suspect what this is trying to prevent is people abusing GValue
(which is usually on the stack) to store a reference to a GObject
--which usually is on the heap. GValue
does not have a destructor, so the reference count of the referred-to-GObject
would go bad in short order.
If that is true then that means this whole mechanism glib is using can't be used for signals or properties, which can likely be GObject
s. At least not if GValue
is used to access those. So I might be wrong, especially since g_signal_emit_valist
is also used by g_signal_emit
which probably doesn't have such limitations.
Is this running a traditional Linux distro or GNU Guix?
It's GNU Guix.
GLIb 2.62.6. Gtk+ 3.24.20.
I use this horrible start script so I don't have to reinstall guile-gi every time I change something:
XDG_DATA_DIRS=/gnu/store/7lcw9yr14gdw8nszj798gfl2h7if7grv-gajim-1.1.3/share:/home/dannym/.guix-profile/share:/run/current-system/profile/share:/home/dannym/.guix-profile/share:/run/current-system/profile/share
GIO_EXTRA_MODULES=/home/dannym/.guix-profile/lib/gio/modules:/run/current-system/profile/lib/gio/modules:/gnu/store/2wa4y9cgw9gm3f507jv3n49rprh2qf4v-dconf-0.34.0/lib/gio/modules
GTK_PATH=/gnu/store/4is168fn75ln9w9nl3xa4gff4fi35z83-libcanberra-0.30/lib/gtk-3.0:/gnu/store/ppm4ymy7gg34iairswb25s347shi843r-gtk+-3.24.20/lib/gtk-3.0
export GIO_EXTRA_MODULES
export XDG_DATA_DIRS
export GTK_PATH
# --search-paths
guix environment -l guix.scm --ad-hoc guile gdk-pixbuf adwaita-icon-theme shared-mime-info -- make
tools/uninstalled-env tools/run-guile "$@"
guile is guile 3.
You are probably experiencing the same problem we experience in
or something similar to it. Basically, it is possible to initialize GLib/GObject twice, which generates a <GObject>
class, that does not spawn from G_TYPE_OBJECT
, among other things, and that's just one possible misconfiguration. As far as I am aware, this is not a bug in Guile-GI, but in your specific GI setup. I once wrote otherwise perfectly fine C code, that results in exactly the same set of errors thanks to some weirdness of Guix/GLib.
There are some things you can do to mitigate them. Loading the GLib/GObject typelib before that of Gtk mitigates one class of errors. Pure environments also help, but they're no silver bullet, sadly. I haven't tried containers yet.
Is there a bug report in Guix about it? That sounds horrible.
(I'm currently reviewing a glib update in Guix--maybe that would fix it, maybe not)
Not as far as I'm aware. My MWE sadly got lost to the hell that is /tmp. There are a number of packages in Guix, that work around this and similar issue(s) by specifically setting GI_TYPELIB_PATH using "=" or "suffix" rather than "prefix". I think, this is because GObject-Introspection is a pseuso-requirement to get conflicting versions of GLib/GObject loaded in the first place.
The warnings in editor.scm disappear when ("GObject" "2.0")
is loaded first. Does this also work for you?
I just tried--yes, this works for me.
Still worrying that this happened in the first place. What is going on?
I believe this happens when calling init!
from Gtk before the GObject stuff is initialized, which happens at some point between require
and the end of typelib->module
. Guile-GI potentially allows a different GObject typelib to be loaded, so we end up with UB in the params.
Not sure if this applies but in case it's useful to you: in node-gtk, we use g_irepository_get_dependencies to load all dependencies before the require
d module is loaded. So our require
function recursively requires dependencies before loading a module itself.
Simplified version:
function giRequire(ns, version) {
if (moduleCache[ns])
return moduleCache[ns]
// ...
loadDependencies(ns, version)
// ...
}
function loadDependencies(ns, version) {
const repo = GI.Repository_get_default()
const dependencies = GI.Repository_get_dependencies.call(repo, ns, version)
dependencies.forEach(dependency => {
const [name, version] = dependency.split('-')
giRequire(name, version)
})
}
For a little more context, I think I've isolated the wall of warnings pretty well with the following:
(use-modules (gi) (gi repository))
(require "GObject" "2.0")
;; Uncomment and warnings vanish
;; (load-by-name "GObject" "Object")
;; Swap comments and see warnings (dis)appear
(typelib->module (current-module) "Gtk" "3.0")
;; (require "Gtk" "3.0")
;; (load-by-name "Gtk" "init")
(init!)
I think in your case giRequire
does the work, that typelib->module
does in ours, only that we're lacking the recursive dependency stuff. We could get that into Scheme by loading the GI repository as you do, or we could write our own wrapper around g_irepository_get_dependencies
. @spk121 WDYT?
Btw. I think your node module duplicates a bit of work. g_irepository_get_dependencies
returns a transitive closure, so there should be no need to have corecursive calls.
When starting up an application with a main window and main loop I get hundreds of warnings like the following:
GLib-GObject-WARNING **: 13:52:00.697: ../glib-2.62.6/gobject/gsignal.c:3381: invalid param spec type 'GParamObject' for value type 'GParam'
I've looked into it a bit. This is
g_signal_emit_valist
verifying that the varargs passed conform to the types of the signal parameters.In this case, the type of the signal parameter is
GParamObject
, but the GValue of the specific vararg passed by the user (in this case that'sg_object_dispatch_properties_changed
, viag_object_notify
, via_gdk_display_manager_add_display
), after being mangled byG_VALUE_COLLECT_INIT
macro, has typeGParam
. This part ofg_signal_emit_valist
is not in the fast path.glib documents:
So the actual GValue value could be derived from
GParam
and it should be fine.My source files do not directly install any custom user objects or signals.
Gtk used is gtk+-3.24.20, glib is glib-2.62.6.
The glib call in question uses
g_param_spec_pool_lookup
to get the pspec, and then usesg_object_notify_by_spec_internal
to notify. The pool got an entry for the pspec byg_object_class_install_property
, the latter of which should always useg_param_spec_object
or similar ways to construct aGParamObject
or similar derived class instance.