Skip to content

GValue

GObject.Value is a generic value container, usually only used to implement GObject Properties in projects written with the C programming language. By storing the value type alongside the value, it allows for dynamic type features usually not available to C programmers.

In JavaScript, this behavior is part of the language (i.e. typeof) and GJS will usually convert them automatically, but there are some situations that require using GObject.Value directly.

Basic Usage

Before a newly created GValue can be used, it must be initialized to hold a specific GType:

js
import GObject from 'gi://GObject';


// Create a new GValue
const booleanValue = new GObject.Value();

// Initialize it to hold a boolean
booleanValue.init(GObject.TYPE_BOOLEAN);


// Create a new GValue
const stringValue = new GObject.Value();
stringValue.init(GObject.TYPE_STRING);

// Set and get the value contents
stringValue.set_string('string value');
console.log(stringValue.get_string());


const doubleValue = new GObject.Value();
doubleValue.init(GObject.TYPE_DOUBLE);

if (GObject.type_check_value_holds(doubleValue, GObject.TYPE_DOUBLE))
    console.log('GValue initialized to hold double values');

if (!GObject.type_check_value_holds(doubleValue, GObject.TYPE_STRING))
    console.log('GValue not initialized to hold string values');

The value can then be set directly, or passed to a function that takes it as an argument and sets the value.

js
import GObject from 'gi://GObject';


// Create a new GValue
const booleanValue = new GObject.Value();

// Initialize it to hold a boolean
booleanValue.init(GObject.TYPE_BOOLEAN);


// Create a new GValue
const stringValue = new GObject.Value();
stringValue.init(GObject.TYPE_STRING);

// Set and get the value contents
stringValue.set_string('string value');
console.log(stringValue.get_string());


const doubleValue = new GObject.Value();
doubleValue.init(GObject.TYPE_DOUBLE);

if (GObject.type_check_value_holds(doubleValue, GObject.TYPE_DOUBLE))
    console.log('GValue initialized to hold double values');

if (!GObject.type_check_value_holds(doubleValue, GObject.TYPE_STRING))
    console.log('GValue not initialized to hold string values');

The type of an initialized GObject.Value can be checked by calling GObject.type_check_value_holds():

js
import GObject from 'gi://GObject';


// Create a new GValue
const booleanValue = new GObject.Value();

// Initialize it to hold a boolean
booleanValue.init(GObject.TYPE_BOOLEAN);


// Create a new GValue
const stringValue = new GObject.Value();
stringValue.init(GObject.TYPE_STRING);

// Set and get the value contents
stringValue.set_string('string value');
console.log(stringValue.get_string());


const doubleValue = new GObject.Value();
doubleValue.init(GObject.TYPE_DOUBLE);

if (GObject.type_check_value_holds(doubleValue, GObject.TYPE_DOUBLE))
    console.log('GValue initialized to hold double values');

if (!GObject.type_check_value_holds(doubleValue, GObject.TYPE_STRING))
    console.log('GValue not initialized to hold string values');

GObject Properties

Although you should always use JavaScript property accessors for native values, the GObject.Object.get_property() and GObject.Object.set_property() methods can be used to work with a GObject.Value that will be passed to another function.

js
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';


const action = new Gio.SimpleAction({
    name: 'test',
    enabled: false,
});


// Create a new boolean GValue
const booleanValue = new GObject.Value();
booleanValue.init(GObject.TYPE_BOOLEAN);

// Get the GValue for a GObject property
action.get_property('enabled', booleanValue);
console.log(booleanValue.get_boolean());

// Set a GObject property from a GValue
booleanValue.set_boolean(true);
action.set_property('enabled', booleanValue);

Return Values and Callback Arguments

There are situations where a function may expect a particular value type (e.g. GObject.TYPE_INT64), but GJS can not determine this from the incoming type (e.g. Number). However, in most cases when GObject.Value is returned from functions or passed as callback arguments, they will be automatically unpacked.

Below is a non-functional example of Drag-n-Drop, where the GObject.Value is automatically unpacked for the Gtk.DropTarget::drop signal:

js
import GObject from 'gi://GObject';
import Gdk from 'gi://Gdk?version=4.0';
import Gtk from 'gi://Gtk?version=4.0';


// Create a GObject to pass around
const objectInstance = new GObject.Object();


// A GValue can be used to pass data via Drag-n-Drop
const dragSource = new Gtk.DragSource({
    actions: Gtk.DragAction.COPY,
});

dragSource.connect('prepare', (_dragSource, _x, _y) => {
    const value = new GObject.Value();
    value.init(GObject.Object);
    value.set_object(objectInstance);

    return Gdk.ContentProvider.new_for_value(value);
});


// The Drag-n-Drop target receives the unpacked value
const dropTarget = Gtk.DropTarget.new(GObject.Object,
    Gdk.DragAction.COPY);

dropTarget.connect('drop', (_dropTarget, value, _x, _y) => {
    if (value instanceof GObject.Object)
        console.debug('The GObject.Value was unpacked to a GObject.Object');
});

MIT Licensed | GJS, A GNOME Project