A GVariant that GTK passes into a JS signal handler (e.g. the parameter of Gio.SimpleAction::activate, or the value of ::change-state) arrives corrupted: reading it emits g_variant_get_string: assertion 'value != NULL' failed and returns garbage. The same variant, read on the JS side before emitting, is fine. In practice this makes it impossible to read the parameter/state variant from an action handler — you have to drive menu actions off action identity + JS state instead.
Minimal repro
import GLib from 'gi:GLib-2.0'
import Gio from 'gi:Gio-2.0'
const action = Gio.SimpleAction.new('t', GLib.VariantType.new('s'))
action.on('activate', (parameter) => { // emitter arg is dropped; parameter is arg 0
console.log('inside handler getString():', parameter.getString()[0])
})
const v = GLib.Variant.newString('hello-world')
console.log('JS-side getString():', v.getString()[0]) // -> "hello-world"
action.activate(v) // synchronously fires the handler
Actual
JS-side getString(): hello-world
(GLib-GObject-CRITICAL): g_boxed_copy: assertion 'G_TYPE_IS_BOXED (boxed_type)' failed
(GLib-CRITICAL): g_variant_get_string: assertion 'value != NULL' failed
inside handler getString(): [object Object] // wrapper points at NULL -> garbage
Expected
Inside the handler, parameter.getString()[0] returns "hello-world" with no criticals.
The g_boxed_copy failure (G_TYPE_IS_BOXED is false) at marshal-in time suggests the incoming GVariant isn't being wrapped/copied as a boxed GVariant, so the JS wrapper ends up pointing at an invalid/NULL value.
Environment
- node-gtk
3.0.0 (commit 9741a54)
- Node.js
v22.22.3, ESM (node --import node-gtk/register)
- GTK
4.22.4, libadwaita 1.9.2, Linux x86_64
A
GVariantthat GTK passes into a JS signal handler (e.g. theparameterofGio.SimpleAction::activate, or the value of::change-state) arrives corrupted: reading it emitsg_variant_get_string: assertion 'value != NULL' failedand returns garbage. The same variant, read on the JS side before emitting, is fine. In practice this makes it impossible to read the parameter/state variant from an action handler — you have to drive menu actions off action identity + JS state instead.Minimal repro
Actual
Expected
Inside the handler,
parameter.getString()[0]returns"hello-world"with no criticals.The
g_boxed_copyfailure (G_TYPE_IS_BOXEDis false) at marshal-in time suggests the incomingGVariantisn't being wrapped/copied as a boxedGVariant, so the JS wrapper ends up pointing at an invalid/NULL value.Environment
3.0.0(commit9741a54)v22.22.3, ESM (node --import node-gtk/register)4.22.4, libadwaita1.9.2, Linux x86_64