From 3023967ca8717db819aba5ed5c2e17ee606b5190 Mon Sep 17 00:00:00 2001 From: Aylur Date: Tue, 29 Aug 2023 17:52:02 +0200 Subject: [PATCH] update eslintrc * re enable typescript eslint rules * increase max-len from 80 to 100 * use private keyword alongside the underscore gjs notation --- .eslintrc.yml | 56 ++++++++++++------------------- src/app.ts | 7 ++-- src/dbus/types.ts | 9 ++--- src/service/apps.ts | 32 +++++++++--------- src/service/audio.ts | 64 +++++++++++++++++------------------- src/service/battery.ts | 51 ++++++++++------------------ src/service/bluetooth.ts | 26 +++++++-------- src/service/hyprland.ts | 55 ++++++++++++++++++------------- src/service/mpris.ts | 24 +++++++------- src/service/network.ts | 20 +++++------ src/service/notifications.ts | 28 ++++++++-------- src/service/service.ts | 12 ++++--- src/utils.ts | 7 ++-- src/widgets/icon.ts | 3 +- src/widgets/menu.ts | 8 ++++- src/widgets/overlay.ts | 16 ++++++++- src/widgets/shared.ts | 13 ++++---- src/widgets/slider.ts | 12 +++++-- src/widgets/stack.ts | 6 +++- src/widgets/window.ts | 13 +++++++- 20 files changed, 244 insertions(+), 218 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 328cdb4..63295a2 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -20,30 +20,8 @@ ignorePatterns: plugins: - '@typescript-eslint' rules: - '@typescript-eslint/no-unused-vars': - - 'warn' - '@typescript-eslint/restrict-template-expressions': - - 'off' - '@typescript-eslint/no-explicit-any': - - 'off' - '@typescript-eslint/no-implied-eval': - - 'off' - '@typescript-eslint/no-unsafe-assignment': - - 'off' - '@typescript-eslint/no-unsafe-member-access': - - 'off' - '@typescript-eslint/no-unsafe-call': - - 'off' - '@typescript-eslint/no-floating-promises': - - 'off' - '@typescript-eslint/no-misused-promises': - - 'off' '@typescript-eslint/ban-ts-comment': - 'off' - '@typescript-eslint/no-empty-function': - - 'off' - '@typescript-eslint/no-misused-new': - - 'off' arrow-parens: - error - as-needed @@ -64,7 +42,8 @@ rules: dot-location: - error - property - eol-last: error + eol-last: + - error indent: - error - 4 @@ -80,7 +59,8 @@ rules: - error - never - allowSingleLineBlocks: false - prefer-const: error + prefer-const: + - error quotes: - error - single @@ -93,21 +73,27 @@ rules: - below no-trailing-spaces: - error - array-bracket-spacing: - - error - - never - key-spacing: - - error - - beforeColon: false - afterColon: true - object-curly-spacing: - - error - - always no-useless-escape: - off max-len: - error - - code: 80 + - code: 100 + + func-call-spacing: + - error + array-bracket-spacing: + - error + space-before-function-paren: + - error + - never + space-before-blocks: + - error + key-spacing: + - error + object-curly-spacing: + - error + - always + globals: pkg: readonly ARGV: readonly diff --git a/src/app.ts b/src/app.ts index 40d838b..2e3500c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -96,6 +96,7 @@ export default class App extends Gtk.Application { connectWidget( widget: Gtk.Widget, + // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (widget: Gtk.Widget, ...args: any[]) => void, event = 'window-toggled', ) { @@ -169,7 +170,7 @@ export default class App extends Gtk.Application { this._windows.set(w.name, w); } - async _load() { + private async _load() { try { const mod = await import(`file://${App.configPath}`); const config = mod.default as Config; @@ -201,7 +202,7 @@ export default class App extends Gtk.Application { } } - _addAction( + private _addAction( name: string, callback: (_source: Gio.SimpleAction, _param: GLib.Variant) => void, parameter_type?: GLib.VariantType, @@ -213,7 +214,7 @@ export default class App extends Gtk.Application { this.add_action(action); } - _exportActions() { + private _exportActions() { this._addAction('inspector', () => Gtk.Window.set_interactive_debugging(true)); this._addAction('quit', App.quit); diff --git a/src/dbus/types.ts b/src/dbus/types.ts index d321c32..fa94d30 100644 --- a/src/dbus/types.ts +++ b/src/dbus/types.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-misused-new */ import GLib from 'gi://GLib'; interface Proxy { @@ -7,7 +8,7 @@ interface Proxy { } export interface DBusProxy extends Proxy { - new(...args: any[]): DBusProxy + new(...args: unknown[]): DBusProxy ListNamesRemote: (callback: (names: string[][]) => void) => void connectSignal: ( event: string, @@ -19,7 +20,7 @@ export interface DBusProxy extends Proxy { } export interface PlayerProxy extends Proxy { - new(...args: any[]): PlayerProxy + new(...args: unknown[]): PlayerProxy CanControl: boolean CanGoNext: boolean CanGoPrevious: boolean @@ -40,7 +41,7 @@ export interface PlayerProxy extends Proxy { } export interface MprisProxy extends Proxy { - new(...args: any[]): MprisProxy + new(...args: unknown[]): MprisProxy Raise: () => void Quit: () => void CanQuit: boolean @@ -50,7 +51,7 @@ export interface MprisProxy extends Proxy { } export interface BatteryProxy extends Proxy { - new(...args: any[]): BatteryProxy + new(...args: unknown[]): BatteryProxy State: number Percentage: number IsPresent: boolean diff --git a/src/service/apps.ts b/src/service/apps.ts index f491b1a..6466cf6 100644 --- a/src/service/apps.ts +++ b/src/service/apps.ts @@ -1,13 +1,14 @@ import Gio from 'gi://Gio'; import Service from './service.js'; -import GObject from 'gi://GObject'; import { CACHE_DIR, ensureDirectory, readFile, writeFile } from '../utils.js'; const APPS_CACHE_DIR = `${CACHE_DIR}/apps`; const CACHE_FILE = APPS_CACHE_DIR + '/apps_frequency.json'; -class Application extends GObject.Object { - static { GObject.registerClass(this); } +class Application extends Service { + static { + Service.register(this, { 'launched': [] }); + } app: Gio.DesktopAppInfo; frequency: number; @@ -32,18 +33,20 @@ class Application extends GObject.Object { this.frequency = this.desktop && service.frequents[this.desktop] || 0; } - _iconName(app: any): string { + private _iconName(app: Gio.DesktopAppInfo): string { if (!app.get_icon()) return ''; + // @ts-ignore if (typeof app.get_icon()?.get_names !== 'function') return ''; + // @ts-ignore const name = app.get_icon()?.get_names()[0]; return name || ''; } - _match(prop: string | null, search: string) { + private _match(prop: string | null, search: string) { if (!prop) return false; @@ -63,8 +66,8 @@ class Application extends GObject.Object { launch() { this.frequency++; - this.service._launched(this.desktop); this.app.launch([], null); + this.emit('launched'); } } @@ -98,7 +101,7 @@ class ApplicationsService extends Service { this._sync(); } - _launched(id: string | null) { + private _launched(id: string | null) { if (!id) return; @@ -111,13 +114,17 @@ class ApplicationsService extends Service { writeFile(json, CACHE_FILE).catch(logError); } - _sync() { + private _sync() { this._list = Gio.AppInfo.get_all() .filter(app => app.should_show()) .map(app => Gio.DesktopAppInfo.new(app.get_id() || '')) .filter(app => app) .map(app => new Application(app, this)); + this._list.forEach(app => app.connect('launched', () => { + this._launched(app.desktop); + })); + this.emit('changed'); } } @@ -131,11 +138,6 @@ export default class Applications { return Applications._instance; } - static frequents() { - return Applications.instance.frequents; - } - - static query(term: string) { - return Applications.instance.query(term); - } + static frequents() { return Applications.instance.frequents; } + static query(term: string) { return Applications.instance.query(term); } } diff --git a/src/service/audio.ts b/src/service/audio.ts index 9831535..355d8aa 100644 --- a/src/service/audio.ts +++ b/src/service/audio.ts @@ -10,8 +10,10 @@ class Stream extends GObject.Object { }, this); } - _stream: Gvc.MixerStream; - _ids: number[]; + private _stream: Gvc.MixerStream; + private _ids: number[]; + + get stream() { return this._stream; } constructor(stream: Gvc.MixerStream) { super(); @@ -36,8 +38,11 @@ class Stream extends GObject.Object { get id() { return this._stream.id; } get name() { return this._stream.name; } + set isMuted(muted) { this._stream.set_is_muted(muted); } + get isMuted() { return this._stream.is_muted; } + get volume() { - const max = Audio._instance._control.get_vol_max_norm(); + const max = Audio.instance.control.get_vol_max_norm(); return this._stream.volume / max; } @@ -48,19 +53,11 @@ class Stream extends GObject.Object { if (value < 0) value = 0; - const max = Audio._instance._control.get_vol_max_norm(); + const max = Audio.instance.control.get_vol_max_norm(); this._stream.set_volume(value * max); this._stream.push_volume(); } - set isMuted(muted) { - this._stream.set_is_muted(muted); - } - - get isMuted() { - return this._stream.is_muted; - } - close() { bulkDisconnect((this._stream as unknown) as GObject.Object, this._ids); this.emit('closed'); @@ -75,12 +72,17 @@ class AudioService extends Service { }); } - _control: Gvc.MixerControl; - _streams: Map; - _speaker!: Stream; - _microphone!: Stream; - _speakerID!: number; - _microphoneID!: number; + private _control: Gvc.MixerControl; + private _streams: Map; + private _speaker!: Stream; + private _microphone!: Stream; + private _speakerID!: number; + private _microphoneID!: number; + + get speaker() { return this._speaker; } + get microphone() { return this._microphone; } + + get control() { return this._control; } constructor() { super(); @@ -90,10 +92,8 @@ class AudioService extends Service { this._streams = new Map(); bulkConnect((this._control as unknown) as GObject.Object, [ - ['default-sink-changed', (_c, id: number) => - this._defaultChanged(id, 'speaker')], - ['default-source-changed', (_c, id: number) => - this._defaultChanged(id, 'microphone')], + ['default-sink-changed', (_c, id: number) => this._defaultChanged(id, 'speaker')], + ['default-source-changed', (_c, id: number) => this._defaultChanged(id, 'microphone')], ['stream-added', this._streamAdded.bind(this)], ['stream-removed', this._streamRemoved.bind(this)], ]); @@ -101,7 +101,7 @@ class AudioService extends Service { this._control.open(); } - _defaultChanged(id: number, type: 'speaker' | 'microphone') { + private _defaultChanged(id: number, type: 'speaker' | 'microphone') { if (this[`_${type}`]) this[`_${type}`].disconnect(this[`_${type}ID`]); @@ -118,7 +118,7 @@ class AudioService extends Service { this.emit('changed'); } - _streamAdded(_c: Gvc.MixerControl, id: number) { + private _streamAdded(_c: Gvc.MixerControl, id: number) { if (this._streams.has(id)) return; @@ -128,7 +128,7 @@ class AudioService extends Service { this.emit('changed'); } - _streamRemoved(_c: Gvc.MixerControl, id: number) { + private _streamRemoved(_c: Gvc.MixerControl, id: number) { if (!this._streams.has(id)) return; @@ -137,21 +137,21 @@ class AudioService extends Service { this.emit('changed'); } - getStreams(filter: any) { + getStreams(filter: { new(): Gvc.MixerStream }) { const map = new Map(); for (const [id, stream] of this._streams) { - if (stream._stream instanceof filter) + if (stream.stream instanceof filter) map.set(id, stream); } return map; } setSpeaker(stream: Stream) { - this._control.set_default_sink(stream._stream); + this._control.set_default_sink(stream.stream); } setMicrophone(stream: Stream) { - this._control.set_default_source(stream._stream); + this._control.set_default_source(stream.stream); } } @@ -164,15 +164,13 @@ export default class Audio { return Audio._instance; } - // eslint-disable-next-line max-len static get microphones() { return Audio.instance.getStreams(Gvc.MixerSource); } static get apps() { return Audio.instance.getStreams(Gvc.MixerSinkInput); } static get speakers() { return Audio.instance.getStreams(Gvc.MixerSink); } - static get speaker() { return Audio.instance._speaker; } + static get speaker() { return Audio.instance.speaker; } static set speaker(stream: Stream) { Audio.instance.setSpeaker(stream); } - // eslint-disable-next-line max-len static set microphone(stream: Stream) { Audio.instance.setMicrophone(stream); } - static get microphone() { return Audio.instance._microphone; } + static get microphone() { return Audio.instance.microphone; } } diff --git a/src/service/battery.ts b/src/service/battery.ts index fb7707b..3f88bf2 100644 --- a/src/service/battery.ts +++ b/src/service/battery.ts @@ -13,31 +13,20 @@ const DeviceState = { FULLY_CHARGED: 4, }; -type BatteryState = { - available: boolean - percent: number - charging: boolean - charged: boolean - iconName: string -} - class BatteryService extends Service { static { Service.register(this); } - _state!: BatteryState; - _proxy: BatteryProxy; + available = false; + percent = -1; + charging = false; + charged = false; + iconName = 'battery-missing-symbolic'; + private _proxy: BatteryProxy; + constructor() { super(); - this._state = { - available: false, - percent: -1, - charging: false, - charged: false, - iconName: 'battery-missing-symbolic', - }; - this._proxy = new PowerManagerProxy( Gio.DBus.system, 'org.freedesktop.UPower', @@ -48,12 +37,11 @@ class BatteryService extends Service { timeout(100, this._sync.bind(this)); } - _sync() { + private _sync() { if (!this._proxy.IsPresent) return; const percent = this._proxy.Percentage; - const charging = this._proxy.State === DeviceState.CHARGING; const charged = this._proxy.State === DeviceState.FULLY_CHARGED || (this._proxy.State === DeviceState.CHARGING && percent === 100); @@ -62,17 +50,14 @@ class BatteryService extends Service { DeviceState.CHARGING ? '-charging' : ''; const level = Math.floor(percent / 10) * 10; - const iconName = charged + this.iconName = charged ? 'battery-level-100-charged-symbolic' : `battery-level-${level}${state}-symbolic`; - this._state = { - available: true, - percent, - charging, - charged, - iconName, - }; + this.charging = this._proxy.State === DeviceState.CHARGING; + this.percent = percent; + this.charged = charged; + this.available = true; this.emit('changed'); } @@ -87,9 +72,9 @@ export default class Battery { return Battery._instance; } - static get available() { return Battery.instance._state.available; } - static get percent() { return Battery.instance._state.percent; } - static get charging() { return Battery.instance._state.charging; } - static get charged() { return Battery.instance._state.charged; } - static get iconName() { return Battery.instance._state.iconName; } + static get available() { return Battery.instance.available; } + static get percent() { return Battery.instance.percent; } + static get charging() { return Battery.instance.charging; } + static get charged() { return Battery.instance.charged; } + static get iconName() { return Battery.instance.iconName; } } diff --git a/src/service/bluetooth.ts b/src/service/bluetooth.ts index 5b03a0f..bc5737d 100644 --- a/src/service/bluetooth.ts +++ b/src/service/bluetooth.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import GObject from 'gi://GObject'; import Service from './service.js'; import { bulkConnect, bulkDisconnect } from '../utils.js'; @@ -12,9 +13,10 @@ class Device extends GObject.Object { }, this); } - _device: any; - _ids: number[]; - _connecting = false; + private _device: any; + private _ids: number[]; + + get device() { return this._device; } constructor(device: any) { super(); @@ -51,12 +53,9 @@ class Device extends GObject.Object { get type() { return GnomeBluetooth.type_to_string(this._device.type); } setConnection(connect: boolean) { - this._connecting = true; Bluetooth.instance.connectDevice(this, connect, () => { - this._connecting = false; this.emit('changed'); }); - this.emit('changed'); } } @@ -64,15 +63,13 @@ class BluetoothService extends Service { static { Service.register(this); } // @ts-ignore - _client: GnomeBluetooth.Client; - _devices: Map; - _connections: Map; + private _client: GnomeBluetooth.Client; + private _devices: Map; constructor() { super(); this._devices = new Map(); - this._connections = new Map(); this._client = new GnomeBluetooth.Client(); bulkConnect(this._client, [ ['notify::default-adapter-state', () => this.emit('changed')], @@ -87,7 +84,7 @@ class BluetoothService extends Service { !this._client.default_adapter_powered; } - _getDevices() { + private _getDevices() { const devices = []; const deviceStore = this._client.get_devices(); @@ -101,7 +98,7 @@ class BluetoothService extends Service { return devices; } - _deviceAdded(_c: unknown, device: any) { + private _deviceAdded(_c: unknown, device: any) { if (this._devices.has(device.address)) return; @@ -111,7 +108,7 @@ class BluetoothService extends Service { this.emit('changed'); } - _deviceRemoved(_c: unknown, device: Device) { + private _deviceRemoved(_c: unknown, device: Device) { if (!this._devices.has(device.address)) return; @@ -126,7 +123,7 @@ class BluetoothService extends Service { callback: (s: boolean) => void, ) { this._client.connect_service( - device._device.get_object_path(), + device.device.get_object_path(), connect, null, (client: any, res: any) => { @@ -174,7 +171,6 @@ export default class Bluetooth { return Bluetooth._instance; } - // eslint-disable-next-line max-len static get connectedDevices() { return Bluetooth.instance.connectedDevices; } static get enabled() { return Bluetooth.instance.enabled; } static set enabled(enable: boolean) { Bluetooth.instance.enabled = enable; } diff --git a/src/service/hyprland.ts b/src/service/hyprland.ts index 9862bcb..380fbde 100644 --- a/src/service/hyprland.ts +++ b/src/service/hyprland.ts @@ -27,13 +27,16 @@ class HyprlandService extends Service { }); } - _active: Active; - _monitors: Map; - _workspaces: Map; - _clients: Map; + private _active: Active; + private _monitors: Map; + private _workspaces: Map; + private _clients: Map; + private _decoder = new TextDecoder(); - _decoder = new TextDecoder(); - _socketStream = new Gio.DataInputStream; + get active() { return this._active; } + get monitors() { return this._monitors; } + get workspaces() { return this._workspaces; } + get clients() { return this._clients; } constructor() { if (!HIS) @@ -59,7 +62,7 @@ class HyprlandService extends Service { this._syncWorkspaces(); this._syncClients(); - this.watchSocket(new Gio.DataInputStream({ + this._watchSocket(new Gio.DataInputStream({ close_base_stream: true, base_stream: new Gio.SocketClient() .connect(new Gio.UnixSocketAddress({ @@ -69,7 +72,7 @@ class HyprlandService extends Service { })); } - watchSocket(stream: Gio.DataInputStream) { + private _watchSocket(stream: Gio.DataInputStream) { stream.read_line_async( 0, null, (stream, result) => { @@ -80,17 +83,25 @@ class HyprlandService extends Service { const [line] = stream.read_line_finish(result); this._onEvent(this._decoder.decode(line)); - this.watchSocket(stream); + this._watchSocket(stream); }); } - async _syncMonitors() { + private async _syncMonitors() { try { const monitors = await execAsync('hyprctl -j monitors'); this._monitors = new Map(); - const json = JSON.parse(monitors) as { [key: string]: any }[]; + const json = JSON.parse(monitors) as { + id: number + name: string + focused: boolean + activeWorkspace: { + id: number + name: string + } + }[]; json.forEach(monitor => { - this._monitors.set(monitor.name, monitor); + this._monitors.set(monitor.id, monitor); if (monitor.focused) { this._active.monitor = monitor.name; this._active.workspace = monitor.activeWorkspace; @@ -101,11 +112,11 @@ class HyprlandService extends Service { } } - async _syncWorkspaces() { + private async _syncWorkspaces() { try { const workspaces = await execAsync('hyprctl -j workspaces'); this._workspaces = new Map(); - const json = JSON.parse(workspaces) as { [key: string]: any }[]; + const json = JSON.parse(workspaces) as { id: number }[]; json.forEach(ws => { this._workspaces.set(ws.id, ws); }); @@ -114,21 +125,21 @@ class HyprlandService extends Service { } } - async _syncClients() { + private async _syncClients() { try { const clients = await execAsync('hyprctl -j clients'); this._clients = new Map(); - const json = JSON.parse(clients) as { [key: string]: any }[]; + const json = JSON.parse(clients) as { address: string }[]; json.forEach(client => { this._clients.set( - (client.address as string).substring(2), client); + client.address.substring(2), client); }); } catch (error) { logError(error as Error); } } - async _onEvent(event: string) { + private async _onEvent(event: string) { if (!event) return; @@ -219,10 +230,10 @@ export default class Hyprland { return Hyprland._instance; } - static get active() { return Hyprland.instance._active; } - static get monitors() { return Hyprland.instance._monitors; } - static get workspaces() { return Hyprland.instance._workspaces; } - static get clients() { return Hyprland.instance._clients; } + static get active() { return Hyprland.instance.active; } + static get monitors() { return Hyprland.instance.monitors; } + static get workspaces() { return Hyprland.instance.workspaces; } + static get clients() { return Hyprland.instance.clients; } static HyprctlGet(cmd: string): unknown | object { const [success, out, err] = diff --git a/src/service/mpris.ts b/src/service/mpris.ts index 448ecc1..eb57bf8 100644 --- a/src/service/mpris.ts +++ b/src/service/mpris.ts @@ -56,9 +56,9 @@ class MprisPlayer extends GObject.Object { loopStatus!: LoopStatus | null; length!: number; - _binding: { mpris: number, player: number }; - _mprisProxy: MprisProxy; - _playerProxy: PlayerProxy; + private _binding: { mpris: number, player: number }; + private _mprisProxy: MprisProxy; + private _playerProxy: PlayerProxy; constructor(busName: string) { super(); @@ -87,7 +87,7 @@ class MprisPlayer extends GObject.Object { this.emit('closed'); } - _onMprisProxyReady() { + private _onMprisProxyReady() { this._binding.mpris = this._mprisProxy.connect( 'notify::g-name-owner', () => { @@ -101,14 +101,14 @@ class MprisPlayer extends GObject.Object { this.close(); } - _onPlayerProxyReady() { + private _onPlayerProxyReady() { this._binding.player = this._playerProxy.connect( 'g-properties-changed', () => this._updateState()); this._updateState(); } - _updateState() { + private _updateState() { const metadata = {} as MprisMetadata; for (const prop in this._playerProxy.Metadata) metadata[prop] = this._playerProxy.Metadata[prop].deep_unpack(); @@ -148,7 +148,7 @@ class MprisPlayer extends GObject.Object { this.emit('changed'); } - _cacheCoverArt() { + private _cacheCoverArt() { this.coverPath = MEDIA_CACHE_PATH + '/' + `${this.trackArtists.join(', ')}-${this.trackTitle}` .replace(/[\,\*\?\"\<\>\|\#\:\?\/\'\(\)]/g, ''); @@ -252,8 +252,8 @@ class MprisService extends Service { }); } - _players!: Players; - _proxy: DBusProxy; + private _players!: Players; + private _proxy: DBusProxy; constructor() { super(); @@ -266,7 +266,7 @@ class MprisService extends Service { this._onProxyReady(); } - _addPlayer(busName: string) { + private _addPlayer(busName: string) { if (this._players.get(busName)) return; @@ -287,7 +287,7 @@ class MprisService extends Service { this.emit('player-added', busName); } - _onProxyReady() { + private _onProxyReady() { this._proxy.ListNamesRemote(([names]) => { names.forEach(name => { if (!name.startsWith('org.mpris.MediaPlayer2.')) @@ -300,7 +300,7 @@ class MprisService extends Service { this._onNameOwnerChanged.bind(this)); } - _onNameOwnerChanged( + private _onNameOwnerChanged( _proxy: string, _sender: string, [name, oldOwner, newOwner]: string[], diff --git a/src/service/network.ts b/src/service/network.ts index 5d16ec0..7aad3f9 100644 --- a/src/service/network.ts +++ b/src/service/network.ts @@ -52,10 +52,10 @@ const _DEVICE = (device: string) => { class Wifi extends Service { static { Service.register(this); } - _client: NM.Client; - _device: NM.DeviceWifi; - _ap!: NM.AccessPoint; - _apBind!: number; + private _client: NM.Client; + private _device: NM.DeviceWifi; + private _ap!: NM.AccessPoint; + private _apBind!: number; constructor(client: NM.Client, device: NM.DeviceWifi) { super(); @@ -79,7 +79,7 @@ class Wifi extends Service { }); } - _activeAp() { + private _activeAp() { if (this._ap) this._ap.disconnect(this._apBind); @@ -150,7 +150,7 @@ class Wifi extends Service { class Wired extends Service { static { Service.register(this); } - _device: NM.DeviceEthernet; + private _device: NM.DeviceEthernet; constructor(device: NM.DeviceEthernet) { super(); @@ -177,7 +177,7 @@ class Wired extends Service { class NetworkService extends Service { static { Service.register(this); } - _client!: NM.Client; + private _client!: NM.Client; _wifi!: Wifi; _wired!: Wired; _primary?: string; @@ -200,13 +200,13 @@ class NetworkService extends Service { this._client.wireless_enabled = !this._client.wireless_enabled; } - _getDevice(devType: NM.DeviceType) { + private _getDevice(devType: NM.DeviceType) { return this._client .get_devices() .find(device => device.get_device_type() === devType); } - _clientReady() { + private _clientReady() { bulkConnect((this._client as unknown) as GObject.Object, [ ['notify::wireless-enabled', this._sync.bind(this)], ['notify::connectivity', this._sync.bind(this)], @@ -225,7 +225,7 @@ class NetworkService extends Service { this._sync(); } - _sync() { + private _sync() { const mainConnection = this._client.get_primary_connection() || this._client.get_activating_connection(); diff --git a/src/service/notifications.ts b/src/service/notifications.ts index 71892ab..1e20be2 100644 --- a/src/service/notifications.ts +++ b/src/service/notifications.ts @@ -50,11 +50,11 @@ class NotificationsService extends Service { }); } - _dbus!: Gio.DBusExportedObject; - _notifications: Map; - _dnd = false; - _idCount = 0; - _timeout = App.config?.notificationPopupTimeout || 3000; + private _dbus!: Gio.DBusExportedObject; + private _notifications: Map; + private _dnd = false; + private _idCount = 0; + private _timeout = App.config?.notificationPopupTimeout || 3000; constructor() { super(); @@ -64,15 +64,14 @@ class NotificationsService extends Service { this._register(); } - get dnd() { - return this._dnd; - } + get dnd() { return this._dnd; } set dnd(value: boolean) { this._dnd = value; this.emit('changed'); } + get notifications() { return this._notifications; } get popups() { const map: Map = new Map(); for (const [id, notification] of this._notifications) { @@ -179,7 +178,7 @@ class NotificationsService extends Service { ]); } - _register() { + private _register() { Gio.bus_own_name( Gio.BusType.SESSION, 'org.freedesktop.Notifications', @@ -199,7 +198,7 @@ class NotificationsService extends Service { ); } - async _readFromFile() { + private async _readFromFile() { try { const file = await readFileAsync(CACHE_FILE); const notifications = JSON.parse(file as string) as Notification[]; @@ -216,11 +215,11 @@ class NotificationsService extends Service { } } - _isFile(path: string) { + private _isFile(path: string) { return GLib.file_test(path, GLib.FileTest.EXISTS) ? path : null; } - _parseImage(id: number, image_data?: GLib.Variant<'(iiibiiay)'>) { + private _parseImage(id: number, image_data?: GLib.Variant<'(iiibiiay)'>) { if (!image_data) return null; @@ -247,7 +246,7 @@ class NotificationsService extends Service { return fileName; } - _cache() { + private _cache() { const notifications = []; for (const [, notification] of this._notifications) { const n = { ...notification, action: [], popup: false }; @@ -271,7 +270,6 @@ export default class Notifications { // eslint-disable-next-line max-len static invoke(id: number, actionId: string) { Notifications.instance.InvokeAction(id, actionId); } - // eslint-disable-next-line max-len static dismiss(id: number) { Notifications.instance.DismissNotification(id); } static clear() { Notifications.instance.Clear(); } static close(id: number) { Notifications.instance.CloseNotification(id); } @@ -279,5 +277,5 @@ export default class Notifications { static get dnd() { return Notifications.instance.dnd; } static set dnd(value: boolean) { Notifications.instance.dnd = value; } static get popups() { return Notifications.instance.popups; } - static get notifications() { return Notifications.instance._notifications; } + static get notifications() { return Notifications.instance.notifications; } } diff --git a/src/service/service.ts b/src/service/service.ts index d855da0..bbb66df 100644 --- a/src/service/service.ts +++ b/src/service/service.ts @@ -1,6 +1,7 @@ import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk?version=3.0'; import { connect } from '../utils.js'; +import { type Ctor } from 'gi-types/gobject2.js'; export default class Service extends GObject.Object { static { @@ -9,12 +10,12 @@ export default class Service extends GObject.Object { }, this); } - static ensureInstance(api: { _instance: any }, service: { new(): any }) { + static ensureInstance(api: { _instance: Service }, service: { new(): Service }) { if (!api._instance) api._instance = new service(); } - static register(service: any, signals?: { [signal: string]: string[] }) { + static register(service: Ctor, signals?: { [signal: string]: string[] }) { const Signals: { [signal: string]: { param_types: GObject.GType[] } } = {}; @@ -32,13 +33,14 @@ export default class Service extends GObject.Object { GObject.registerClass({ Signals }, service); } - static export(api: any, name: string) { - (Service as { [key: string]: any })[name] = api; + static export(api: { instance: object }, name: string) { + // @ts-ignore + Service[name] = api; } connectWidget( widget: Gtk.Widget, - callback: (widget: Gtk.Widget, ...args: any[]) => void, + callback: (widget: Gtk.Widget, ...args: unknown[]) => void, event = 'changed', ) { connect(this, widget, callback, event); diff --git a/src/utils.ts b/src/utils.ts index 70e2b2f..d0e2d59 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -72,6 +72,7 @@ export function bulkConnect( service: GObject.Object, list: [ event: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (...args: any[]) => void ][], ) { @@ -90,11 +91,11 @@ export function bulkDisconnect(service: GObject.Object, ids: number[]) { export function connect( service: GObject.Object, widget: Gtk.Widget, - callback: (widget: Gtk.Widget, ...args: any[]) => void, + callback: (widget: Gtk.Widget, ...args: unknown[]) => void, event = 'changed', ) { const bind = service.connect( - event, (_s, ...args: any[]) => callback(widget, ...args)); + event, (_s, ...args: unknown[]) => callback(widget, ...args)); widget.connect('destroy', () => service.disconnect(bind)); timeout(10, () => callback(widget)); @@ -124,7 +125,7 @@ export function timeout(ms: number, callback: () => void) { export function runCmd( cmd: Command, - ...args: any[] + ...args: unknown[] ) { if (typeof cmd !== 'string' && typeof cmd !== 'function') { console.error('Command has to be string or function'); diff --git a/src/widgets/icon.ts b/src/widgets/icon.ts index 56dba4a..e3a457b 100644 --- a/src/widgets/icon.ts +++ b/src/widgets/icon.ts @@ -2,6 +2,7 @@ import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk?version=3.0'; import GLib from 'gi://GLib'; import GdkPixbuf from 'gi://GdkPixbuf'; +import { Context } from 'gi-types/cairo1'; export default class AgsIcon extends Gtk.Image { static { @@ -68,7 +69,7 @@ export default class AgsIcon extends Gtk.Image { } } - vfunc_draw(cr: any): boolean { + vfunc_draw(cr: Context): boolean { if (this._size > 1) return super.vfunc_draw(cr); diff --git a/src/widgets/menu.ts b/src/widgets/menu.ts index 9941c2e..1919e14 100644 --- a/src/widgets/menu.ts +++ b/src/widgets/menu.ts @@ -3,6 +3,12 @@ import Gtk from 'gi://Gtk?version=3.0'; import { runCmd } from '../utils.js'; import { Command } from './shared.js'; +interface Params { + children?: Gtk.Widget[] + onPopup?: Command + onMoveScroll?: Command +} + export class AgsMenu extends Gtk.Menu { static { GObject.registerClass({ GTypeName: 'AgsMenu' }, this); @@ -16,7 +22,7 @@ export class AgsMenu extends Gtk.Menu { onPopup = '', onMoveScroll = '', ...rest - }: { [key: string]: any }) { + }: Params = {}) { super(rest); if (children) diff --git a/src/widgets/overlay.ts b/src/widgets/overlay.ts index 5d5df1e..337e3b0 100644 --- a/src/widgets/overlay.ts +++ b/src/widgets/overlay.ts @@ -1,6 +1,12 @@ import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk?version=3.0'; +interface Params { + overlays?: Gtk.Widget[] + pass_through?: boolean + passThrough?: boolean +} + export default class AgsOverlay extends Gtk.Overlay { static { GObject.registerClass({ @@ -15,9 +21,17 @@ export default class AgsOverlay extends Gtk.Overlay { }, this); } - constructor({ overlays = [], ...rest } = {}) { + constructor({ + overlays = [], + pass_through, + passThrough, + ...rest + }: Params = {}) { super(rest); this.overlays = overlays; + + if (pass_through || passThrough) + this.pass_through = true; } _passthrough = false; diff --git a/src/widgets/shared.ts b/src/widgets/shared.ts index 10524d1..ebbde63 100644 --- a/src/widgets/shared.ts +++ b/src/widgets/shared.ts @@ -1,13 +1,13 @@ import Gtk from 'gi://Gtk?version=3.0'; import { interval } from '../utils.js'; -export type Command = string | ((...args: any[]) => boolean); +export type Command = string | ((...args: unknown[]) => boolean); interface ServiceAPI { instance: { connectWidget: ( widget: Gtk.Widget, - callback: (widget: Gtk.Widget, ...args: any[]) => void, + callback: (widget: Gtk.Widget, ...args: unknown[]) => void, event?: string ) => void } @@ -19,11 +19,11 @@ interface CommonParams { halign?: 'start' | 'center' | 'end' | 'fill' valign?: 'start' | 'center' | 'end' | 'fill' connections?: ( - [string, (...args: any[]) => any] | - [number, (...args: any[]) => any] | - [ServiceAPI, (...args: any[]) => any, string] + [string, (...args: unknown[]) => unknown] | + [number, (...args: unknown[]) => unknown] | + [ServiceAPI, (...args: unknown[]) => unknown, string] )[] - properties?: [any, any][] + properties?: [string, unknown][] setup?: (widget: Gtk.Widget) => void } @@ -102,6 +102,7 @@ function parseCommon(widget: Gtk.Widget, { setup(widget); } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type ctor = { new(...args: any[]): Gtk.Widget } export default function constructor( ctor: ctor, diff --git a/src/widgets/slider.ts b/src/widgets/slider.ts index 7d1e878..16602d8 100644 --- a/src/widgets/slider.ts +++ b/src/widgets/slider.ts @@ -4,6 +4,14 @@ import { runCmd } from '../utils.js'; import { EventButton, EventScroll } from 'gi-types/gdk3'; import { Command } from './shared.js'; +interface Params { + onChange?: Command + value?: number + min?: number + max?: number + step?: number +} + export default class AgsSlider extends Gtk.Scale { static { GObject.registerClass({ @@ -32,7 +40,7 @@ export default class AgsSlider extends Gtk.Scale { max = 1, step = 0.01, ...rest - } = {}) { + }: Params = {}) { super({ ...rest, adjustment: new Gtk.Adjustment({ @@ -50,7 +58,7 @@ export default class AgsSlider extends Gtk.Scale { typeof this.onChange === 'function' ? this.onChange(this, event, value) - : runCmd(onChange.replace(/\{\}/g, value)); + : runCmd((onChange as string).replace(/\{\}/g, value)); }); if (value) diff --git a/src/widgets/stack.ts b/src/widgets/stack.ts index a36877c..eeb590c 100644 --- a/src/widgets/stack.ts +++ b/src/widgets/stack.ts @@ -1,6 +1,10 @@ import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk?version=3.0'; +interface Params { + items?: [string, Gtk.Widget][] +} + const transitions = [ 'none', 'crossfade', 'slide_right', 'slide_left', 'slide_up', 'slide_down', @@ -29,7 +33,7 @@ export default class AgsStack extends Gtk.Stack { }, this); } - constructor({ items = [], ...params }: { [key: string]: any } = {}) { + constructor({ items = [], ...params }: Params = {}) { super(params); this.items = items; } diff --git a/src/widgets/window.ts b/src/widgets/window.ts index b6eedea..521ba96 100644 --- a/src/widgets/window.ts +++ b/src/widgets/window.ts @@ -5,6 +5,17 @@ import App from '../app.js'; const { GtkLayerShell } = imports.gi; +interface Params { + anchor?: string[] | string + exclusive?: boolean + focusable?: boolean + layer?: string + margin?: number[] | number + monitor?: null | Gdk.Monitor | number + popup?: boolean + visible?: null | boolean +} + export default class AgsWindow extends Gtk.Window { static { GObject.registerClass({ GTypeName: 'AgsWindow' }, this); @@ -20,7 +31,7 @@ export default class AgsWindow extends Gtk.Window { popup = false, visible = null, ...params - }: any) { + }: Params = {}) { super(params); GtkLayerShell.init_for_window(this); GtkLayerShell.set_namespace(this, this.name);