diff --git a/modules/ags/gtk4/widget/subclasses/_astal.ts b/modules/ags/gtk4/widget/subclasses/_astal.ts index a7093131..13186c5c 100644 --- a/modules/ags/gtk4/widget/subclasses/_astal.ts +++ b/modules/ags/gtk4/widget/subclasses/_astal.ts @@ -1,12 +1,14 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { execAsync, Variable } from 'astal'; +import { Gtk } from 'astal/gtk4'; import Binding, { Connectable, kebabify, snakeify, Subscribable } from 'astal/binding'; export const noImplicitDestroy = Symbol('no no implicit destroy'); export const setChildren = Symbol('children setter method'); -const mergeBindings = (array: any[]) => { - const getValues = (...args: any[]) => { +const mergeBindings = ( + array: (Value | Binding)[], +): Value[] | Binding => { + const getValues = (...args: Value[]) => { let i = 0; return array.map((value) => value instanceof Binding ? @@ -16,14 +18,19 @@ const mergeBindings = (array: any[]) => { const bindings = array.filter((i) => i instanceof Binding); - if (bindings.length === 0) { return array; } + if (bindings.length === 0) { + return array as Value[]; + } - if (bindings.length === 1) { return bindings[0].as(getValues); } + if (bindings.length === 1) { + return bindings[0].as(getValues); + } return Variable.derive(bindings, getValues)(); }; -const setProp = (obj: any, prop: string, value: any) => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const setProp = (obj: any, prop: string, value: unknown) => { try { const setter = `set_${snakeify(prop)}`; @@ -39,11 +46,11 @@ const setProp = (obj: any, prop: string, value: any) => { export const hook = ( widget: Widget, object: Connectable | Subscribable, - signalOrCallback: string | ((self: Widget, ...args: any[]) => void), - callback?: (self: Widget, ...args: any[]) => void, + signalOrCallback: string | ((self: Widget, ...args: unknown[]) => void), + callback?: (self: Widget, ...args: unknown[]) => void, ) => { if (typeof object.connect === 'function' && callback) { - const id = object.connect(signalOrCallback, (_: any, ...args: unknown[]) => { + const id = object.connect(signalOrCallback, (_: unknown, ...args: unknown[]) => { callback(widget, ...args); }); @@ -61,7 +68,8 @@ export const hook = ( }; export const construct = void + [setChildren]: (children: Gtk.Widget[]) => void + // eslint-disable-next-line @typescript-eslint/no-explicit-any }>(widget: Widget, config: any) => { // eslint-disable-next-line prefer-const let { setup, child, children = [], ...props } = config; @@ -82,9 +90,9 @@ export const construct = ][] = Object + const bindings: [string, Binding][] = Object .keys(props) - .reduce((acc: any, prop) => { + .reduce((acc: [string, Binding][], prop) => { if (props[prop] instanceof Binding) { const binding = props[prop]; @@ -99,7 +107,7 @@ export const construct = unknown)][] = Object .keys(props) - .reduce((acc: any, key) => { + .reduce((acc: [string, Binding][], key) => { if (key.startsWith('on')) { const sig = kebabify(key).split('-').slice(1).join('-'); const handler = props[key]; @@ -113,7 +121,7 @@ export const construct = (children.flat(Infinity)); if (mergedChildren instanceof Binding) { widget[setChildren](mergedChildren.get()); @@ -143,11 +151,11 @@ export const construct = { + widget.connect('destroy', (binding as Binding).subscribe((v: Gtk.Widget[]) => { widget[setChildren](v); })); } - widget.connect('destroy', binding.subscribe((v: any) => { + widget.connect('destroy', binding.subscribe((v: unknown) => { setProp(widget, prop, v); })); setProp(widget, prop, binding.get()); diff --git a/modules/ags/gtk4/widget/subclasses/astalify.ts b/modules/ags/gtk4/widget/subclasses/astalify.ts index 099d6471..9cb00002 100644 --- a/modules/ags/gtk4/widget/subclasses/astalify.ts +++ b/modules/ags/gtk4/widget/subclasses/astalify.ts @@ -1,9 +1,7 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import Gdk from 'gi://Gdk?version=4.0'; -import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk?version=4.0'; +import { property, register } from 'astal'; import Binding, { type Connectable, type Subscribable } from 'astal/binding'; import { hook, @@ -14,12 +12,6 @@ import { export type BindableChild = Gtk.Widget | Binding; -export const filter = (children: any[]) => { - return children.flat(Infinity).map((ch) => ch instanceof Gtk.Widget ? - ch : - new Gtk.Label({ visible: true, label: String(ch) })); -}; - export const type = Symbol('child type'); const dummyBuilder = new Gtk.Builder(); @@ -131,13 +123,17 @@ const setupControllers = (widget: Gtk.Widget, { return props; }; -export default < - C extends new(...args: any[]) => Gtk.Widget, ->(cls: C, clsName = cls.name) => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export default Gtk.Widget>( + cls: C, + clsName = cls.name, +) => { + @register({ GTypeName: `RealClass_${clsName}` }) class Widget extends cls { declare private _css: string | undefined; declare private _provider: Gtk.CssProvider | undefined; + @property(String) get css(): string | undefined { return this._css; } @@ -156,18 +152,28 @@ export default < this._provider.load_from_string(value); } + declare private [type]: string; + + @property(String) get type(): string { return this[type]; } + set type(value: string) { this[type] = value; } + get children(): Gtk.Widget[] { return this.getChildren(this); } + set children(value: Gtk.Widget[]) { this.setChildren(this, value); } declare private [noImplicitDestroy]: boolean; + + @property(String) get noImplicitDestroy(): boolean { return this[noImplicitDestroy]; } + set noImplicitDestroy(value: boolean) { this[noImplicitDestroy] = value; } + protected getChildren(widget: Gtk.Widget): Gtk.Widget[] { if ('get_child' in widget && typeof widget.get_child == 'function') { return widget.get_child() ? [widget.get_child()] : []; @@ -184,11 +190,7 @@ export default < return children; } - protected setChildren(widget: Gtk.Widget, children: any[]) { - children = children.flat(Infinity).map((ch) => ch instanceof Gtk.Widget ? - ch : - new Gtk.Label({ visible: true, label: String(ch) })); - + protected setChildren(widget: Gtk.Widget, children: Gtk.Widget[]) { for (const child of children) { widget.vfunc_add_child( dummyBuilder, @@ -198,38 +200,42 @@ export default < } } - [setChildren](children: any[]) { - const w = this as unknown as Widget; + [setChildren](children: Gtk.Widget[]) { + for (const child of (this.getChildren(this))) { + child?.unparent(); - for (const child of (this.getChildren(w))) { - if (child instanceof Gtk.Widget) { - child.unparent(); - if (!children.includes(child) && noImplicitDestroy in this) { child.run_dispose(); } + if (!children.includes(child) && noImplicitDestroy in this) { + child.run_dispose(); } } - this.setChildren(w, children); + this.setChildren(this, children); } + hook( object: Connectable, signal: string, - callback: (self: this, ...args: any[]) => void, + callback: (self: this, ...args: unknown[]) => void, ): this; + hook( object: Subscribable, - callback: (self: this, ...args: any[]) => void, + callback: (self: this, ...args: unknown[]) => void, ): this; + hook( object: Connectable | Subscribable, - signalOrCallback: string | ((self: this, ...args: any[]) => void), - callback?: (self: this, ...args: any[]) => void, + signalOrCallback: string | ((self: this, ...args: unknown[]) => void), + callback?: (self: this, ...args: unknown[]) => void, ) { hook(this, object, signalOrCallback, callback); return this; } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(...params: any[]) { const props = params[0] || {}; @@ -249,24 +255,9 @@ export default < delete props.type; } - construct(this as any, setupControllers(this, props)); + construct(this, setupControllers(this, props)); } } - GObject.registerClass({ - GTypeName: `RealClass_${clsName}`, - Properties: { - 'css': GObject.ParamSpec.string( - 'css', '', '', GObject.ParamFlags.READWRITE, '', - ), - 'type': GObject.ParamSpec.string( - 'type', '', '', GObject.ParamFlags.READWRITE, '', - ), - 'no-implicit-destroy': GObject.ParamSpec.boolean( - 'no-implicit-destroy', '', '', GObject.ParamFlags.READWRITE, false, - ), - }, - }, Widget); - return Widget; }; diff --git a/modules/ags/gtk4/widget/subclasses/box.ts b/modules/ags/gtk4/widget/subclasses/box.ts index 92cc817b..9412e575 100644 --- a/modules/ags/gtk4/widget/subclasses/box.ts +++ b/modules/ags/gtk4/widget/subclasses/box.ts @@ -1,9 +1,7 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; -import { Astal, type ConstructProps } from 'astal/gtk4'; +import { Astal, type ConstructProps, Gtk } from 'astal/gtk4'; -import astalify, { filter } from './astalify'; +import astalify from './astalify'; export type BoxProps = ConstructProps< @@ -13,13 +11,14 @@ export type BoxProps = ConstructProps< @register({ GTypeName: 'Box' }) export class Box extends astalify(Astal.Box) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: BoxProps) { super(props as any); } getChildren(self: Box) { return self.get_children(); } - setChildren(self: Box, children: any[]) { - return self.set_children(filter(children)); + setChildren(self: Box, children: Gtk.Widget[]) { + return self.set_children(children); } } diff --git a/modules/ags/gtk4/widget/subclasses/button.ts b/modules/ags/gtk4/widget/subclasses/button.ts index 251f0cd0..1a8f6551 100644 --- a/modules/ags/gtk4/widget/subclasses/button.ts +++ b/modules/ags/gtk4/widget/subclasses/button.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -17,5 +15,6 @@ export type ButtonProps = ConstructProps< @register({ GTypeName: 'Button' }) export class Button extends astalify(Gtk.Button) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: ButtonProps) { super(props as any); } } diff --git a/modules/ags/gtk4/widget/subclasses/calendar.ts b/modules/ags/gtk4/widget/subclasses/calendar.ts index dd7877e7..542aab54 100644 --- a/modules/ags/gtk4/widget/subclasses/calendar.ts +++ b/modules/ags/gtk4/widget/subclasses/calendar.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -22,5 +20,6 @@ export type CalendarProps = ConstructProps< @register({ GTypeName: 'Calendar' }) export class Calendar extends astalify(Gtk.Calendar) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: CalendarProps) { super(props as any); } } diff --git a/modules/ags/gtk4/widget/subclasses/centerbox.ts b/modules/ags/gtk4/widget/subclasses/centerbox.ts index 1dd2a4e8..9834db6e 100644 --- a/modules/ags/gtk4/widget/subclasses/centerbox.ts +++ b/modules/ags/gtk4/widget/subclasses/centerbox.ts @@ -1,9 +1,7 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; -import astalify, { filter } from './astalify'; +import astalify from './astalify'; export type CenterBoxProps = ConstructProps< @@ -13,17 +11,20 @@ export type CenterBoxProps = ConstructProps< @register({ GTypeName: 'CenterBox' }) export class CenterBox extends astalify(Gtk.CenterBox) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: CenterBoxProps) { super(props as any); } getChildren(box: CenterBox) { return [box.startWidget, box.centerWidget, box.endWidget]; } - setChildren(box: CenterBox, children: any[]) { - const ch = filter(children); + setChildren(box: CenterBox, children: (Gtk.Widget | null)[]) { + if (children.length > 3) { + throw new Error('Cannot have more than 3 children in a CenterBox'); + } - box.startWidget = ch[0] || new Gtk.Box(); - box.centerWidget = ch[1] || new Gtk.Box(); - box.endWidget = ch[2] || new Gtk.Box(); + box.startWidget = children[0] || new Gtk.Box(); + box.centerWidget = children[1] || new Gtk.Box(); + box.endWidget = children[2] || new Gtk.Box(); } } diff --git a/modules/ags/gtk4/widget/subclasses/entry.ts b/modules/ags/gtk4/widget/subclasses/entry.ts index 8a60467f..a5e42666 100644 --- a/modules/ags/gtk4/widget/subclasses/entry.ts +++ b/modules/ags/gtk4/widget/subclasses/entry.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -18,6 +16,7 @@ export type EntryProps = ConstructProps< @register({ GTypeName: 'Entry' }) export class Entry extends astalify(Gtk.Entry) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: EntryProps) { super(props as any); } getChildren() { return []; } diff --git a/modules/ags/gtk4/widget/subclasses/image.ts b/modules/ags/gtk4/widget/subclasses/image.ts index 14d05382..5e24735d 100644 --- a/modules/ags/gtk4/widget/subclasses/image.ts +++ b/modules/ags/gtk4/widget/subclasses/image.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -13,6 +11,7 @@ export type ImageProps = ConstructProps< @register({ GTypeName: 'Image' }) export class Image extends astalify(Gtk.Image) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: ImageProps) { super(props as any); } getChildren() { return []; } diff --git a/modules/ags/gtk4/widget/subclasses/label.ts b/modules/ags/gtk4/widget/subclasses/label.ts index b85d83a1..c5a4749e 100644 --- a/modules/ags/gtk4/widget/subclasses/label.ts +++ b/modules/ags/gtk4/widget/subclasses/label.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -13,9 +11,8 @@ export type LabelProps = ConstructProps< @register({ GTypeName: 'Label' }) export class Label extends astalify(Gtk.Label) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: LabelProps) { super(props as any); } getChildren() { return []; } - - setChildren(self: Label, children: any[]) { self.label = String(children); } } diff --git a/modules/ags/gtk4/widget/subclasses/levelbar.ts b/modules/ags/gtk4/widget/subclasses/levelbar.ts index 06f45c88..87b9491d 100644 --- a/modules/ags/gtk4/widget/subclasses/levelbar.ts +++ b/modules/ags/gtk4/widget/subclasses/levelbar.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -13,6 +11,7 @@ export type LevelBarProps = ConstructProps< @register({ GTypeName: 'LevelBar' }) export class LevelBar extends astalify(Gtk.LevelBar) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: LevelBarProps) { super(props as any); } getChildren() { return []; } diff --git a/modules/ags/gtk4/widget/subclasses/menubutton.ts b/modules/ags/gtk4/widget/subclasses/menubutton.ts index 8adb62e3..e4f6d19d 100644 --- a/modules/ags/gtk4/widget/subclasses/menubutton.ts +++ b/modules/ags/gtk4/widget/subclasses/menubutton.ts @@ -1,9 +1,7 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; -import astalify, { filter } from './astalify'; +import astalify from './astalify'; export type MenuButtonProps = ConstructProps< @@ -13,14 +11,15 @@ export type MenuButtonProps = ConstructProps< @register({ GTypeName: 'MenuButton' }) export class MenuButton extends astalify(Gtk.MenuButton) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: MenuButtonProps) { super(props as any); } getChildren(self: MenuButton) { return [self.popover, self.child]; } - setChildren(self: MenuButton, children: any[]) { - for (const child of filter(children)) { + setChildren(self: MenuButton, children: Gtk.Widget[]) { + for (const child of children) { if (child instanceof Gtk.Popover) { self.set_popover(child); } diff --git a/modules/ags/gtk4/widget/subclasses/overlay.ts b/modules/ags/gtk4/widget/subclasses/overlay.ts index 6d794d72..e49489b6 100644 --- a/modules/ags/gtk4/widget/subclasses/overlay.ts +++ b/modules/ags/gtk4/widget/subclasses/overlay.ts @@ -1,9 +1,7 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; -import astalify, { filter, type } from './astalify'; +import astalify, { type } from './astalify'; export type OverlayProps = ConstructProps< @@ -13,6 +11,7 @@ export type OverlayProps = ConstructProps< @register({ GTypeName: 'Overlay' }) export class Overlay extends astalify(Gtk.Overlay) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: OverlayProps) { super(props as any); } getChildren(self: Overlay) { @@ -27,8 +26,8 @@ export class Overlay extends astalify(Gtk.Overlay) { return children.filter((child) => child !== self.child); } - setChildren(self: Overlay, children: any[]) { - for (const child of filter(children)) { + setChildren(self: Overlay, children: Gtk.Widget[]) { + for (const child of children) { const types = type in child ? (child[type] as string).split(/\s+/) : []; diff --git a/modules/ags/gtk4/widget/subclasses/popover.ts b/modules/ags/gtk4/widget/subclasses/popover.ts index 4b22d361..53c42d86 100644 --- a/modules/ags/gtk4/widget/subclasses/popover.ts +++ b/modules/ags/gtk4/widget/subclasses/popover.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -13,5 +11,6 @@ export type PopoverProps = ConstructProps< @register({ GTypeName: 'Popover' }) export class Popover extends astalify(Gtk.Popover) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: PopoverProps) { super(props as any); } } diff --git a/modules/ags/gtk4/widget/subclasses/revealer.ts b/modules/ags/gtk4/widget/subclasses/revealer.ts index 2f2da691..45e4ae26 100644 --- a/modules/ags/gtk4/widget/subclasses/revealer.ts +++ b/modules/ags/gtk4/widget/subclasses/revealer.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -13,5 +11,6 @@ export type RevealerProps = ConstructProps< @register({ GTypeName: 'Revealer' }) export class Revealer extends astalify(Gtk.Revealer) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: RevealerProps) { super(props as any); } } diff --git a/modules/ags/gtk4/widget/subclasses/slider.ts b/modules/ags/gtk4/widget/subclasses/slider.ts index fddb47b6..090eae4d 100644 --- a/modules/ags/gtk4/widget/subclasses/slider.ts +++ b/modules/ags/gtk4/widget/subclasses/slider.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Astal, type ConstructProps } from 'astal/gtk4'; @@ -17,6 +15,7 @@ export type SliderProps = ConstructProps< @register({ GTypeName: 'Slider' }) export class Slider extends astalify(Astal.Slider) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: SliderProps) { super(props as any); } getChildren() { return []; } diff --git a/modules/ags/gtk4/widget/subclasses/stack.ts b/modules/ags/gtk4/widget/subclasses/stack.ts index a65823ca..1be389ea 100644 --- a/modules/ags/gtk4/widget/subclasses/stack.ts +++ b/modules/ags/gtk4/widget/subclasses/stack.ts @@ -1,9 +1,7 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; -import astalify, { filter } from './astalify'; +import astalify from './astalify'; export type StackProps = ConstructProps< @@ -13,10 +11,11 @@ export type StackProps = ConstructProps< @register({ GTypeName: 'Stack' }) export class Stack extends astalify(Gtk.Stack) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: StackProps) { super(props as any); } - setChildren(self: Stack, children: any[]) { - for (const child of filter(children)) { + setChildren(self: Stack, children: Gtk.Widget[]) { + for (const child of children) { if (child.name !== '' && child.name !== null) { self.add_named(child, child.name); } diff --git a/modules/ags/gtk4/widget/subclasses/switch.ts b/modules/ags/gtk4/widget/subclasses/switch.ts index b2fdc1b2..09360c55 100644 --- a/modules/ags/gtk4/widget/subclasses/switch.ts +++ b/modules/ags/gtk4/widget/subclasses/switch.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Gtk, type ConstructProps } from 'astal/gtk4'; @@ -13,6 +11,7 @@ export type SwitchProps = ConstructProps< @register({ GTypeName: 'Switch' }) export class Switch extends astalify(Gtk.Switch) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: SwitchProps) { super(props as any); } getChildren() { return []; } diff --git a/modules/ags/gtk4/widget/subclasses/window.ts b/modules/ags/gtk4/widget/subclasses/window.ts index eca145b6..939d4ada 100644 --- a/modules/ags/gtk4/widget/subclasses/window.ts +++ b/modules/ags/gtk4/widget/subclasses/window.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { register } from 'astal'; import { Astal, type ConstructProps } from 'astal/gtk4'; @@ -13,5 +11,6 @@ export type WindowProps = ConstructProps< @register({ GTypeName: 'Window' }) export class Window extends astalify(Astal.Window) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(props?: WindowProps) { super(props as any); } }