summaryrefslogtreecommitdiff
path: root/lang
diff options
context:
space:
mode:
Diffstat (limited to 'lang')
-rw-r--r--lang/gjs/meson.build1
-rw-r--r--lang/gjs/package.json2
-rw-r--r--lang/gjs/src/_app.ts1
-rw-r--r--lang/gjs/src/gobject.ts6
-rw-r--r--lang/gjs/src/gtk3/astalify.ts6
-rw-r--r--lang/gjs/src/gtk3/index.ts4
-rw-r--r--lang/gjs/src/gtk3/jsx-runtime.ts3
-rw-r--r--lang/gjs/src/index.ts1
-rw-r--r--lang/gjs/src/overrides.ts69
-rw-r--r--lang/gjs/tsconfig.json1
-rw-r--r--lang/lua/astal-dev-1.rockspec2
-rw-r--r--lang/lua/astal/binding.lua26
-rw-r--r--lang/lua/astal/gtk3/app.lua47
-rw-r--r--lang/lua/astal/gtk3/astalify.lua4
-rw-r--r--lang/lua/astal/gtk3/widget.lua1
-rw-r--r--lang/lua/astal/init.lua1
-rw-r--r--lang/lua/astal/variable.lua25
17 files changed, 139 insertions, 61 deletions
diff --git a/lang/gjs/meson.build b/lang/gjs/meson.build
index f4272ee..51496dc 100644
--- a/lang/gjs/meson.build
+++ b/lang/gjs/meson.build
@@ -14,6 +14,7 @@ install_data(
'src/process.ts',
'src/time.ts',
'src/variable.ts',
+ 'src/overrides.ts',
'src/_app.ts',
],
install_dir: dest,
diff --git a/lang/gjs/package.json b/lang/gjs/package.json
index da88d90..43a7702 100644
--- a/lang/gjs/package.json
+++ b/lang/gjs/package.json
@@ -4,7 +4,7 @@
"description": "Building blocks for building linux desktop shell",
"type": "module",
"author": "Aylur",
- "license": "GPL",
+ "license": "LGPL-2.1",
"repository": {
"type": "git",
"url": "https://github.com/aylur/astal.git",
diff --git a/lang/gjs/src/_app.ts b/lang/gjs/src/_app.ts
index 82e8bb5..3dadd04 100644
--- a/lang/gjs/src/_app.ts
+++ b/lang/gjs/src/_app.ts
@@ -1,3 +1,4 @@
+import "./overrides.js"
import { setConsoleLogDomain } from "console"
import { exit, programArgs } from "system"
import IO from "gi://AstalIO"
diff --git a/lang/gjs/src/gobject.ts b/lang/gjs/src/gobject.ts
index 59dd62a..b744cfb 100644
--- a/lang/gjs/src/gobject.ts
+++ b/lang/gjs/src/gobject.ts
@@ -51,6 +51,8 @@ export function register(options: MetaInfo = {}) {
Properties: { ...cls[meta]?.Properties },
...options,
}, cls)
+
+ delete cls[meta]
}
}
@@ -124,7 +126,9 @@ export function signal(
}
}
else {
- target.constructor[meta].Signals[name] = declaration
+ target.constructor[meta].Signals[name] = declaration || {
+ param_types: [],
+ }
}
if (!desc) {
diff --git a/lang/gjs/src/gtk3/astalify.ts b/lang/gjs/src/gtk3/astalify.ts
index b9621be..6973805 100644
--- a/lang/gjs/src/gtk3/astalify.ts
+++ b/lang/gjs/src/gtk3/astalify.ts
@@ -43,7 +43,7 @@ function setProp(obj: any, prop: string, value: any) {
export default function astalify<
C extends { new(...args: any[]): Gtk.Widget },
->(cls: C) {
+>(cls: C, clsName = cls.name) {
class Widget extends cls {
get css(): string { return Astal.widget_get_css(this) }
set css(css: string) { Astal.widget_set_css(this, css) }
@@ -233,7 +233,7 @@ export default function astalify<
}
GObject.registerClass({
- GTypeName: `Astal_${cls.name}`,
+ GTypeName: `Astal_${clsName}`,
Properties: {
"class-name": GObject.ParamSpec.string(
"class-name", "", "", GObject.ParamFlags.READWRITE, "",
@@ -256,7 +256,7 @@ export default function astalify<
return Widget
}
-type BindableProps<T> = {
+export type BindableProps<T> = {
[K in keyof T]: Binding<T[K]> | T[K];
}
diff --git a/lang/gjs/src/gtk3/index.ts b/lang/gjs/src/gtk3/index.ts
index cfafbda..ff641af 100644
--- a/lang/gjs/src/gtk3/index.ts
+++ b/lang/gjs/src/gtk3/index.ts
@@ -1,9 +1,9 @@
import Astal from "gi://Astal?version=3.0"
import Gtk from "gi://Gtk?version=3.0"
import Gdk from "gi://Gdk?version=3.0"
-import astalify, { type ConstructProps } from "./astalify.js"
+import astalify, { type ConstructProps, type BindableProps } from "./astalify.js"
export { Astal, Gtk, Gdk }
export { default as App } from "./app.js"
-export { astalify, ConstructProps }
+export { astalify, ConstructProps, BindableProps }
export * as Widget from "./widget.js"
diff --git a/lang/gjs/src/gtk3/jsx-runtime.ts b/lang/gjs/src/gtk3/jsx-runtime.ts
index 22dc424..9da4bb6 100644
--- a/lang/gjs/src/gtk3/jsx-runtime.ts
+++ b/lang/gjs/src/gtk3/jsx-runtime.ts
@@ -10,7 +10,8 @@ export function Fragment({ children = [], child }: {
child?: BindableChild
children?: Array<BindableChild>
}) {
- return mergeBindings([...children, child])
+ if (child) children.push(child)
+ return mergeBindings(children)
}
export function jsx(
diff --git a/lang/gjs/src/index.ts b/lang/gjs/src/index.ts
index cabc961..8fe8d01 100644
--- a/lang/gjs/src/index.ts
+++ b/lang/gjs/src/index.ts
@@ -1,3 +1,4 @@
+import "./overrides.js"
export { default as AstalIO } from "gi://AstalIO?version=0.1"
export * from "./process.js"
export * from "./time.js"
diff --git a/lang/gjs/src/overrides.ts b/lang/gjs/src/overrides.ts
new file mode 100644
index 0000000..6643ba5
--- /dev/null
+++ b/lang/gjs/src/overrides.ts
@@ -0,0 +1,69 @@
+/**
+ * Workaround for "Can't convert non-null pointer to JS value "
+ */
+
+export { }
+
+const snakeify = (str: string) => str
+ .replace(/([a-z])([A-Z])/g, "$1_$2")
+ .replaceAll("-", "_")
+ .toLowerCase()
+
+async function suppress<T>(mod: Promise<{ default: T }>, patch: (m: T) => void) {
+ return mod.then(m => patch(m.default)).catch(() => void 0)
+}
+
+function patch<P extends object>(proto: P, prop: Extract<keyof P, string>) {
+ Object.defineProperty(proto, prop, {
+ get() { return this[`get_${snakeify(prop)}`]() },
+ })
+}
+
+await suppress(import("gi://AstalApps"), ({ Apps, Application }) => {
+ patch(Apps.prototype, "list")
+ patch(Application.prototype, "keywords")
+ patch(Application.prototype, "categories")
+})
+
+await suppress(import("gi://AstalBattery"), ({ UPower }) => {
+ patch(UPower.prototype, "devices")
+})
+
+await suppress(import("gi://AstalBluetooth"), ({ Adapter, Bluetooth, Device }) => {
+ patch(Adapter.prototype, "uuids")
+ patch(Bluetooth.prototype, "adapters")
+ patch(Bluetooth.prototype, "devices")
+ patch(Device.prototype, "uuids")
+})
+
+await suppress(import("gi://AstalHyprland"), ({ Hyprland, Monitor, Workspace }) => {
+ patch(Hyprland.prototype, "monitors")
+ patch(Hyprland.prototype, "workspaces")
+ patch(Hyprland.prototype, "clients")
+ patch(Monitor.prototype, "availableModes")
+ patch(Monitor.prototype, "available_modes")
+ patch(Workspace.prototype, "clients")
+})
+
+await suppress(import("gi://AstalMpris"), ({ Mpris, Player }) => {
+ patch(Mpris.prototype, "players")
+ patch(Player.prototype, "supported_uri_schemas")
+ patch(Player.prototype, "supportedUriSchemas")
+ patch(Player.prototype, "supported_mime_types")
+ patch(Player.prototype, "supportedMimeTypes")
+ patch(Player.prototype, "comments")
+})
+
+await suppress(import("gi://AstalNetwork"), ({ Wifi }) => {
+ patch(Wifi.prototype, "access_points")
+ patch(Wifi.prototype, "accessPoints")
+})
+
+await suppress(import("gi://AstalNotifd"), ({ Notifd, Notification }) => {
+ patch(Notifd.prototype, "notifications")
+ patch(Notification.prototype, "actions")
+})
+
+await suppress(import("gi://AstalPowerProfiles"), ({ PowerProfiles }) => {
+ patch(PowerProfiles.prototype, "actions")
+})
diff --git a/lang/gjs/tsconfig.json b/lang/gjs/tsconfig.json
index 4e57e37..7a3a8c8 100644
--- a/lang/gjs/tsconfig.json
+++ b/lang/gjs/tsconfig.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"experimentalDecorators": true,
+ "module": "ES2022",
"target": "ES2023",
"outDir": "dist",
"strict": true,
diff --git a/lang/lua/astal-dev-1.rockspec b/lang/lua/astal-dev-1.rockspec
index 3970672..d8ee9be 100644
--- a/lang/lua/astal-dev-1.rockspec
+++ b/lang/lua/astal-dev-1.rockspec
@@ -8,7 +8,7 @@ source = {
description = {
summary = "lua bindings for libastal.",
homepage = "https://aylur.github.io/astal/",
- license = "GPL-3",
+ license = "LGPL-2.1",
}
dependencies = {
diff --git a/lang/lua/astal/binding.lua b/lang/lua/astal/binding.lua
index 2944ec4..dd2df7f 100644
--- a/lang/lua/astal/binding.lua
+++ b/lang/lua/astal/binding.lua
@@ -2,12 +2,14 @@ local lgi = require("lgi")
local GObject = lgi.require("GObject", "2.0")
---@class Binding
----@field emitter table|Variable
+---@field emitter table | Variable | userdata
---@field property? string
---@field transform_fn function
+---@overload fun(emitter: table | userdata, property?: string): Binding
local Binding = {}
+Binding.__index = Binding
----@param emitter table
+---@param emitter table | Variable | userdata
---@param property? string
---@return Binding
function Binding.new(emitter, property)
@@ -28,14 +30,15 @@ function Binding:__tostring()
return str .. ">"
end
+---@return any
function Binding:get()
if self.property ~= nil and GObject.Object:is_type_of(self.emitter) then
return self.transform_fn(self.emitter[self.property])
- end
- if type(self.emitter.get) == "function" then
+ elseif type(self.emitter.get) == "function" then
return self.transform_fn(self.emitter:get())
+ else
+ error("can not get: Not a GObject or a Variable " + self)
end
- error("can not get: Not a GObject or a Variable " + self)
end
---@param transform fun(value: any): any
@@ -58,14 +61,17 @@ function Binding:subscribe(callback)
return function()
GObject.signal_handler_disconnect(self.emitter, id)
end
- end
- if type(self.emitter.subscribe) == "function" then
+ elseif type(self.emitter.subscribe) == "function" then
return self.emitter:subscribe(function()
callback(self:get())
end)
+ else
+ error("can not subscribe: Not a GObject or a Variable " + self)
end
- error("can not subscribe: Not a GObject or a Variable " + self)
end
-Binding.__index = Binding
-return Binding
+return setmetatable(Binding, {
+ __call = function(_, emitter, prop)
+ return Binding.new(emitter, prop)
+ end,
+})
diff --git a/lang/lua/astal/gtk3/app.lua b/lang/lua/astal/gtk3/app.lua
index 7895f69..58564ce 100644
--- a/lang/lua/astal/gtk3/app.lua
+++ b/lang/lua/astal/gtk3/app.lua
@@ -25,29 +25,26 @@ end
local app = AstalLua()
---@class StartConfig
----@field icons? string
----@field instance_name? string
----@field gtk_theme? string
----@field icon_theme? string
----@field cursor_theme? string
----@field css? string
----@field hold? boolean
----@field request_handler? fun(msg: string, response: fun(res: any))
----@field main? fun(...): unknown
----@field client? fun(message: fun(msg: string): string, ...): unknown
+---@field icons string?
+---@field instance_name string?
+---@field gtk_theme string?
+---@field icon_theme string?
+---@field cursor_theme string?
+---@field css string?
+---@field hold boolean?
+---@field request_handler fun(msg: string, response: fun(res: any)): nil
+---@field main fun(...): nil
+---@field client fun(message: fun(msg: string): string, ...): nil
----@param config StartConfig | nil
+---@param config? StartConfig
function Astal.Application:start(config)
- if config == nil then
- config = {}
- end
+ config = config or {}
- if config.client == nil then
- config.client = function()
+ config.client = config.client
+ or function()
print('Astal instance "' .. app.instance_name .. '" is already running')
os.exit(1)
end
- end
if config.hold == nil then
config.hold = true
@@ -61,17 +58,11 @@ function Astal.Application:start(config)
if config.icons then
self:add_icons(config.icons)
end
- if config.instance_name then
- self.instance_name = config.instance_name
- end
- if config.gtk_theme then
- self.gtk_theme = config.gtk_theme
- end
- if config.icon_theme then
- self.icon_theme = config.icon_theme
- end
- if config.cursor_theme then
- self.cursor_theme = config.cursor_theme
+
+ for _, key in ipairs({ "instance_name", "gtk_theme", "icon_theme", "cursor_theme" }) do
+ if config[key] then
+ self[key] = config[key]
+ end
end
app.on_activate = function()
diff --git a/lang/lua/astal/gtk3/astalify.lua b/lang/lua/astal/gtk3/astalify.lua
index 211a1d4..95faa2c 100644
--- a/lang/lua/astal/gtk3/astalify.lua
+++ b/lang/lua/astal/gtk3/astalify.lua
@@ -163,9 +163,7 @@ return function(ctor)
end
return function(tbl)
- if tbl == nil then
- tbl = {}
- end
+ tbl = tbl or {}
local bindings = {}
local setup = tbl.setup
diff --git a/lang/lua/astal/gtk3/widget.lua b/lang/lua/astal/gtk3/widget.lua
index beaad6c..c8857e7 100644
--- a/lang/lua/astal/gtk3/widget.lua
+++ b/lang/lua/astal/gtk3/widget.lua
@@ -3,6 +3,7 @@ local Astal = lgi.require("Astal", "3.0")
local Gtk = lgi.require("Gtk", "3.0")
local astalify = require("astal.gtk3.astalify")
+---@overload fun(ctor: any): function
local Widget = {
astalify = astalify,
Box = astalify(Astal.Box),
diff --git a/lang/lua/astal/init.lua b/lang/lua/astal/init.lua
index 5630ba4..190994a 100644
--- a/lang/lua/astal/init.lua
+++ b/lang/lua/astal/init.lua
@@ -7,6 +7,7 @@ local Binding = require("astal.binding")
local File = require("astal.file")
local Process = require("astal.process")
local Time = require("astal.time")
+---@type Variable | fun(v: any): Variable
local Variable = require("astal.variable")
return {
diff --git a/lang/lua/astal/variable.lua b/lang/lua/astal/variable.lua
index 2305a71..ad59a3f 100644
--- a/lang/lua/astal/variable.lua
+++ b/lang/lua/astal/variable.lua
@@ -17,6 +17,7 @@ local Process = require("astal.process")
---@field private poll_fn? function
---@field private watch_transform? fun(next: any, prev: any): any
---@field private watch_exec? string[] | string
+---@overload fun(transform?: fun(v: any): any): Binding
local Variable = {}
Variable.__index = Variable
@@ -24,23 +25,23 @@ Variable.__index = Variable
---@return Variable
function Variable.new(value)
local v = Astal.VariableBase()
- local variable = setmetatable({
- variable = v,
- _value = value,
- }, Variable)
+ local variable = setmetatable({ variable = v, _value = value }, Variable)
+
v.on_dropped = function()
variable:stop_watch()
variable:stop_poll()
end
+
v.on_error = function(_, err)
if variable.err_handler then
variable.err_handler(err)
end
end
+
return variable
end
----@param transform? fun(v: any): any
+---@param transform? fun(v: any): any
---@return Binding
function Variable:__call(transform)
if type(transform) == "nil" then
@@ -54,10 +55,13 @@ function Variable:__tostring()
return "Variable<" .. tostring(self:get()) .. ">"
end
+---@return any
function Variable:get()
return self._value
end
+---@param value any
+---@return nil
function Variable:set(value)
if value ~= self:get() then
self._value = value
@@ -107,7 +111,6 @@ function Variable:start_watch()
end)
end
-
function Variable:stop_poll()
if self:is_polling() then
self._poll.cancel()
@@ -122,7 +125,6 @@ function Variable:stop_watch()
self._watch = nil
end
-
function Variable:drop()
self.variable.emit_dropped()
end
@@ -180,8 +182,9 @@ end
---@param exec string | string[]
---@param transform? fun(next: any, prev: any): any
+---@return Variable
function Variable:watch(exec, transform)
- transform = transform or function (next)
+ transform = transform or function(next)
return next
end
@@ -240,7 +243,7 @@ function Variable.derive(deps, transform)
for i, var in ipairs(deps) do
if getmetatable(var) == Variable then
- deps[i] = Binding.new(var)
+ deps[i] = var()
end
end
@@ -249,7 +252,7 @@ function Variable.derive(deps, transform)
for i, binding in ipairs(deps) do
params[i] = binding:get()
end
- return transform(table.unpack(params), 1, #deps)
+ return transform(table.unpack(params, 1, #deps))
end
local var = Variable.new(update())
@@ -272,4 +275,4 @@ return setmetatable(Variable, {
__call = function(_, v)
return Variable.new(v)
end,
-}) \ No newline at end of file
+})