DBus decorators
WARNING
This is an experimental feature.
Decorators that make it possible to generate interface definitions from classes.
Read more about using DBus in GJS on gjs.guide.
Example client usage
ts
import * as dbus from "gjsx/dbus"
@dbus.iface("my.service.interface")
class MyService {
@dbus.method("s", { type: "s", direction: "out" })
declare MyMethod: (param1: string) => void
// proxy.MyMethod is undefined at runtime
// gjs binds a sync and async version with suffixes
declare MyMethodSync: (param1: string) => void
declare MyMethodAsync: (param1: string) => Promise<void>
@dbus.signal("s", "i")
declare MySignal: (param1: string, param2: number) => void
@dbus.property("s", "readwrite")
declare MyProp: string
}
const proxy = await dbus.proxyAsync(MyService, {
name: "my.service.domain",
path: "/my/service/object",
})
proxy.connect("g-signal", (_, _name, signal, params) => {
if (signal === "MySignal") {
const [param1, param2] = params.deepUnpack() as [string, number]
print(param1, param2)
}
})
proxy.connect("g-properties-changed", (_, changed) => {
print(changed.deepUnpack())
})
print(proxy.MyMethodSync("hello"))
print(await proxy.MyMethodAsync("hello"))
proxy.MyProp = "new value"
Example service implementation
It is possible to use these decorators in combination with gobject decorators.
ts
import * as g from "gjsx/gobject"
import * as dbus from "gjsx/dbus"
@g.register({ GTypeName: "MyService" })
@dbus.iface("my.service.interface")
class MyService extends g.Object {
declare private _myProp: string
// will be available after construction with `dbus.serve`
declare dbusObject: dbus.DBusObject
@dbus.method("s", { type: "s", direction: "out" })
MyMethod(param1: string) {
print("MyMethod called")
return param1
}
@g.signal(String, Number)
@dbus.signal("s", "i")
MySignal(param1: string, param2: number) {
print("MySignal", param1, param2)
}
@g.property(String)
@dbus.property("s")
set MyProp(value: string) {
// when using both dbus and gobject decorators
// prop notification has to be done explicitly
if (this.MyProp !== value) {
this._myProp = value
// notify gobject instance
this.notify("my-prop")
// notify dbus
this.dbusObject.emit_property_changed(
"MyProp",
new dbus.Variant("s", value),
)
}
}
get MyProp(): string {
return this._myProp ?? ""
}
}
const service = await dbus.serveAsync(MyService, {
name: "my.service.domain",
path: "/my/service/object",
})
service.connect("my-signal", (_, param1: string, param2: number) => {
print(param1, param2)
})
service.connect("notify::my-prop", ({ MyProp }: MyService) => {
print(MyProp)
})
service.MySignal("hello", 1234)
service.MyProp = "new value"