Subclassing GObject.Object
Astal provides decorator functions that make it easy to subclass gobjects.
Example Usage
import GObject, { register, property } from "astal/gobject"
@register()
class MyObj extends GObject.Object {
@property(String)
declare myProp: string
@signal(String, Number)
declare mySignal: (a: string, b: number) => void
}
Property decorator
type PropertyDeclaration =
| GObject.ParamSpec
| { $gtype: GObject.GType }
function property(declaration: PropertyDeclaration)
The property
decorator can take any class that has a registered GType. This includes the globally available String
, Number
, Boolean
and Object
javascript constructors. They are mapped to their relative GObject.ParamSpec
.
The property decorator can be applied in the following ways:
- On a property declaration
@register()
class MyObj extends GObject.Object {
@property(String)
declare myProp: string
}
This will create a getter and setter for the property and will also emit the notify signal when the value is set to a new value.
INFO
The declare
keyword is required so that the property declaration is not transpiled into JavaScript, otherwise the initial value of the property would be undefined
.
WARNING
The value is checked by reference, this is important if your property is an object type.
const dict = obj.prop
dict["key"] = 0
obj.prop = dict // This will not emit notify::prop
obj.prop = { ...dict } // This will emit notify::prop
If you want to set a custom default value, do so in the constructor of your class.
@register()
class MyObj extends GObject.Object {
@property(String)
declare myProp: string
constructor() {
super({ myProp: "default-value" })
}
}
- On a getter
@register()
class MyObj extends GObject.Object {
@property(String)
get myProp () {
return "value"
}
}
This will create a read-only property.
- On a getter and setter
@register()
class MyObj extends GObject.Object {
declare private _prop: string
@property(String)
get myProp () {
return "value"
}
set myProp (v: string) {
if (v !== this._prop) {
this._prop = v
this.notify("my-prop")
}
}
}
This will create a read-write property.
INFO
When defining getter/setters for the property, notify signal emission has to be done explicitly.
Signal decorator
function signal(...params: Array<{ $gtype: GObject.GType })
function signal(declaration?: SignalDeclaration) // Object you would pass to GObject.registerClass
You can apply the signal decorator to either a property declaration or a method.
@register()
class MyObj extends GObject.Object {
@signal(String, String)
declare mySig: (a: String, b: String) => void
@signal(String, String)
mySig(a: string, b: string) {
// default signal handler
}
}
You can emit the signal by calling the signal method or using emit
.
const obj = new MyObj()
obj.connect("my-sig", (obj, a: string, b: string) => {})
obj.mySig("a", "b")
obj.emit("my-sig", "a", "b")
Register decorator
Every GObject subclass has to be registered. You can pass the same options to this decorator as you would to GObject.registerClass
@register({ GTypeName: "MyObj" })
class MyObj extends GObject.Object {
}