diff --git a/src/ags.src.gresource.xml b/src/ags.src.gresource.xml
index 4e16607..4064319 100644
--- a/src/ags.src.gresource.xml
+++ b/src/ags.src.gresource.xml
@@ -6,6 +6,7 @@
client.js
utils.js
widget.js
+ service.js
widgets/overrides.js
widgets/box.js
@@ -26,7 +27,7 @@
widgets/window.js
service/service.js
- service/apps.js
+ service/applications.js
service/audio.js
service/battery.js
service/bluetooth.js
diff --git a/src/main.ts b/src/main.ts
index c9d8664..42edd9f 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,16 +3,8 @@ import GLib from 'gi://GLib';
import * as Utils from './utils.js';
import App from './app.js';
import client from './client.js';
-import Service from './service/service.js';
+import Service from './service.js';
import Widget from './widget.js';
-import './service/apps.js';
-import './service/audio.js';
-import './service/battery.js';
-import './service/bluetooth.js';
-import './service/hyprland.js';
-import './service/mpris.js';
-import './service/network.js';
-import './service/notifications.js';
const APP_BUS = (name: string) => 'com.github.Aylur.ags.' + name;
const APP_PATH = (name: string) => '/com/github/Aylur/ags/' + name;
@@ -23,23 +15,14 @@ const help = (bin: string) => `USAGE:
OPTIONS:
-h, --help Print this help and exit
-
-v, --version Print version and exit
-
-q, --quit Kill AGS
-
-c, --config Path to the config file. Default: ${DEFAULT_CONF}
-
-b, --bus-name Bus name of the process
-
-i, --inspector Open up the Gtk debug tool
-
-t, --toggle-window Show or hide a window
-
-r, --run-js Evaluate given string as a function and execute it
-
-p, --run-promise Evaluate and execute function as Promise
-
--clear-cache Remove ${Utils.CACHE_DIR}
EXAMPLES
@@ -56,7 +39,7 @@ function isRunning(dbusName: string) {
'/org/freedesktop/DBus',
'org.freedesktop.DBus',
'NameHasOwner',
- // @ts-ignore
+ // @ts-expect-error
GLib.Variant.new_tuple([new GLib.Variant('s', dbusName)]),
new GLib.VariantType('(b)'),
Gio.DBusCallFlags.NONE,
@@ -141,7 +124,7 @@ export function main(args: string[]) {
}
}
- // @ts-ignore
+ // @ts-expect-error
globalThis.ags = {
App,
Utils,
@@ -168,7 +151,7 @@ export function main(args: string[]) {
app.Inspector();
});
- // @ts-ignore
+ // @ts-expect-error
return app.runAsync(null);
}
else {
diff --git a/src/service.ts b/src/service.ts
new file mode 100644
index 0000000..23b4d3f
--- /dev/null
+++ b/src/service.ts
@@ -0,0 +1,34 @@
+// @ts-nocheck
+import Service from './service/service.js';
+import Applications from './service/applications.js';
+import Audio from './service/audio.js';
+import Battery from './service/battery.js';
+import Bluetooth from './service/bluetooth.js';
+import Hyprland from './service/hyprland.js';
+import Mpris from './service/mpris.js';
+import Network from './service/network.js';
+import Notifications from './service/notifications.js';
+
+export {
+ Applications,
+ Audio,
+ Battery,
+ Bluetooth,
+ Hyprland,
+ Mpris,
+ Network,
+ Notifications,
+ Service,
+};
+
+Service.Applications = Applications;
+Service.Audio = Audio;
+Service.Battery = Battery;
+Service.Bluetooth = Bluetooth;
+Service.Hyprland = Hyprland;
+Service.Mpris = Mpris;
+Service.Network = Network;
+Service.Notifications = Notifications;
+Service.Service = Service;
+
+export default Service;
diff --git a/src/service/apps.ts b/src/service/applications.ts
similarity index 97%
rename from src/service/apps.ts
rename to src/service/applications.ts
index 6466cf6..fea761c 100644
--- a/src/service/apps.ts
+++ b/src/service/applications.ts
@@ -37,11 +37,11 @@ class Application extends Service {
if (!app.get_icon())
return '';
- // @ts-ignore
+ // @ts-expect-error
if (typeof app.get_icon()?.get_names !== 'function')
return '';
- // @ts-ignore
+ // @ts-expect-error
const name = app.get_icon()?.get_names()[0];
return name || '';
}
@@ -130,7 +130,6 @@ class ApplicationsService extends Service {
}
export default class Applications {
- static { Service.export(this, 'Applications'); }
static _instance: ApplicationsService;
static get instance() {
diff --git a/src/service/audio.ts b/src/service/audio.ts
index 355d8aa..05964a7 100644
--- a/src/service/audio.ts
+++ b/src/service/audio.ts
@@ -3,11 +3,11 @@ import GObject from 'gi://GObject';
import Gvc from 'gi://Gvc';
import { bulkConnect, bulkDisconnect } from '../utils.js';
-class Stream extends GObject.Object {
+class Stream extends Service {
static {
- GObject.registerClass({
- Signals: { 'changed': {}, 'closed': {} },
- }, this);
+ Service.register(this, {
+ 'closed': [],
+ });
}
private _stream: Gvc.MixerStream;
@@ -156,7 +156,6 @@ class AudioService extends Service {
}
export default class Audio {
- static { Service.export(this, 'Audio'); }
static _instance: AudioService;
static get instance() {
diff --git a/src/service/battery.ts b/src/service/battery.ts
index 3f88bf2..60aacc9 100644
--- a/src/service/battery.ts
+++ b/src/service/battery.ts
@@ -64,7 +64,6 @@ class BatteryService extends Service {
}
export default class Battery {
- static { Service.export(this, 'Battery'); }
static _instance: BatteryService;
static get instance() {
diff --git a/src/service/bluetooth.ts b/src/service/bluetooth.ts
index bc5737d..da56f53 100644
--- a/src/service/bluetooth.ts
+++ b/src/service/bluetooth.ts
@@ -62,7 +62,7 @@ class Device extends GObject.Object {
class BluetoothService extends Service {
static { Service.register(this); }
- // @ts-ignore
+ // @ts-expect-error
private _client: GnomeBluetooth.Client;
private _devices: Map;
@@ -163,7 +163,6 @@ class BluetoothService extends Service {
}
export default class Bluetooth {
- static { Service.export(this, 'Bluetooth'); }
static _instance: BluetoothService;
static get instance() {
diff --git a/src/service/hyprland.ts b/src/service/hyprland.ts
index 380fbde..b02f374 100644
--- a/src/service/hyprland.ts
+++ b/src/service/hyprland.ts
@@ -202,7 +202,7 @@ class HyprlandService extends Service {
case 'changefloating': {
const client = this._clients.get(argv[0]);
if (client)
- // @ts-ignore
+ // @ts-expect-error
client.floating = argv[1] === '1';
break;
}
@@ -222,7 +222,6 @@ class HyprlandService extends Service {
}
export default class Hyprland {
- static { Service.export(this, 'Hyprland'); }
static _instance: HyprlandService;
static get instance() {
diff --git a/src/service/mpris.ts b/src/service/mpris.ts
index eb57bf8..9eafd5b 100644
--- a/src/service/mpris.ts
+++ b/src/service/mpris.ts
@@ -168,11 +168,8 @@ class MprisPlayer extends GObject.Object {
Gio.File.new_for_path(coverPath),
Gio.FileCopyFlags.OVERWRITE,
GLib.PRIORITY_DEFAULT,
- null,
- // @ts-ignore
- null,
- // @ts-ignore
- (source, result) => {
+ // @ts-expect-error
+ null, null, (source, result) => {
try {
source.copy_finish(result);
this.emit('changed');
@@ -314,7 +311,6 @@ class MprisService extends Service {
getPlayer(name: string | ((players: Players) => MprisPlayer) = '') {
if (typeof name === 'function')
- // @ts-ignore
return name(new Map(this._players)) || null;
for (const [busName, player] of this._players) {
@@ -326,7 +322,6 @@ class MprisService extends Service {
}
export default class Mpris {
- static { Service.export(this, 'Mpris'); }
static _instance: MprisService;
static get instance() {
diff --git a/src/service/network.ts b/src/service/network.ts
index 7aad3f9..a0186ec 100644
--- a/src/service/network.ts
+++ b/src/service/network.ts
@@ -237,7 +237,6 @@ class NetworkService extends Service {
}
export default class Network {
- static { Service.export(this, 'Network'); }
static _instance: NetworkService;
static get instance() {
diff --git a/src/service/notifications.ts b/src/service/notifications.ts
index 1e20be2..6216245 100644
--- a/src/service/notifications.ts
+++ b/src/service/notifications.ts
@@ -260,7 +260,6 @@ class NotificationsService extends Service {
}
export default class Notifications {
- static { Service.export(this, 'Notifications'); }
static _instance: NotificationsService;
static get instance() {
diff --git a/src/service/service.ts b/src/service/service.ts
index bbb66df..61cd07e 100644
--- a/src/service/service.ts
+++ b/src/service/service.ts
@@ -6,6 +6,7 @@ import { type Ctor } from 'gi-types/gobject2.js';
export default class Service extends GObject.Object {
static {
GObject.registerClass({
+ GTypeName: 'AgsService',
Signals: { 'changed': {} },
}, this);
}
@@ -24,7 +25,7 @@ export default class Service extends GObject.Object {
Object.keys(signals).forEach(signal =>
Signals[signal] = {
param_types: signals[signal].map(t =>
- // @ts-ignore
+ // @ts-expect-error
GObject[`TYPE_${t.toUpperCase()}`]),
},
);
@@ -34,8 +35,11 @@ export default class Service extends GObject.Object {
}
static export(api: { instance: object }, name: string) {
- // @ts-ignore
+ // @ts-expect-error
Service[name] = api;
+ console.error('Service.register is DEPRECATED.\n' +
+ "Simply do Service['YourService'] = YourService\n" +
+ 'or just export and import your YourService');
}
connectWidget(
@@ -46,3 +50,4 @@ export default class Service extends GObject.Object {
connect(this, widget, callback, event);
}
}
+
diff --git a/src/utils.ts b/src/utils.ts
index d0e2d59..2a97ea0 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -97,8 +97,18 @@ export function connect(
const bind = service.connect(
event, (_s, ...args: unknown[]) => callback(widget, ...args));
- widget.connect('destroy', () => service.disconnect(bind));
- timeout(10, () => callback(widget));
+ widget.connect('destroy', () => {
+ // @ts-expect-error
+ widget._destroyed = true;
+ service.disconnect(bind);
+ });
+ GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
+ // @ts-expect-error
+ if (!widget._destroyed)
+ callback(widget);
+
+ return GLib.SOURCE_REMOVE;
+ });
}
export function interval(
diff --git a/src/widget.ts b/src/widget.ts
index f743212..10f7076 100644
--- a/src/widget.ts
+++ b/src/widget.ts
@@ -21,7 +21,7 @@ export default function Widget({ type, ...params }: { type: ctor }) {
return constructor(type, params);
}
-// @ts-ignore
+// @ts-expect-error
export const Window = (args: object) => constructor(AgsWindow, args);
export const Box = (args: object) => constructor(AgsBox, args);
export const Button = (args: object) => constructor(AgsButton, args);
diff --git a/src/widgets/label.ts b/src/widgets/label.ts
index f6c530c..b3dbc64 100644
--- a/src/widgets/label.ts
+++ b/src/widgets/label.ts
@@ -38,7 +38,7 @@ export default class AgsLabel extends Gtk.Label {
return;
}
- // @ts-ignore
+ // @ts-expect-error
this.ellipsize = Pango.EllipsizeMode[truncate.toUpperCase()];
}
@@ -52,7 +52,7 @@ export default class AgsLabel extends Gtk.Label {
return;
}
- // @ts-ignore
+ // @ts-expect-error
this.justify = Gtk.Justification[justify.toUpperCase()];
}
}
diff --git a/src/widgets/overrides.ts b/src/widgets/overrides.ts
index 62943e8..af78953 100644
--- a/src/widgets/overrides.ts
+++ b/src/widgets/overrides.ts
@@ -66,12 +66,12 @@ Object.defineProperty(Gtk.Widget.prototype, 'style', {
},
});
-// @ts-ignore
+// @ts-expect-error
Gtk.Widget.prototype.setStyle = function(css: string) {
setStyle(this, css);
};
-// @ts-ignore
+// @ts-expect-error
Gtk.Widget.prototype.toggleClassName = function(cn: string, condition = true) {
toggleClassName(this, cn, condition);
};
diff --git a/src/widgets/revealer.ts b/src/widgets/revealer.ts
index 21fa6e9..6ab3baf 100644
--- a/src/widgets/revealer.ts
+++ b/src/widgets/revealer.ts
@@ -31,8 +31,7 @@ export default class AgsRevealer extends Gtk.Revealer {
return;
}
- this.transitionType =
- // @ts-ignore
- Gtk.RevealerTransitionType[transition.toUpperCase()];
+ // @ts-expect-error
+ this.transitionType = Gtk.RevealerTransitionType[transition.toUpperCase()];
}
}
diff --git a/src/widgets/scrollable.ts b/src/widgets/scrollable.ts
index ab8abb1..310813e 100644
--- a/src/widgets/scrollable.ts
+++ b/src/widgets/scrollable.ts
@@ -62,9 +62,9 @@ export default class AgsScrollable extends Gtk.ScrolledWindow {
policy() {
this.set_policy(
- // @ts-ignore
+ // @ts-expect-error
Gtk.PolicyType[this._hscroll?.toUpperCase() || 'AUTOMATIC'],
- // @ts-ignore
+ // @ts-expect-error
Gtk.PolicyType[this._vscroll?.toUpperCase() || 'AUTOMATIC'],
);
}
diff --git a/src/widgets/shared.ts b/src/widgets/shared.ts
index ebbde63..34dccff 100644
--- a/src/widgets/shared.ts
+++ b/src/widgets/shared.ts
@@ -1,16 +1,18 @@
import Gtk from 'gi://Gtk?version=3.0';
-import { interval } from '../utils.js';
+import GObject from 'gi://GObject';
+import { connect, interval } from '../utils.js';
export type Command = string | ((...args: unknown[]) => boolean);
-interface ServiceAPI {
- instance: {
- connectWidget: (
- widget: Gtk.Widget,
- callback: (widget: Gtk.Widget, ...args: unknown[]) => void,
- event?: string
- ) => void
- }
+type ConnectWidget = (
+ widget: Gtk.Widget,
+ callback: (widget: Gtk.Widget, ...args: unknown[]) => void,
+ event?: string
+) => void
+
+interface Connectable extends GObject.Object {
+ instance: { connectWidget: ConnectWidget }
+ connectWidget: ConnectWidget
}
interface CommonParams {
@@ -21,7 +23,7 @@ interface CommonParams {
connections?: (
[string, (...args: unknown[]) => unknown] |
[number, (...args: unknown[]) => unknown] |
- [ServiceAPI, (...args: unknown[]) => unknown, string]
+ [Connectable, (...args: unknown[]) => unknown, string]
)[]
properties?: [string, unknown][]
setup?: (widget: Gtk.Widget) => void
@@ -43,16 +45,16 @@ function parseCommon(widget: Gtk.Widget, {
connections, properties, setup,
}: CommonParams) {
if (className !== undefined)
- // @ts-ignore
+ // @ts-expect-error
widget.className = className;
if (style !== undefined)
- // @ts-ignore
+ // @ts-expect-error
widget.style = style;
if (typeof halign === 'string') {
- // @ts-ignore
+ // @ts-expect-error
const align = Gtk.Align[halign.toUpperCase()];
if (typeof align !== 'number')
console.error('wrong halign value');
@@ -64,7 +66,7 @@ function parseCommon(widget: Gtk.Widget, {
widget.halign = halign;
if (typeof valign === 'string') {
- // @ts-ignore
+ // @ts-expect-error
const align = Gtk.Align[valign.toUpperCase()];
if (typeof align !== 'number')
console.error('wrong valign value');
@@ -77,7 +79,7 @@ function parseCommon(widget: Gtk.Widget, {
if (properties) {
properties.forEach(([key, value]) => {
- // @ts-ignore
+ // @ts-expect-error
widget[`_${key}`] = value;
});
}
@@ -93,8 +95,14 @@ function parseCommon(widget: Gtk.Widget, {
else if (typeof s?.instance?.connectWidget === 'function')
s.instance.connectWidget(widget, callback, event);
+ else if (typeof s?.connectWidget === 'function')
+ s.connectWidget(widget, callback, event);
+
+ else if (typeof s?.connect === 'function')
+ connect(s, widget, callback, event);
+
else
- logError(new Error(`${s} is not an instanceof Service`));
+ logError(new Error(`${s} is not connectable`));
});
}
diff --git a/src/widgets/stack.ts b/src/widgets/stack.ts
index eeb590c..d41b3a6 100644
--- a/src/widgets/stack.ts
+++ b/src/widgets/stack.ts
@@ -74,7 +74,7 @@ export default class AgsStack extends Gtk.Stack {
return;
}
- // @ts-ignore
+ // @ts-expect-error
this.transitionType = Gtk.StackTransitionType[transition.toUpperCase()];
}
diff --git a/src/widgets/window.ts b/src/widgets/window.ts
index 521ba96..b90efd5 100644
--- a/src/widgets/window.ts
+++ b/src/widgets/window.ts
@@ -115,10 +115,10 @@ export default class AgsWindow extends Gtk.Window {
_margin: number[] | number = [0];
- // @ts-ignore
+ // @ts-expect-error
get margin() { return this._margin; }
- // @ts-ignore
+ // @ts-expect-error
set margin(margin: number[] | number) {
let margins: [side: string, index: number][] = [];
if (typeof margin === 'number')