GType
GType is the foundation of the GObject system. Although it is rarely necessary to interact with a GType directly in GJS, there are some situations where you may need to pass a GType as a function argument or in a class definition.
GType Object
Every GObject class has a static $gtype
property that holds a GType object for the given type. This is the proper way to find the GType for an object class or instance. If an instance of the class has been constructed, you could also call GObject.type_from_name()
.
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
const icon = new Gio.ThemedIcon({name: 'dialog-information'});
if (icon.constructor.$gtype === Gio.ThemedIcon.$gtype)
console.log('These values are exactly equivalent');
if (icon.constructor.$gtype === GObject.type_from_name('GThemedIcon'))
console.log('These values are exactly equivalent');
if (icon instanceof Gio.ThemedIcon)
console.log('instance is a GThemedIcon');
if (icon instanceof GObject.Object && icon instanceof Gio.Icon)
console.log('instance is a GObject and GIcon');
const listStore = Gio.ListStore.new(Gio.Icon);
const pspec = GObject.ParamSpec.object(
'gicon',
'GIcon',
'A property holding a GIcon',
GObject.ParamFlags.READWRITE,
Gio.Icon);
To check the GType of a class instance, you can use the instanceof
operator to compare it to a constructor object. This will return true
for any parent type, including interfaces like Gio.Icon
.
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
const icon = new Gio.ThemedIcon({name: 'dialog-information'});
if (icon.constructor.$gtype === Gio.ThemedIcon.$gtype)
console.log('These values are exactly equivalent');
if (icon.constructor.$gtype === GObject.type_from_name('GThemedIcon'))
console.log('These values are exactly equivalent');
if (icon instanceof Gio.ThemedIcon)
console.log('instance is a GThemedIcon');
if (icon instanceof GObject.Object && icon instanceof Gio.Icon)
console.log('instance is a GObject and GIcon');
const listStore = Gio.ListStore.new(Gio.Icon);
const pspec = GObject.ParamSpec.object(
'gicon',
'GIcon',
'A property holding a GIcon',
GObject.ParamFlags.READWRITE,
Gio.Icon);
In many cases, you can pass the constructor object instead of a GType, which is often more convenient and idiomatic in JavaScript.
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
const icon = new Gio.ThemedIcon({name: 'dialog-information'});
if (icon.constructor.$gtype === Gio.ThemedIcon.$gtype)
console.log('These values are exactly equivalent');
if (icon.constructor.$gtype === GObject.type_from_name('GThemedIcon'))
console.log('These values are exactly equivalent');
if (icon instanceof Gio.ThemedIcon)
console.log('instance is a GThemedIcon');
if (icon instanceof GObject.Object && icon instanceof Gio.Icon)
console.log('instance is a GObject and GIcon');
const listStore = Gio.ListStore.new(Gio.Icon);
const pspec = GObject.ParamSpec.object(
'gicon',
'GIcon',
'A property holding a GIcon',
GObject.ParamFlags.READWRITE,
Gio.Icon);
GType Name
The name
property of a GType object gives the GType name as a string (the same name passed to GObject.type_from_name()
). This is the proper way to find the type name for an object class or instance. By default, the GType name of a subclass in GJS will be the JavaScript class name prefixed with Gjs_
:
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=4.0';
/*
* GTypeName
*/
const ExampleSubclass = GObject.registerClass({
}, class ExampleSubclass extends GObject.Object {
});
const objectInstance = new GObject.Object();
const subclassInstance = new ExampleSubclass();
// expected output: 'GObject'
console.log(GObject.Object.$gtype.name);
console.log(objectInstance.constructor.$gtype.name);
// expected output: 'Gjs_MySubclass'
console.log(ExampleSubclass.$gtype.name);
console.log(subclassInstance.constructor.$gtype.name);
/*
* GtkBuilder
*/
const Square = GObject.registerClass({
GTypeName: 'Square',
Template: 'resource:///guide/gjs/Example/ui/square.ui',
}, class Square extends Gtk.Box {
});
const widget = new Square();
// expected output: 'Square'
console.log(Square.$gtype.name);
console.log(widget.constructor.$gtype.name);
In most cases you will not need to specify your own name, however, this may be useful when creating a GtkBuilder template class. To set the GType name, pass it as the value for the GTypeName
property to GObject.registerClass()
.
<interface>
<template class="Square" parent="GtkBox">
<!-- Template Definition -->
</template>
</interface>
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=4.0';
/*
* GTypeName
*/
const ExampleSubclass = GObject.registerClass({
}, class ExampleSubclass extends GObject.Object {
});
const objectInstance = new GObject.Object();
const subclassInstance = new ExampleSubclass();
// expected output: 'GObject'
console.log(GObject.Object.$gtype.name);
console.log(objectInstance.constructor.$gtype.name);
// expected output: 'Gjs_MySubclass'
console.log(ExampleSubclass.$gtype.name);
console.log(subclassInstance.constructor.$gtype.name);
/*
* GtkBuilder
*/
const Square = GObject.registerClass({
GTypeName: 'Square',
Template: 'resource:///guide/gjs/Example/ui/square.ui',
}, class Square extends Gtk.Box {
});
const widget = new Square();
// expected output: 'Square'
console.log(Square.$gtype.name);
console.log(widget.constructor.$gtype.name);
JavaScript Types
WARNING
GObject.TYPE_JSOBJECT
is a boxed type, so it may not be used where a GObject is expected, such as with Gio.ListModel
.
GObject.TYPE_JSOBJECT
is a special GType
in GJS, created so that JavaScript types that inherit from Object
can be used with the GObject framework. This allows you to use them as property types and in signal parameters in your GObject subclasses.
This means that you may use Object
and Array
types, but also more complex types such as Date
and Function
. However, it will not allow you to use JavaScript primitive data types like BigInt
or Symbol
.
import GObject from 'gi://GObject';
const ExampleSubclass = GObject.registerClass({
Properties: {
'example-property': GObject.ParamSpec.jsobject(
'example-property',
'Example Property',
'A property that holds a JavaScript Object',
GObject.ParamFlags.READWRITE
),
},
Signals: {
'example-signal': {
param_types: [GObject.TYPE_JSOBJECT],
},
},
}, class ExampleSubclass extends GObject.Object {
get example_property() {
if (this._example_property === undefined)
this._example_property = {};
return this._example_property;
}
set example_property(obj) {
if (this.example_property === obj)
return;
this._example_property = obj;
this.notify('example-object');
}
emitExampleSignal(obj) {
this.emit('example-signal', obj);
}
});
Type Constants
For convenience, GJS has predefined constants for most built-in types.
Constant | GLib | JavaScript |
---|---|---|
GObject.TYPE_BOOLEAN | gboolean | Boolean |
GObject.TYPE_STRING | gchararray | String |
GObject.TYPE_INT | gint | Number |
GObject.TYPE_UINT | guint | Number |
GObject.TYPE_LONG | glong | Number |
GObject.TYPE_ULONG | gulong | Number |
GObject.TYPE_INT64 | gint64 | Number |
GObject.TYPE_UINT64 | guint64 | Number |
GObject.TYPE_FLOAT | gfloat | Number |
GObject.TYPE_DOUBLE | gdouble | Number |
GObject.TYPE_ENUM | GEnum | Number |
GObject.TYPE_FLAGS | GFlags | Number |
GObject.TYPE_OBJECT | GObject | GObject.Object |
GObject.TYPE_INTERFACE | GInterface | GObject.Interface |
GObject.TYPE_BOXED | GBoxed | |
GObject.TYPE_POINTER | gpointer | nothing |
GObject.TYPE_PARAM | GParam | GObject.ParamSpec |
GObject.TYPE_VARIANT | GVariant | GLib.Variant |
GObject.TYPE_GTYPE | GType | GObject.Type |
GObject.TYPE_JSOBJECT | GBoxed | Object |