diff options
author | Aylur <[email protected]> | 2024-11-03 02:51:15 +0100 |
---|---|---|
committer | Aylur <[email protected]> | 2024-11-03 02:52:59 +0100 |
commit | 510b233438987890d794644da909f6cf34d03a42 (patch) | |
tree | fd97a590d3af33f5042f2def1545160bfc187ac9 /lang/gjs/src/_app.ts | |
parent | da892f050143807f8a267dbbee1527cf655876b8 (diff) | |
parent | c0612d1d7e78c413d0c69de34f1ae7951e90bc90 (diff) |
Merge branch 'feat/gtk4'
initial gtk4 app and window
Diffstat (limited to 'lang/gjs/src/_app.ts')
-rw-r--r-- | lang/gjs/src/_app.ts | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/lang/gjs/src/_app.ts b/lang/gjs/src/_app.ts new file mode 100644 index 0000000..82e8bb5 --- /dev/null +++ b/lang/gjs/src/_app.ts @@ -0,0 +1,122 @@ +import { setConsoleLogDomain } from "console" +import { exit, programArgs } from "system" +import IO from "gi://AstalIO" +import GObject from "gi://GObject" +import Gio from "gi://Gio?version=2.0" +import type Astal3 from "gi://Astal?version=3.0" +import type Astal4 from "gi://Astal?version=4.0" + +type Config = Partial<{ + instanceName: string + css: string + icons: string + gtkTheme: string + iconTheme: string + cursorTheme: string + hold: boolean + requestHandler(request: string, res: (response: any) => void): void + main(...args: string[]): void + client(message: (msg: string) => string, ...args: string[]): void +}> + +interface Astal3JS extends Astal3.Application { + eval(body: string): Promise<any> + requestHandler: Config["requestHandler"] + apply_css(style: string, reset?: boolean): void + quit(code?: number): void + start(config?: Config): void +} + +interface Astal4JS extends Astal4.Application { + eval(body: string): Promise<any> + requestHandler?: Config["requestHandler"] + apply_css(style: string, reset?: boolean): void + quit(code?: number): void + start(config?: Config): void +} + +type App3 = typeof Astal3.Application +type App4 = typeof Astal4.Application + +export function mkApp<App extends App3>(App: App): Astal3JS +export function mkApp<App extends App4>(App: App): Astal4JS + +export function mkApp(App: App3 | App4) { + return new (class AstalJS extends App { + static { GObject.registerClass({ GTypeName: "AstalJS" }, this as any) } + + eval(body: string): Promise<any> { + return new Promise((res, rej) => { + try { + const fn = Function(`return (async function() { + ${body.includes(";") ? body : `return ${body};`} + })`) + fn()().then(res).catch(rej) + } + catch (error) { + rej(error) + } + }) + } + + requestHandler?: Config["requestHandler"] + + vfunc_request(msg: string, conn: Gio.SocketConnection): void { + if (typeof this.requestHandler === "function") { + this.requestHandler(msg, (response) => { + IO.write_sock(conn, String(response), (_, res) => + IO.write_sock_finish(res), + ) + }) + } + else { + super.vfunc_request(msg, conn) + } + } + + apply_css(style: string, reset = false) { + super.apply_css(style, reset) + } + + quit(code?: number): void { + super.quit() + exit(code ?? 0) + } + + start({ requestHandler, css, hold, main, client, icons, ...cfg }: Config = {}) { + const app = this as unknown as InstanceType<App3 | App4> + + client ??= () => { + print(`Astal instance "${app.instanceName}" already running`) + exit(1) + } + + Object.assign(this, cfg) + setConsoleLogDomain(app.instanceName) + + this.requestHandler = requestHandler + app.connect("activate", () => { + main?.(...programArgs) + }) + + try { + app.acquire_socket() + } + catch (error) { + return client(msg => IO.send_message(app.instanceName, msg)!, ...programArgs) + } + + if (css) + this.apply_css(css, false) + + if (icons) + app.add_icons(icons) + + hold ??= true + if (hold) + app.hold() + + app.runAsync([]) + } + }) +} |