🔧 chore: implement gresource in application + global variables

This commit is contained in:
retrozinndev
2025-08-09 20:54:08 -03:00
parent ade1816cfe
commit 4df1a9e7c9
3 changed files with 48 additions and 37 deletions
+21 -7
View File
@@ -43,7 +43,9 @@ const runnerPlugins: Array<Runner.Plugin> = [
const defaultWindows: Array<string> = []; const defaultWindows: Array<string> = [];
Gtk.init();
Adw.init(); Adw.init();
GLib.unsetenv("LD_PRELOAD");
@register({ GTypeName: "Shell" }) @register({ GTypeName: "Shell" })
export class Shell extends Gtk.Application { export class Shell extends Gtk.Application {
@@ -51,8 +53,10 @@ export class Shell extends Gtk.Application {
#loop!: GLib.MainLoop; #loop!: GLib.MainLoop;
#scope!: ReturnType<typeof getScope>; #scope!: ReturnType<typeof getScope>;
#connections = new Map<GObject.Object, Array<number> | number>();
#stylesheet: Uint8Array|undefined; #stylesheet: Uint8Array|undefined;
#styleProvider: Gtk.CssProvider; #styleProvider: Gtk.CssProvider;
#gresource: Gio.Resource|null = null;
get scope() { return this.#scope; } get scope() { return this.#scope; }
@@ -64,6 +68,12 @@ export class Shell extends Gtk.Application {
}); });
this.#styleProvider = Gtk.CssProvider.new(); this.#styleProvider = Gtk.CssProvider.new();
try {
this.#gresource = Gio.Resource.load(GRESOURCES_FILE);
} catch(_e) {
const e = _e as Error;
console.error(`Error: couldn't load gresource! Stderr: ${e.message}\n${e.stack}`);
}
} }
public static getDefault(): Shell { public static getDefault(): Shell {
@@ -121,18 +131,22 @@ export class Shell extends Gtk.Application {
printerr("Error: colorshell not running. Try to clean-run before using arguments"); printerr("Error: colorshell not running. Try to clean-run before using arguments");
return 1; return 1;
} }
this.main(); this.activate();
} }
return 0; return 0;
} }
vfunc_activate(): void {
super.vfunc_activate();
this.main();
}
private main(): void { private main(): void {
this.#loop = GLib.MainLoop.new(null, false); this.#loop = GLib.MainLoop.new(null, false);
const connections = new Map<GObject.Object, Array<number> | number>();
connections.set(this, this.connect("shutdown", () => this.#scope.dispose())); this.#connections.set(this, this.connect("shutdown", () => this.#scope.dispose()));
createRoot(() => { createRoot(() => {
console.log(`Colorshell: initializing`); console.log(`Colorshell: initializing`);
this.#scope = getScope(); this.#scope = getScope();
@@ -148,12 +162,12 @@ export class Shell extends Gtk.Application {
console.log("Adding runner plugins"); console.log("Adding runner plugins");
runnerPlugins.forEach(plugin => Runner.addPlugin(plugin)); runnerPlugins.forEach(plugin => Runner.addPlugin(plugin));
connections.set(Wireplumber.getDefault(), this.#connections.set(Wireplumber.getDefault(),
Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () => Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () =>
triggerOSD()) triggerOSD())
); );
connections.set(Notifications.getDefault(), [ this.#connections.set(Notifications.getDefault(), [
Notifications.getDefault().connect("notification-added", (_, _notif: AstalNotifd.Notification) => { Notifications.getDefault().connect("notification-added", (_, _notif: AstalNotifd.Notification) => {
Windows.getDefault().open("floating-notifications"); Windows.getDefault().open("floating-notifications");
}), }),
@@ -167,7 +181,7 @@ export class Shell extends Gtk.Application {
this.#scope.onCleanup(() => { this.#scope.onCleanup(() => {
console.log("Colorshell: disposing connections and quitting because of ::shutdown"); console.log("Colorshell: disposing connections and quitting because of ::shutdown");
connections.forEach((ids, obj) => Array.isArray(ids) ? this.#connections.forEach((ids, obj) => Array.isArray(ids) ?
ids.forEach(id => obj.disconnect(id)) ids.forEach(id => obj.disconnect(id))
: obj.disconnect(ids)); : obj.disconnect(ids));
}); });
+2
View File
@@ -1,4 +1,6 @@
declare const SRC: string declare const SRC: string
declare const DEVEL: boolean;
declare const GRESOURCES_FILE: string;
declare module "inline:*" { declare module "inline:*" {
const content: string const content: string
+25 -30
View File
@@ -7,7 +7,7 @@ import { FloatingNotifications } from "./window/FloatingNotifications";
import { CenterWindow } from "./window/CenterWindow"; import { CenterWindow } from "./window/CenterWindow";
import { LogoutMenu } from "./window/LogoutMenu"; import { LogoutMenu } from "./window/LogoutMenu";
import { AppsWindow } from "./window/AppsWindow"; import { AppsWindow } from "./window/AppsWindow";
import { Scope } from "/usr/share/ags/js/gnim/src/jsx/scope"; import { createRoot, getScope, onCleanup, Scope } from "/usr/share/ags/js/gnim/src/jsx/scope";
import { Shell } from "./app"; import { Shell } from "./app";
import GObject, { getter, register, signal } from "ags/gobject"; import GObject, { getter, register, signal } from "ags/gobject";
@@ -35,6 +35,7 @@ export type WindowData = {
class Windows extends GObject.Object { class Windows extends GObject.Object {
private static instance: (Windows | null); private static instance: (Windows | null);
#scope!: ReturnType<typeof getScope>;
#windows: Record<string, WindowData> = { #windows: Record<string, WindowData> = {
"bar": { create: this.createWindowForMonitors(Bar) }, "bar": { create: this.createWindowForMonitors(Bar) },
"osd": { create: this.createWindowForFocusedMonitor(OSD), }, "osd": { create: this.createWindowForFocusedMonitor(OSD), },
@@ -60,32 +61,24 @@ class Windows extends GObject.Object {
constructor() { constructor() {
super(); super();
// Listen to monitor events createRoot((dispose) => {
const hyprConnections = [ this.#scope = getScope();
AstalHyprland.get_default().connect("monitor-added", () => Shell.getDefault().scope.onMount(dispose);
this.reopen()),
AstalHyprland.get_default().connect("monitor-removed", () =>
AstalHyprland.get_default().get_monitors().length > 0 &&
this.reopen())
];
Shell.getDefault().scope.run(() => { // Listen to monitor events
// open windows with the "open" status on startup const hyprConnections = [
Object.keys(this.#windows).filter((key) => AstalHyprland.get_default().connect("monitor-added", () =>
this.#windows[key].status === "open" this.reopen()),
).forEach(name => { AstalHyprland.get_default().connect("monitor-removed", () =>
this.open(name, true); AstalHyprland.get_default().get_monitors().length > 0 &&
console.log(`Windows: opening window \`${name}\` on startup`); this.reopen())
];
onCleanup(() => {
hyprConnections.forEach(id => AstalHyprland.get_default().disconnect(id));
this.openWindows.forEach(name => this.disconnectWindow(name));
}); });
});
Shell.getDefault().scope.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));
}); });
} }
@@ -199,12 +192,14 @@ class Windows extends GObject.Object {
// create a scope for every window generator function and dispose on ::close-request // create a scope for every window generator function and dispose on ::close-request
return () => monitors.map(mon => { return () => monitors.map(mon => {
const scope = new Scope(null); return createRoot(() => {
return scope.run(() => { const scope = getScope();
const instance = create(mon.id, scope) as Astal.Window; const instance = create(mon.id, scope) as Astal.Window;
const connection: number = instance.connect("close-request", () => const connection: number = instance.connect("close-request", () =>
scope.dispose()); scope.dispose());
this.#scope.onMount(scope.dispose);
scope.onCleanup(() => instance.disconnect(connection)); scope.onCleanup(() => instance.disconnect(connection));
return instance; return instance;
@@ -227,12 +222,12 @@ class Windows extends GObject.Object {
}); });
return () => { return () => {
const scope = new Scope(null); return createRoot((dispose) => {
return scope.run(() => { const scope = getScope();
const instance = create(focusedMonitor, scope) as Astal.Window; const instance = create(focusedMonitor, scope) as Astal.Window;
const connection: number = instance.connect("close-request", () => const connection = instance.connect("close-request", () => dispose());
scope.dispose());
this.#scope.onMount(dispose)
scope.onCleanup(() => instance.disconnect(connection)); scope.onCleanup(() => instance.disconnect(connection));
return instance; return instance;