82 lines
2.4 KiB
TypeScript

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;
private onOutputEvent(event: VSOutputEvent) {
console.log("processing output change event");
const idx = this.#monitors.findIndex(
(monitor) => monitor.name === event.output,
);
switch (event.type) {
case EventType.CREATE:
if (idx === -1) {
console.log(`new monitor ${event.output} connected`);
const newMonitor = new VSMonitor(event.adapter!);
this.#monitors.push(newMonitor);
this.monitorConnected(newMonitor);
} else {
console.warn(
`Received create event for monitor ${event.output} we already know about. This is probably a bug!`,
);
}
break;
case EventType.CHANGE:
if (idx === -1) {
console.warn(
`Received change event for monitor ${event.output} we don't know about. This is probably a bug!`,
);
} else {
this.#monitors[idx].sync(event.adapter!);
}
break;
case EventType.DESTROY:
if (idx === -1) {
console.warn(
`Received destroy event for monitor ${event.output} we don't know about. This is probably a bug!`,
);
} else {
this.#monitors[idx].destroy();
this.#monitors.splice(idx, 1);
}
}
}
constructor() {
super();
CompositorConnection.instance
.getOutputs()
.then((compositorOutputs) => {
compositorOutputs.forEach((output) =>
this.#monitors.push(new VSMonitor(output)),
);
})
.catch(console.error)
.then(() =>
CompositorConnection.instance.connect(
"output-change",
(_, event: VSOutputEvent) => this.onOutputEvent(event),
),
);
}
}