This commit is contained in:
Aylur
2023-08-18 20:04:09 +02:00
parent 84f48d7550
commit d488dd8865
23 changed files with 267 additions and 110 deletions
-3
View File
@@ -1,3 +0,0 @@
/types/**
/gi-types/**
_build/
+9 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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; }
}
+12 -4
View File
@@ -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; }
}
+8 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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');
}
}
+28 -11
View File
@@ -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; }
+8 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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(); }
+2 -1
View File
@@ -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;
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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) {