diff --git a/ags/app.ts b/ags/app.ts index 46ea022..7976dc5 100644 --- a/ags/app.ts +++ b/ags/app.ts @@ -14,12 +14,15 @@ import { Stylesheet } from "./scripts/stylesheet"; import { Clipboard } from "./scripts/clipboard"; import { PluginClipboard } from "./runner/plugins/clipboard"; import { Config } from "./scripts/config"; +import { onCleanup, Scope } from "/usr/share/ags/js/gnim/src/jsx/scope"; import App from "ags/gtk4/app" import GObject from "ags/gobject"; import AstalNotifd from "gi://AstalNotifd"; +export const appScope: Scope = new Scope(null); + let osdTimer: (Time|undefined), osdTimeout = 3500; let connections = new Map | number)>(); @@ -40,8 +43,10 @@ App.start({ requestHandler: (request: string, response: (result: any) => void): void => { response(handleArguments(request)); }, - main: (..._args: Array) => { + main: (..._args: Array) => appScope.run(() => { console.log(`Initialized astal instance as: ${ App.instanceName || "astal" }`); + App.connect("shutdown", () => appScope.dispose()); + console.log("Config: initializing configuration file"); Config.getDefault(); @@ -63,10 +68,10 @@ App.start({ console.log("Adding runner plugins"); runnerPlugins.map(plugin => Runner.addPlugin(plugin)); - connections.set(Wireplumber.getDefault(), [ + connections.set(Wireplumber.getDefault(), Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () => triggerOSD()) - ]); + ); connections.set(Notifications.getDefault(), [ Notifications.getDefault().connect("notification-added", (_, _notif: AstalNotifd.Notification) => { @@ -78,7 +83,11 @@ App.start({ ]); defaultWindows.forEach(w => Windows.getDefault().open(w)); - } + + onCleanup(() => connections.forEach((ids, obj) => Array.isArray(ids) ? + ids.forEach(id => obj.disconnect(id)) + : obj.disconnect(ids))); + }) }); function triggerOSD() { diff --git a/ags/windows.ts b/ags/windows.ts index 7241c5a..1f4f7e9 100644 --- a/ags/windows.ts +++ b/ags/windows.ts @@ -12,6 +12,7 @@ import GObject, { getter, register, signal } from "ags/gobject"; import AstalHyprland from "gi://AstalHyprland"; import { Scope } from "../../../../usr/share/ags/js/gnim/src/jsx/scope"; +import { appScope } from "./app"; export { Windows }; @@ -60,25 +61,16 @@ class Windows extends GObject.Object { constructor() { super(); - createRoot((_) => { - // Listen to monitor events - const hyprConnections = [ - AstalHyprland.get_default().connect("monitor-added", () => - this.reopen()), - AstalHyprland.get_default().connect("monitor-removed", () => - AstalHyprland.get_default().get_monitors().length > 0 && - this.reopen()) - ]; - - onCleanup(() => { - hyprConnections.forEach(id => - GObject.signal_handler_is_connected(AstalHyprland.get_default(), id) && - AstalHyprland.get_default().disconnect(id) - ); - - this.openWindows.forEach(name => this.disconnectWindow(name)); - }); + // Listen to monitor events + const hyprConnections = [ + AstalHyprland.get_default().connect("monitor-added", () => + this.reopen()), + AstalHyprland.get_default().connect("monitor-removed", () => + AstalHyprland.get_default().get_monitors().length > 0 && + this.reopen()) + ]; + appScope.run(() => { // open windows with the "open" status on startup Object.keys(this.#windows).filter((key) => this.#windows[key].status === "open" @@ -87,6 +79,15 @@ class Windows extends GObject.Object { console.log(`Windows: opening window \`${name}\` on startup`); }); }); + + onCleanup(() => { + hyprConnections.forEach(id => + GObject.signal_handler_is_connected(AstalHyprland.get_default(), id) && + AstalHyprland.get_default().disconnect(id) + ); + + this.openWindows.forEach(name => this.disconnectWindow(name)); + }); } private disconnectWindow(name: string) { @@ -157,7 +158,7 @@ class Windows extends GObject.Object { window.instance.forEach(inst => inst.connections = [ inst.instance!.connect("close-request", () => { this.disconnectWindow(name); - inst.instance = undefined; + delete window.instance; window.status = "closed"; this.notify("open-windows"); }) @@ -169,7 +170,7 @@ class Windows extends GObject.Object { window.instance.connections = [ window.instance.instance!.connect("close-request", () => { this.disconnectWindow(name); - (window.instance as WindowInstance).instance = undefined; + delete window.instance; window.status = "closed"; this.notify("open-windows"); })