A Service is an instance of a GObject.Object that emits signals when its state changes. Widgets can connect to them and execute a callback function on their signals which are usually functions that updates the widget's properties.
Widget.Label({
// the signal is 'changed' if not specified
// [Service, callback, signal = 'changed']
setup: (self) =>
self.hook(someService, function (self, ...args) {
// there can be other arguments based on signals
self.label = "new label";
}, "changed"),
});
Widget.Label({
label: someService.bind("service-prop").as((serviceProp) => {
return `transformed ${serviceProp}`;
}),
});
Utility to have multiple bindings as one
Widget.Label({
label: Utils.merge(
[service1.bind("prop1"), service2.bind("prop2")],
(p1, p2) => {
return `service1.prop1: ${p1}, service2.prop2: ${p2}`;
},
),
});
Services can be also connected outside of widgets
someService.connect("changed", (service, ...args) => {
print(service, ...args);
});
If you reference a widget inside someService.connect, make sure to handle
disconnection as well if that widget is destroyed
use Service.import
const battery = await Service.import("battery");
or if you prefer static import
import { battery } from "resource:///com/github/Aylur/ags/service/battery.js";
Import default and don't import the service class from the module, unless
you need the type when using typescript.
// this is the service singleton instance
import Battery from "resource:///com/github/Aylur/ags/service/battery.js";
// this is also the service singleton instance
import { battery } from "resource:///com/github/Aylur/ags/service/battery.js";
Battery === battery; // true
// DON'T import it this way, this is the class
import { Battery } from "resource:///com/github/Aylur/ags/service/battery.js";
Every service has a "changed" signal which is emitted on any kind of state
change, unless stated otherwise.