import GObject, { register, property, signal } from "astal/gobject"; import { VSMonitor } from "./monitor"; import { VSOutput } from "./output"; import { CompositorConnection } from "@services/compositor"; import { EventType, VSOutputEvent } from "@services/compositor/types"; @register({ GTypeName: "OutputService", }) export class OutputService extends GObject.Object { #monitors: VSMonitor[] = []; #outputs: VSOutput[] = []; public get monitors(): readonly VSMonitor[] { return this.#monitors; } public get outputs(): readonly VSOutput[] { return this.#outputs; } @signal(VSMonitor) declare monitorConnected: (monitor: VSMonitor) => void; constructor() { super(); CompositorConnection.instance.connect( "output-change", (_, event: VSOutputEvent) => { console.log("processing output change event"); switch (event.type) { case EventType.CREATE: if ( this.#monitors.find( (monitor) => monitor.name === event.output, ) === null ) { this.#monitors.push(new VSMonitor(event.adapter!)); break; } case EventType.CHANGE: const monitor = this.#monitors.find( (monitor) => monitor.name === event.output, ); monitor?.sync(event.adapter!); break; case EventType.DESTROY: const idx = this.#monitors.findIndex( (output) => output.name === event.output, ); if (idx === -1) break; this.#monitors[idx].destroyed(); this.#monitors.splice(idx, 1); break; } }, ); CompositorConnection.instance .getOutputs() .then((compositorOutputs) => { compositorOutputs.forEach((output) => this.#monitors.push(new VSMonitor(output)), ); }) .catch(console.error); } }