diff options
Diffstat (limited to 'js/node')
-rw-r--r-- | js/node/application.ts | 51 | ||||
-rw-r--r-- | js/node/astal.ts | 38 | ||||
-rw-r--r-- | js/node/widgets.ts | 63 |
3 files changed, 152 insertions, 0 deletions
diff --git a/js/node/application.ts b/js/node/application.ts new file mode 100644 index 0000000..875c1c8 --- /dev/null +++ b/js/node/application.ts @@ -0,0 +1,51 @@ +import gi from "node-gtk" +import { RequestHandler, Config, runJS } from "../src/application.js" +const Astal = gi.require("Astal", "0.1") + +class AstalJS extends Astal.Application { + static GTypeName = "AstalJS" + static { gi.registerClass(this) } + + eval = runJS + requestHandler?: RequestHandler + + vfunc_response(msg: string, conn: any): void { + if (typeof this.requestHandler === "function") { + this.requestHandler(msg, response => { + Astal.writeSock(conn, response, (_, res) => + Astal.writeSockFinish(res), + ) + }) + } else { + // @ts-expect-error missing type + super.vfunc_response(msg, conn) + } + } + + start( + { requestHandler, css, ...cfg }: Omit<Config, "hold"> = {}, + callback?: (args: string[]) => any, + ) { + Object.assign(this, cfg) + + this.requestHandler = requestHandler + this.on("activate", () => { + callback?.(process.argv) + }) + + if (!this.acquireSocket()) { + console.error(`Astal instance "${this.instanceName}" already running`) + process.exit() + } + + if (css) + this.applyCss(css, false) + + // FIXME: promises never resolve + // https://github.com/romgrk/node-gtk/issues/121 + // https://gitlab.gnome.org/GNOME/gjs/-/issues/468 + App.run([]) + } +} + +export const App = new AstalJS diff --git a/js/node/astal.ts b/js/node/astal.ts new file mode 100644 index 0000000..9560a81 --- /dev/null +++ b/js/node/astal.ts @@ -0,0 +1,38 @@ +import gi from "node-gtk" +import Time from "../src/time.js" +import Process from "../src/process.js" +import * as variable from "../src/variable.js" +const Astal = gi.require("Astal", "0.1") + +const { interval, timeout, idle } = Time(Astal.Time) +const { subprocess, exec, execAsync } = Process({ + defaultOut: console.log, + defaultErr: console.error, + exec: Astal.Process.exec, + execv: Astal.Process.execv, + execAsync: Astal.Process.execAsync, + execAsyncv: Astal.Process.execAsyncv, + subprocess: Astal.Process.subprocess, + subprocessv: Astal.Process.subprocessv, +}) + +variable.config.defaultErrHandler = console.log +variable.config.execAsync = execAsync +variable.config.subprocess = subprocess +variable.config.interval = interval +variable.config.VariableBase = Astal.VariableBase +Object.freeze(variable.config) + +export { subprocess, exec, execAsync } +export { interval, timeout, idle } +export { bind } from "../src/binding.js" +export { Variable } from "../src/variable.js" +export * as Widget from "./widgets.js" +export { App } from "./application.js" + +// for convinience +export const GLib = gi.require("GLib", "2.0") +export const Gtk = gi.require("Gtk", "3.0") +export const Gio = gi.require("Gio", "2.0") +export const GObject = gi.require("GObject", "2.0") +export { Astal, gi } diff --git a/js/node/widgets.ts b/js/node/widgets.ts new file mode 100644 index 0000000..914821d --- /dev/null +++ b/js/node/widgets.ts @@ -0,0 +1,63 @@ +/* eslint-disable max-len */ +import gi from "node-gtk" +import proxy, { type ConstructProps, type Widget } from "../src/astalify.js" +import type GtkT from "@girs/node-gtk-3.0/node-gtk-3.0" +import type AstalT from "@girs/node-astal-0.1/node-astal-0.1" + +const Astal = gi.require("Astal", "0.1") +const Gtk = gi.require("Gtk", "3.0") + +const proxify = proxy(Gtk, + prop => `set${prop.charAt(0).toUpperCase() + prop.slice(1)}`, + { + cssGetter: Astal.widgetGetCss, + cssSetter: Astal.widgetSetCss, + classGetter: Astal.widgetGetClassNames, + classSetter: Astal.widgetSetClassNames, + cursorGetter: Astal.widgetGetCursor, + cursorSetter: Astal.widgetSetCursor, + }) + +export function astalify< + C extends typeof Gtk.Widget, + P extends Record<string, any>, + N extends string = "Widget", +>(klass: C) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type Astal<N> = Omit<C, "new"> & { + new(props: P, ...children: GtkT.Widget[]): Widget<C> + (props: P, ...children: GtkT.Widget[]): Widget<C> + } + + return proxify(klass) as unknown as Astal<N> +} + +// Label +export const Label = astalify<typeof Gtk.Label, LabelProps, "Label">(Gtk.Label) +export type LabelProps = ConstructProps<typeof Gtk.Label, GtkT.Label.ConstructorProperties> + +// Icon +export const Icon = astalify<typeof Astal.Icon, IconProps, "Icon">(Astal.Icon) +export type IconProps = ConstructProps<typeof Astal.Icon, AstalT.Icon.ConstructorProperties> + +// Button +export const Button = astalify<typeof Astal.Button, ButtonProps, "Button">(Astal.Button) +export type ButtonProps = ConstructProps<typeof Astal.Button, AstalT.Button.ConstructorProperties, { + onClicked: (self: Widget<typeof Astal.Button>) => void +}> + +// Window +export const Window = astalify<typeof Astal.Window, WindowProps, "Window">(Astal.Window) +export type WindowProps = ConstructProps<typeof Astal.Window, AstalT.Window.ConstructorProperties> + +// Box +export const Box = astalify<typeof Astal.Box, BoxProps, "Box">(Astal.Box) +export type BoxProps = ConstructProps<typeof Astal.Box, AstalT.Box.ConstructorProperties> + +// CenterBox +export const CenterBox = astalify<typeof Astal.CenterBox, CenterBoxProps, "CenterBox">(Astal.CenterBox) +export type CenterBoxProps = ConstructProps<typeof Astal.CenterBox, AstalT.CenterBox.ConstructorProperties> + +// EventBox +export const EventBox = astalify<typeof Astal.EventBox, EventBoxProps, "EventBox">(Astal.EventBox) +export type EventBoxProps = ConstructProps<typeof Astal.EventBox, AstalT.EventBox.ConstructorProperties> |