mirror of
https://github.com/zoriya/ags.git
synced 2026-06-03 10:55:53 +00:00
lint
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
/types/**
|
||||
/gi-types/**
|
||||
_build/
|
||||
+9
-2
@@ -10,11 +10,14 @@ parserOptions:
|
||||
project: './tsconfig.json'
|
||||
warnOnUnsupportedTypeScriptVersion: false
|
||||
root: true
|
||||
ignorePatterns:
|
||||
- example/
|
||||
- types/
|
||||
- gi-types/
|
||||
- _build/
|
||||
plugins:
|
||||
- '@typescript-eslint'
|
||||
rules:
|
||||
no-unused-vars:
|
||||
- off
|
||||
'@typescript-eslint/no-unused-vars':
|
||||
- 'warn'
|
||||
'@typescript-eslint/restrict-template-expressions':
|
||||
@@ -100,6 +103,10 @@ rules:
|
||||
- always
|
||||
no-useless-escape:
|
||||
- off
|
||||
max-len:
|
||||
- error
|
||||
- code: 80
|
||||
tabWidth: 80
|
||||
globals:
|
||||
pkg: readonly
|
||||
ARGV: readonly
|
||||
|
||||
+8
-5
@@ -156,14 +156,16 @@ export default class App extends Gtk.Application {
|
||||
App.applyCss(config.style);
|
||||
|
||||
if (config.windows && !Array.isArray(config.windows)) {
|
||||
console.error(`windows attribute has to be an array, but it is a ${typeof config.windows}`);
|
||||
console.error('windows attribute has to be an array, ' +
|
||||
`but it is a ${typeof config.windows}`);
|
||||
this.emit('config-parsed');
|
||||
return;
|
||||
}
|
||||
|
||||
config.windows?.forEach(w => {
|
||||
if (!(w instanceof Gtk.Window)) {
|
||||
console.error(`${w} is not an instanceof Gtk.Window, but ${typeof w}`);
|
||||
console.error(`${w} is not an instanceof Gtk.Window, ` +
|
||||
` but it is of type ${typeof w}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -198,11 +200,12 @@ export default class App extends Gtk.Application {
|
||||
}
|
||||
|
||||
_exportActions() {
|
||||
this._addAction('inspector', () => Gtk.Window.set_interactive_debugging(true));
|
||||
this._addAction('inspector',
|
||||
() => Gtk.Window.set_interactive_debugging(true));
|
||||
this._addAction('quit', App.quit);
|
||||
|
||||
this._addAction('toggle-window', (_, arg) =>
|
||||
App.toggleWindow(arg.unpack() as string), new GLib.VariantType('s'));
|
||||
this._addAction('toggle-window', (_, arg) => App.toggleWindow(
|
||||
arg.unpack() as string), new GLib.VariantType('s'));
|
||||
|
||||
this._addAction('run-js', (_, arg) => {
|
||||
const fn = new Function(arg.unpack() as string);
|
||||
|
||||
+7
-1
@@ -20,7 +20,13 @@ export interface TDBusProxy {
|
||||
disconnect: (id: number) => void
|
||||
g_name_owner: string
|
||||
ListNamesRemote: (callback: (names: string[][]) => void) => void
|
||||
connectSignal: (event: string, callback: (proxy: string, sender: string, owners: string[]) => void) => void
|
||||
connectSignal: (
|
||||
event: string,
|
||||
callback: (
|
||||
proxy: string,
|
||||
sender: string,
|
||||
owners: string[]
|
||||
) => void) => void
|
||||
}
|
||||
|
||||
export const DBusProxy = Gio.DBusProxy.makeProxyWrapper(dbus) as TDBusProxy;
|
||||
|
||||
+5
-2
@@ -84,5 +84,8 @@ export interface TMprisProxy extends Proxy {
|
||||
DesktopEntry: string
|
||||
}
|
||||
|
||||
export const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(player) as TPlayerProxy;
|
||||
export const MprisProxy = Gio.DBusProxy.makeProxyWrapper(mpris) as TMprisProxy;
|
||||
export const MprisPlayerProxy =
|
||||
Gio.DBusProxy.makeProxyWrapper(player) as TPlayerProxy;
|
||||
|
||||
export const MprisProxy =
|
||||
Gio.DBusProxy.makeProxyWrapper(mpris) as TMprisProxy;
|
||||
|
||||
+18
-7
@@ -25,12 +25,15 @@ OPTIONS:
|
||||
-v, --version Print version and exit
|
||||
-q, --quit Kills AGS
|
||||
-c, --config Path to the config file. Default: ${DEFAULT_CONF}
|
||||
-b, --bus-name Bus name of the process, can be used to launch multiple instances
|
||||
-i, --inspector Open up the Gtk debug tool, useful for fetching css selectors
|
||||
-b, --bus-name Bus name of the process,
|
||||
can be used to launch multiple instances
|
||||
-i, --inspector Open up the Gtk debug tool,
|
||||
useful for fetching css selectors
|
||||
-t, --toggle-window Show or hide a window
|
||||
-r, --run-js Evaluate given string as a function and execute it.
|
||||
NOTE: It won't print anything, but if the function logs something,
|
||||
it can be seen on AGS's stdout.
|
||||
NOTE: It won't print anything,
|
||||
but if the function logs something,
|
||||
it can be seen on AGS's stdout.
|
||||
--clear-cache Removes ${Utils.CACHE_DIR}
|
||||
|
||||
EXAMPLES
|
||||
@@ -38,12 +41,20 @@ EXAMPLES
|
||||
ags --run-js "ags.Service.Mpris.getPlayer()?.playPause()"
|
||||
ags --toggle-window "window-name"`;
|
||||
|
||||
function client(busName: string, inspector: boolean, runJs: string, toggleWindow: string, quit: boolean) {
|
||||
function client(
|
||||
busName: string,
|
||||
inspector: boolean,
|
||||
runJs: string,
|
||||
toggleWindow: string,
|
||||
quit: boolean,
|
||||
) {
|
||||
const actions = Gio.DBusActionGroup.get(
|
||||
Gio.DBus.session, APP_BUS(busName), APP_PATH(busName));
|
||||
|
||||
if (toggleWindow)
|
||||
actions.activate_action('toggle-window', new GLib.Variant('s', toggleWindow));
|
||||
if (toggleWindow) {
|
||||
actions.activate_action('toggle-window',
|
||||
new GLib.Variant('s', toggleWindow));
|
||||
}
|
||||
|
||||
if (runJs)
|
||||
actions.activate_action('run-js', new GLib.Variant('s', runJs));
|
||||
|
||||
+2
-1
@@ -89,7 +89,8 @@ class ApplicationsService extends Service {
|
||||
Gio.AppInfoMonitor.get().connect('changed', this._sync.bind(this));
|
||||
|
||||
try {
|
||||
this.frequents = JSON.parse(readFile(CACHE_FILE)) as { [app: string]: number };
|
||||
this.frequents =
|
||||
JSON.parse(readFile(CACHE_FILE)) as { [app: string]: number };
|
||||
} catch (_) {
|
||||
this.frequents = {};
|
||||
}
|
||||
|
||||
+23
-9
@@ -24,7 +24,10 @@ class Stream extends GObject.Object {
|
||||
'icon-name',
|
||||
'id',
|
||||
'state',
|
||||
].map(prop => stream.connect(`notify::${prop}`, () => this.emit('changed')));
|
||||
].map(prop => stream.connect(
|
||||
`notify::${prop}`, () => this.emit('changed'),
|
||||
));
|
||||
|
||||
this.emit('changed');
|
||||
}
|
||||
|
||||
@@ -34,7 +37,8 @@ class Stream extends GObject.Object {
|
||||
get name() { return this._stream.name; }
|
||||
|
||||
get volume() {
|
||||
return this._stream.volume / Audio._instance._control.get_vol_max_norm();
|
||||
const max = Audio._instance._control.get_vol_max_norm();
|
||||
return this._stream.volume / max;
|
||||
}
|
||||
|
||||
set volume(value) { // 0..100
|
||||
@@ -44,7 +48,8 @@ class Stream extends GObject.Object {
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
|
||||
this._stream.set_volume(value * 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();
|
||||
}
|
||||
|
||||
@@ -79,12 +84,16 @@ class AudioService extends Service {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._control = new Gvc.MixerControl({ name: `${pkg.name} mixer control` });
|
||||
this._control = new Gvc.MixerControl({
|
||||
name: `${pkg.name} mixer control`,
|
||||
});
|
||||
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)],
|
||||
]);
|
||||
@@ -100,7 +109,10 @@ class AudioService extends Service {
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
this[`_${type}ID`] = stream.connect('changed', () => this.emit(`${type}-changed`));
|
||||
this[`_${type}ID`] = stream.connect(
|
||||
'changed',
|
||||
() => this.emit(`${type}-changed`),
|
||||
);
|
||||
this[`_${type}`] = stream;
|
||||
this.emit(`${type}-changed`);
|
||||
this.emit('changed');
|
||||
@@ -152,13 +164,15 @@ 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 microphones() { return Audio.instance.getStreams(Gvc.MixerSource); }
|
||||
|
||||
static get speaker() { return Audio.instance._speaker; }
|
||||
static set speaker(stream: Stream) { Audio.instance.setSpeaker(stream); }
|
||||
|
||||
static get microphone() { return Audio.instance._microphone; }
|
||||
// eslint-disable-next-line max-len
|
||||
static set microphone(stream: Stream) { Audio.instance.setMicrophone(stream); }
|
||||
static get microphone() { return Audio.instance._microphone; }
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ class Device extends GObject.Object {
|
||||
'name',
|
||||
'paired',
|
||||
'trusted',
|
||||
].map(prop => device.connect(`notify::${prop}`, () => this.emit('changed')));
|
||||
].map(prop => device.connect(
|
||||
`notify::${prop}`, () => this.emit('changed'),
|
||||
));
|
||||
}
|
||||
|
||||
close() {
|
||||
@@ -81,7 +83,8 @@ class BluetoothService extends Service {
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this._client.default_adapter_powered = !this._client.default_adapter_powered;
|
||||
this._client.default_adapter_powered =
|
||||
!this._client.default_adapter_powered;
|
||||
}
|
||||
|
||||
_getDevices() {
|
||||
@@ -117,7 +120,11 @@ class BluetoothService extends Service {
|
||||
this.emit('changed');
|
||||
}
|
||||
|
||||
connectDevice(device: Device, connect: boolean, callback: (s: boolean) => void) {
|
||||
connectDevice(
|
||||
device: Device,
|
||||
connect: boolean,
|
||||
callback: (s: boolean) => void,
|
||||
) {
|
||||
this._client.connect_service(
|
||||
device._device.get_object_path(),
|
||||
connect,
|
||||
@@ -167,8 +174,9 @@ 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; }
|
||||
static get devices() { return Bluetooth.instance.devices; }
|
||||
static get connectedDevices() { return Bluetooth.instance.connectedDevices; }
|
||||
}
|
||||
|
||||
@@ -88,7 +88,8 @@ class HyprlandService extends Service {
|
||||
try {
|
||||
const monitors = await execAsync('hyprctl -j monitors');
|
||||
this._monitors = new Map();
|
||||
(JSON.parse(monitors) as { [key: string]: any }[]).forEach(monitor => {
|
||||
const json = JSON.parse(monitors) as { [key: string]: any }[];
|
||||
json.forEach(monitor => {
|
||||
this._monitors.set(monitor.name, monitor);
|
||||
if (monitor.focused) {
|
||||
this._active.monitor = monitor.name;
|
||||
@@ -104,7 +105,8 @@ class HyprlandService extends Service {
|
||||
try {
|
||||
const workspaces = await execAsync('hyprctl -j workspaces');
|
||||
this._workspaces = new Map();
|
||||
(JSON.parse(workspaces) as { [key: string]: any }[]).forEach(ws => {
|
||||
const json = JSON.parse(workspaces) as { [key: string]: any }[];
|
||||
json.forEach(ws => {
|
||||
this._workspaces.set(ws.id, ws);
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -116,8 +118,10 @@ class HyprlandService extends Service {
|
||||
try {
|
||||
const clients = await execAsync('hyprctl -j clients');
|
||||
this._clients = new Map();
|
||||
(JSON.parse(clients as string) as { [key: string]: any }[]).forEach(client => {
|
||||
this._clients.set((client.address as string).substring(2), client);
|
||||
const json = JSON.parse(clients) as { [key: string]: any }[];
|
||||
json.forEach(client => {
|
||||
this._clients.set(
|
||||
(client.address as string).substring(2), client);
|
||||
});
|
||||
} catch (error) {
|
||||
logError(error as Error);
|
||||
|
||||
+15
-6
@@ -3,9 +3,12 @@ import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Service from './service.js';
|
||||
import { ensureDirectory, timeout } from '../utils.js';
|
||||
import { MprisPlayerProxy, MprisProxy, TMprisProxy, TPlayerProxy, MprisMetadata } from '../dbus/mpris.js';
|
||||
import { DBusProxy, TDBusProxy } from '../dbus/dbus.js';
|
||||
import { CACHE_DIR } from '../utils.js';
|
||||
import {
|
||||
MprisPlayerProxy, MprisProxy,
|
||||
TMprisProxy, TPlayerProxy, MprisMetadata,
|
||||
} from '../dbus/mpris.js';
|
||||
|
||||
const MEDIA_CACHE_PATH = `${CACHE_DIR}/media`;
|
||||
|
||||
@@ -116,12 +119,14 @@ class MprisPlayer extends GObject.Object {
|
||||
? -1
|
||||
: Number.parseInt(`${length}`.substring(0, 3));
|
||||
|
||||
this.playBackStatus = this._playerProxy.PlaybackStatus as PlaybackStatus;
|
||||
this.shuffleStatus = this._playerProxy.Shuffle;
|
||||
this.loopStatus = this._playerProxy.LoopStatus as LoopStatus;
|
||||
this.canGoNext = this._playerProxy.CanGoNext;
|
||||
this.canGoPrev = this._playerProxy.CanGoPrevious;
|
||||
this.canPlay = this._playerProxy.CanPlay;
|
||||
this.shuffleStatus = this._playerProxy.Shuffle;
|
||||
this.loopStatus = this._playerProxy.LoopStatus as LoopStatus;
|
||||
this.playBackStatus =
|
||||
this._playerProxy.PlaybackStatus as PlaybackStatus;
|
||||
|
||||
this.trackid = metadata['mpris:trackid'];
|
||||
this.trackArtists = trackArtists;
|
||||
this.trackTitle = trackTitle;
|
||||
@@ -283,7 +288,11 @@ class MprisService extends Service {
|
||||
this._onNameOwnerChanged.bind(this));
|
||||
}
|
||||
|
||||
_onNameOwnerChanged(_proxy: string, _sender: string, [name, oldOwner, newOwner]: string[]) {
|
||||
_onNameOwnerChanged(
|
||||
_proxy: string,
|
||||
_sender: string,
|
||||
[name, oldOwner, newOwner]: string[],
|
||||
) {
|
||||
if (!name.startsWith('org.mpris.MediaPlayer2.'))
|
||||
return;
|
||||
|
||||
@@ -313,7 +322,7 @@ export default class Mpris {
|
||||
return Mpris._instance;
|
||||
}
|
||||
|
||||
static getPlayer(name: string | ((players: Players) => MprisPlayer)): MprisPlayer | null {
|
||||
static getPlayer(name: string | ((players: Players) => MprisPlayer)) {
|
||||
return Mpris._instance.getPlayer(name);
|
||||
}
|
||||
}
|
||||
|
||||
+33
-20
@@ -1,4 +1,5 @@
|
||||
import NM from 'gi://NM';
|
||||
import GObject from 'gi://GObject';
|
||||
import Service from './service.js';
|
||||
import { bulkConnect } from '../utils.js';
|
||||
|
||||
@@ -30,6 +31,24 @@ const _DEVICE_STATE = (device: NM.Device) => {
|
||||
}
|
||||
};
|
||||
|
||||
const _CONNECTIVITY_STATE = (client: NM.Client) => {
|
||||
switch (client.connectivity) {
|
||||
case NM.ConnectivityState.NONE: return 'none';
|
||||
case NM.ConnectivityState.PORTAL: return 'none';
|
||||
case NM.ConnectivityState.LIMITED: return 'none';
|
||||
case NM.ConnectivityState.FULL: return 'none';
|
||||
default: return 'unknown';
|
||||
}
|
||||
};
|
||||
|
||||
const _DEVICE = (device: string) => {
|
||||
switch (device) {
|
||||
case '802-11-wireless': return 'wifi';
|
||||
case '802-3-ethernet': return 'wired';
|
||||
default: return '';
|
||||
}
|
||||
};
|
||||
|
||||
class Wifi extends Service {
|
||||
static { Service.register(this); }
|
||||
|
||||
@@ -68,7 +87,8 @@ class Wifi extends Service {
|
||||
if (!this._ap)
|
||||
return;
|
||||
|
||||
this._apBind = this._ap.connect('notify::strength', () => this.emit('changed'));
|
||||
this._apBind = this._ap.connect(
|
||||
'notify::strength', () => this.emit('changed'));
|
||||
}
|
||||
|
||||
get accessPoints() {
|
||||
@@ -151,15 +171,19 @@ class NetworkService extends Service {
|
||||
}
|
||||
|
||||
_clientReady() {
|
||||
this._client.connect('notify::wireless-enabled', this._sync.bind(this));
|
||||
this._client.connect('notify::connectivity', this._sync.bind(this));
|
||||
this._client.connect('notify::primary-connection', this._sync.bind(this));
|
||||
this._client.connect('notify::activating-connection', this._sync.bind(this));
|
||||
bulkConnect((this._client as unknown) as GObject.Object, [
|
||||
['notify::wireless-enabled', this._sync.bind(this)],
|
||||
['notify::connectivity', this._sync.bind(this)],
|
||||
['notify::primary-connection', this._sync.bind(this)],
|
||||
['notify::activating-connection', this._sync.bind(this)],
|
||||
]);
|
||||
|
||||
this._wifi = new Wifi(this._client, this._getDevice(NM.DeviceType.WIFI) as NM.DeviceWifi);
|
||||
this._wifi = new Wifi(this._client,
|
||||
this._getDevice(NM.DeviceType.WIFI) as NM.DeviceWifi);
|
||||
this._wifi.connect('changed', this._sync.bind(this));
|
||||
|
||||
this._wired = new Wired(this._getDevice(NM.DeviceType.ETHERNET) as NM.DeviceEthernet);
|
||||
this._wired = new Wired(
|
||||
this._getDevice(NM.DeviceType.ETHERNET) as NM.DeviceEthernet);
|
||||
this._wired.connect('changed', this._sync.bind(this));
|
||||
|
||||
this._sync();
|
||||
@@ -170,19 +194,8 @@ class NetworkService extends Service {
|
||||
this._client.get_primary_connection() ||
|
||||
this._client.get_activating_connection();
|
||||
|
||||
const primary = mainConnection?.type;
|
||||
this._primary = {
|
||||
'802-11-wireless': 'wifi',
|
||||
'802-3-ethernet': 'wired',
|
||||
}[primary || ''],
|
||||
|
||||
this._connectivity = {
|
||||
[NM.ConnectivityState.NONE]: 'none',
|
||||
[NM.ConnectivityState.PORTAL]: 'portal',
|
||||
[NM.ConnectivityState.LIMITED]: 'limited',
|
||||
[NM.ConnectivityState.FULL]: 'full',
|
||||
}[this._client.connectivity] || 'unknown';
|
||||
|
||||
this._primary = _DEVICE(mainConnection?.type || '');
|
||||
this._connectivity = _CONNECTIVITY_STATE(this._client);
|
||||
this.emit('changed');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ import GLib from 'gi://GLib';
|
||||
import Service from './service.js';
|
||||
import App from '../app.js';
|
||||
import { NotificationIFace } from '../dbus/notifications.js';
|
||||
import { CACHE_DIR, ensureDirectory, readFileAsync, timeout, writeFile } from '../utils.js';
|
||||
import {
|
||||
CACHE_DIR, ensureDirectory, readFileAsync,
|
||||
timeout, writeFile,
|
||||
} from '../utils.js';
|
||||
|
||||
const NOTIFICATIONS_CACHE_PATH = `${CACHE_DIR}/notifications`;
|
||||
const CACHE_FILE = NOTIFICATIONS_CACHE_PATH + '/notifications.json';
|
||||
@@ -113,8 +116,10 @@ class NotificationsService extends Service {
|
||||
actions,
|
||||
urgency,
|
||||
time: GLib.DateTime.new_now_local().to_unix(),
|
||||
image: this._parseImage(`${summary}${id}`, hints['image-data']) || this._isFile(appIcon),
|
||||
popup: !this._dnd,
|
||||
image: this._parseImage(
|
||||
id, hints['image-data']) ||
|
||||
this._isFile(appIcon),
|
||||
});
|
||||
|
||||
timeout(this._timeout, () => this.DismissNotification(id));
|
||||
@@ -139,7 +144,9 @@ class NotificationsService extends Service {
|
||||
if (!this._notifications.has(id))
|
||||
return;
|
||||
|
||||
this._dbus.emit_signal('NotificationClosed', GLib.Variant.new('(uu)', [id, 3]));
|
||||
this._dbus.emit_signal('NotificationClosed',
|
||||
GLib.Variant.new('(uu)', [id, 3]));
|
||||
|
||||
this._notifications.delete(id);
|
||||
this.emit('closed', id);
|
||||
this.emit('changed');
|
||||
@@ -150,7 +157,9 @@ class NotificationsService extends Service {
|
||||
if (!this._notifications.has(id))
|
||||
return;
|
||||
|
||||
this._dbus.emit_signal('ActionInvoked', GLib.Variant.new('(us)', [id, actionId]));
|
||||
this._dbus.emit_signal('ActionInvoked',
|
||||
GLib.Variant.new('(us)', [id, actionId]));
|
||||
|
||||
this.CloseNotification(id);
|
||||
this._cache();
|
||||
}
|
||||
@@ -174,12 +183,16 @@ class NotificationsService extends Service {
|
||||
'org.freedesktop.Notifications',
|
||||
Gio.BusNameOwnerFlags.NONE,
|
||||
(connection: Gio.DBusConnection) => {
|
||||
this._dbus = Gio.DBusExportedObject.wrapJSObject(NotificationIFace, this);
|
||||
this._dbus = Gio.DBusExportedObject
|
||||
.wrapJSObject(NotificationIFace, this);
|
||||
|
||||
this._dbus.export(connection, '/org/freedesktop/Notifications');
|
||||
},
|
||||
null,
|
||||
() => {
|
||||
print('Another notification daemon is already running, make sure you stop Dunst or any other daemon you have running');
|
||||
print('Another notification daemon is already running, ' +
|
||||
'make sure you stop Dunst ' +
|
||||
'or any other daemon you have running');
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -205,12 +218,12 @@ class NotificationsService extends Service {
|
||||
return GLib.file_test(path, GLib.FileTest.EXISTS) ? path : null;
|
||||
}
|
||||
|
||||
_parseImage(name: string, image_data?: GLib.Variant<'(iiibiiay)'>) {
|
||||
_parseImage(id: number, image_data?: GLib.Variant<'(iiibiiay)'>) {
|
||||
if (!image_data)
|
||||
return null;
|
||||
|
||||
ensureDirectory(NOTIFICATIONS_CACHE_PATH);
|
||||
const fileName = NOTIFICATIONS_CACHE_PATH + '/' + name.replace(/[^a-zA-Z0-9]/g, '');
|
||||
const fileName = NOTIFICATIONS_CACHE_PATH + `/${id}`;
|
||||
const image = image_data.recursiveUnpack();
|
||||
const pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(
|
||||
image[6],
|
||||
@@ -240,7 +253,8 @@ class NotificationsService extends Service {
|
||||
}
|
||||
|
||||
ensureDirectory(NOTIFICATIONS_CACHE_PATH);
|
||||
writeFile(JSON.stringify(notifications, null, 2), CACHE_FILE).catch(logError);
|
||||
const json = JSON.stringify(notifications, null, 2);
|
||||
writeFile(json, CACHE_FILE).catch(logError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,10 +267,13 @@ export default class Notifications {
|
||||
return Notifications._instance;
|
||||
}
|
||||
|
||||
// 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); }
|
||||
static dismiss(id: number) { Notifications.instance.DismissNotification(id); }
|
||||
static invoke(id: number, actionId: string) { Notifications.instance.InvokeAction(id, actionId); }
|
||||
|
||||
static get dnd() { return Notifications.instance.dnd; }
|
||||
static set dnd(value: boolean) { Notifications.instance.dnd = value; }
|
||||
static get popups() { return Notifications.instance.popups; }
|
||||
|
||||
@@ -22,8 +22,9 @@ export default class Service extends GObject.Object {
|
||||
if (signals) {
|
||||
Object.keys(signals).forEach(signal =>
|
||||
Signals[signal] = {
|
||||
// @ts-ignore
|
||||
param_types: signals[signal].map(t => GObject[`TYPE_${t.toUpperCase()}`]),
|
||||
param_types: signals[signal].map(t =>
|
||||
// @ts-ignore
|
||||
GObject[`TYPE_${t.toUpperCase()}`]),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -35,7 +36,11 @@ export default class Service extends GObject.Object {
|
||||
(Service as { [key: string]: any })[name] = api;
|
||||
}
|
||||
|
||||
connectWidget(widget: Gtk.Widget, callback: (widget: Gtk.Widget, ...args: any[]) => void, event = 'changed') {
|
||||
connectWidget(
|
||||
widget: Gtk.Widget,
|
||||
callback: (widget: Gtk.Widget, ...args: any[]) => void,
|
||||
event = 'changed',
|
||||
) {
|
||||
connect(this, widget, callback, event);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-5
@@ -21,7 +21,8 @@ export function readFileAsync(path: string): Promise<string> {
|
||||
const [success, bytes] = file.load_contents_finish(res);
|
||||
return success
|
||||
? resolve(new TextDecoder().decode(bytes))
|
||||
: reject(new Error(`reading file ${path} was unsuccessful`));
|
||||
: reject(new Error(
|
||||
`reading file ${path} was unsuccessful`));
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
@@ -51,7 +52,13 @@ export function writeFile(string: string, path: string): Promise<Gio.File> {
|
||||
});
|
||||
}
|
||||
|
||||
export function bulkConnect(service: GObject.Object, list: [event: string, callback: (...args: any[]) => void][]) {
|
||||
export function bulkConnect(
|
||||
service: GObject.Object,
|
||||
list: [
|
||||
event: string,
|
||||
callback: (...args: any[]) => void
|
||||
][],
|
||||
) {
|
||||
const ids = [];
|
||||
for (const [event, callback] of list)
|
||||
ids.push(service.connect(event, callback));
|
||||
@@ -70,12 +77,17 @@ export function connect(
|
||||
callback: (widget: Gtk.Widget, ...args: any[]) => void,
|
||||
event = 'changed',
|
||||
) {
|
||||
const bind = service.connect(event, (_s: GObject.Object, ...args: any[]) => callback(widget, ...args));
|
||||
const bind = service.connect(
|
||||
event, (_s, ...args: any[]) => callback(widget, ...args));
|
||||
|
||||
widget.connect('destroy', () => service.disconnect(bind));
|
||||
timeout(10, () => callback(widget));
|
||||
}
|
||||
|
||||
export function interval(interval: number, callback: () => void, widget: Gtk.Widget) {
|
||||
export function interval(
|
||||
interval: number,
|
||||
callback: () => void, widget: Gtk.Widget,
|
||||
) {
|
||||
callback();
|
||||
const id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, interval, () => {
|
||||
callback();
|
||||
@@ -95,7 +107,10 @@ export function timeout(ms: number, callback: () => void) {
|
||||
});
|
||||
}
|
||||
|
||||
export function runCmd(cmd: string | ((...args: any[]) => boolean), ...args: any[]) {
|
||||
export function runCmd(
|
||||
cmd: string | ((...args: any[]) => boolean),
|
||||
...args: any[]
|
||||
) {
|
||||
if (typeof cmd !== 'string' && typeof cmd !== 'function') {
|
||||
console.error('Command has to be string or function');
|
||||
return false;
|
||||
|
||||
+7
-1
@@ -16,7 +16,13 @@ import { Menu, MenuItem } from './widgets/menu.js';
|
||||
import Window from './widgets/window.js';
|
||||
import constructor from './widgets/shared.js';
|
||||
|
||||
export default function Widget({ type, ...params }: { type: { new(...args: any[]): Gtk.Widget } }) {
|
||||
interface Params {
|
||||
type: {
|
||||
new(...args: any[]): Gtk.Widget
|
||||
}
|
||||
}
|
||||
|
||||
export default function Widget({ type, ...params }: Params) {
|
||||
return constructor(type, params);
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -74,23 +74,28 @@ export default class Button extends Gtk.Button {
|
||||
|
||||
vfunc_button_release_event(event: Gdk.EventButton): boolean {
|
||||
this.unset_state_flags(Gtk.StateFlags.ACTIVE);
|
||||
if (this.onPrimaryClickRelease && event.button === Gdk.BUTTON_PRIMARY)
|
||||
if (this.onPrimaryClickRelease &&
|
||||
event.button === Gdk.BUTTON_PRIMARY)
|
||||
return runCmd(this.onPrimaryClickRelease, this, event);
|
||||
|
||||
else if (this.onSecondaryClickRelease && event.button === Gdk.BUTTON_SECONDARY)
|
||||
else if (this.onSecondaryClickRelease &&
|
||||
event.button === Gdk.BUTTON_SECONDARY)
|
||||
return runCmd(this.onSecondaryClickRelease, this, event);
|
||||
|
||||
else if (this.onMiddleClickRelease && event.button === Gdk.BUTTON_MIDDLE)
|
||||
else if (this.onMiddleClickRelease &&
|
||||
event.button === Gdk.BUTTON_MIDDLE)
|
||||
return runCmd(this.onMiddleClickRelease, this, event);
|
||||
|
||||
return super.vfunc_button_release_event(event);
|
||||
}
|
||||
|
||||
vfunc_scroll_event(event: Gdk.EventScroll): boolean {
|
||||
if (this.onScrollUp && event.direction === Gdk.ScrollDirection.UP)
|
||||
if (this.onScrollUp &&
|
||||
event.direction === Gdk.ScrollDirection.UP)
|
||||
return runCmd(this.onScrollUp, this, event);
|
||||
|
||||
else if (this.onScrollDown && event.direction === Gdk.ScrollDirection.DOWN)
|
||||
else if (this.onScrollDown &&
|
||||
event.direction === Gdk.ScrollDirection.DOWN)
|
||||
return runCmd(this.onScrollDown, this, event);
|
||||
|
||||
return super.vfunc_scroll_event(event);
|
||||
|
||||
+7
-2
@@ -24,7 +24,10 @@ export default class Icon extends Gtk.Image {
|
||||
}
|
||||
|
||||
constructor(params: object | string) {
|
||||
const { icon = '', size = 0 } = params as { icon: string, size: number };
|
||||
const {
|
||||
icon = '',
|
||||
size = 0,
|
||||
} = params as { icon: string, size: number };
|
||||
super(typeof params === 'string' ? { icon: params } : params);
|
||||
|
||||
// set correct size after construct
|
||||
@@ -53,7 +56,9 @@ export default class Icon extends Gtk.Image {
|
||||
if (GLib.file_test(icon, GLib.FileTest.EXISTS)) {
|
||||
this._file = true;
|
||||
this.set_from_pixbuf(
|
||||
GdkPixbuf.Pixbuf.new_from_file_at_size(icon, this.size, this.size),
|
||||
GdkPixbuf.Pixbuf.new_from_file_at_size(
|
||||
icon, this.size, this.size,
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
+5
-2
@@ -24,8 +24,11 @@ export class Menu extends Gtk.Menu {
|
||||
this.onPopup = onPopup;
|
||||
this.onMoveScroll = onMoveScroll;
|
||||
|
||||
this.connect('popped-up', (...args) => runCmd(this.onPopup, ...args));
|
||||
this.connect('move-scroll', (...args) => runCmd(this.onMoveScroll, ...args));
|
||||
this.connect('popped-up', (...args) =>
|
||||
runCmd(this.onPopup, ...args));
|
||||
|
||||
this.connect('move-scroll', (...args) =>
|
||||
runCmd(this.onMoveScroll, ...args));
|
||||
}
|
||||
|
||||
get children() { return this.get_children(); }
|
||||
|
||||
@@ -30,7 +30,8 @@ export default class Overlay extends Gtk.Overlay {
|
||||
get pass_through() { return this._passthrough; }
|
||||
set pass_through(passthrough: boolean) {
|
||||
this._passthrough = passthrough;
|
||||
this.get_children().forEach(ch => this.set_overlay_pass_through(ch, passthrough));
|
||||
this.get_children().forEach(ch =>
|
||||
this.set_overlay_pass_through(ch, passthrough));
|
||||
}
|
||||
|
||||
_child!: Gtk.Widget;
|
||||
|
||||
@@ -31,8 +31,9 @@ export default class Revealer extends Gtk.Revealer {
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.transitionType = Gtk.RevealerTransitionType[transition.toUpperCase()];
|
||||
this.transitionType =
|
||||
// @ts-ignore
|
||||
Gtk.RevealerTransitionType[transition.toUpperCase()];
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
|
||||
+18
-5
@@ -3,7 +3,11 @@ import { interval } from '../utils.js';
|
||||
|
||||
interface ServiceAPI {
|
||||
instance: {
|
||||
connectWidget: (widget: Gtk.Widget, callback: (widget: Gtk.Widget, ...args: any[]) => void, event?: string) => void
|
||||
connectWidget: (
|
||||
widget: Gtk.Widget,
|
||||
callback: (widget: Gtk.Widget, ...args: any[]) => void,
|
||||
event?: string
|
||||
) => void
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +34,16 @@ function setStyle(widget: Gtk.Widget, css: string) {
|
||||
const provider = new Gtk.CssProvider();
|
||||
const style = `* { ${css} }`;
|
||||
provider.load_from_data(style);
|
||||
widget.get_style_context().add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
|
||||
widget.get_style_context()
|
||||
.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
|
||||
widgetProviders.set(widget, provider);
|
||||
}
|
||||
|
||||
function toggleClassName(widget: Gtk.Widget, className: string, condition = true) {
|
||||
function toggleClassName(
|
||||
widget: Gtk.Widget,
|
||||
className: string,
|
||||
condition = true,
|
||||
) {
|
||||
condition
|
||||
? widget.get_style_context().add_class(className)
|
||||
: widget.get_style_context().remove_class(className);
|
||||
@@ -59,7 +68,8 @@ function parseCommon(widget: Gtk.Widget, {
|
||||
widget.setStyle = (css: string) => setStyle(widget, css);
|
||||
|
||||
// @ts-ignore
|
||||
widget.toggleClassName = (className: string, condition = true) => toggleClassName(widget, className, condition);
|
||||
widget.toggleClassName = (className: string, condition = true) =>
|
||||
toggleClassName(widget, className, condition);
|
||||
|
||||
if (typeof className === 'string') {
|
||||
className.split(' ').forEach(cn => {
|
||||
@@ -110,7 +120,10 @@ function parseCommon(widget: Gtk.Widget, {
|
||||
setup(widget);
|
||||
}
|
||||
|
||||
export default function constructor(ctor: { new(...args: any[]): Gtk.Widget }, params: CommonParams | string = {}) {
|
||||
export default function constructor(
|
||||
ctor: { new(...args: any[]): Gtk.Widget },
|
||||
params: CommonParams | string = {},
|
||||
) {
|
||||
let widget;
|
||||
if (typeof params === 'string') {
|
||||
widget = new ctor(params);
|
||||
|
||||
+19
-9
@@ -72,7 +72,8 @@ export default class Window extends Gtk.Window {
|
||||
get layet() { return this._layer; }
|
||||
set layer(layer: string) {
|
||||
this._layer;
|
||||
GtkLayerShell.set_layer(this, GtkLayerShell.Layer[layer?.toUpperCase()]);
|
||||
GtkLayerShell.set_layer(this,
|
||||
GtkLayerShell.Layer[layer?.toUpperCase()]);
|
||||
}
|
||||
|
||||
_anchor: string[] = [];
|
||||
@@ -108,23 +109,28 @@ export default class Window extends Gtk.Window {
|
||||
|
||||
switch (margin.length) {
|
||||
case 1:
|
||||
margins = [['TOP', 0], ['RIGHT', 0], ['BOTTOM', 0], ['LEFT', 0]];
|
||||
margins = [
|
||||
['TOP', 0], ['RIGHT', 0], ['BOTTOM', 0], ['LEFT', 0]];
|
||||
break;
|
||||
case 2:
|
||||
margins = [['TOP', 0], ['RIGHT', 1], ['BOTTOM', 0], ['LEFT', 1]];
|
||||
margins = [
|
||||
['TOP', 0], ['RIGHT', 1], ['BOTTOM', 0], ['LEFT', 1]];
|
||||
break;
|
||||
case 3:
|
||||
margins = [['TOP', 0], ['RIGHT', 1], ['BOTTOM', 2], ['LEFT', 1]];
|
||||
margins = [
|
||||
['TOP', 0], ['RIGHT', 1], ['BOTTOM', 2], ['LEFT', 1]];
|
||||
break;
|
||||
case 4:
|
||||
margins = [['TOP', 0], ['RIGHT', 1], ['BOTTOM', 2], ['LEFT', 3]];
|
||||
margins = [
|
||||
['TOP', 0], ['RIGHT', 1], ['BOTTOM', 2], ['LEFT', 3]];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
margins.forEach(([side, i]) =>
|
||||
GtkLayerShell.set_margin(this, GtkLayerShell.Edge[side], (margin as number[])[i]),
|
||||
GtkLayerShell.set_margin(this,
|
||||
GtkLayerShell.Edge[side], (margin as number[])[i]),
|
||||
);
|
||||
|
||||
this._margins = margin;
|
||||
@@ -138,14 +144,18 @@ export default class Window extends Gtk.Window {
|
||||
|
||||
if (popup) {
|
||||
this.connect('key-press-event', (_, event) => {
|
||||
if (event.get_keyval()[1] === Gdk.KEY_Escape)
|
||||
App.getWindow(this.name) ? App.closeWindow(this.name) : this.hide();
|
||||
if (event.get_keyval()[1] === Gdk.KEY_Escape) {
|
||||
App.getWindow(this.name)
|
||||
? App.closeWindow(this.name)
|
||||
: this.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get focusable() {
|
||||
return GtkLayerShell.get_keyboard_mode(this) === GtkLayerShell.KeyboardMode.ON_DEMAND;
|
||||
return GtkLayerShell.get_keyboard_mode(this) ===
|
||||
GtkLayerShell.KeyboardMode.ON_DEMAND;
|
||||
}
|
||||
|
||||
set focusable(focusable: boolean) {
|
||||
|
||||
Reference in New Issue
Block a user