mirror of
https://github.com/zoriya/ags.git
synced 2025-12-06 00:06:10 +00:00
@@ -4,27 +4,16 @@ import Notifications from 'resource:///com/github/Aylur/ags/service/notification
|
||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
||||
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
|
||||
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
|
||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
||||
import {
|
||||
Box, Button, Stack, Label, Icon, CenterBox, Window, Slider, ProgressBar
|
||||
} from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import { exec, execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||
|
||||
// import statements are long, so there is also the global ags object you can import from
|
||||
// const { Hyprland, Notifications, Mpris, Audio, Battery } = ags.Service;
|
||||
// const { App } = ags;
|
||||
// const { exec } = ags.Utils;
|
||||
// const {
|
||||
// Box, Button, Stack, Label, Icon, CenterBox, Window, Slider, ProgressBar
|
||||
// } = ags.Widget;
|
||||
|
||||
// every widget is a subclass of Gtk.<widget>
|
||||
// with a few extra available properties
|
||||
// for example Box is a subclass of Gtk.Box
|
||||
const { Box, Button, Stack, Label, Icon, CenterBox, Window, Slider, ProgressBar } = Widget;
|
||||
|
||||
// widgets can be only assigned as a child in one container
|
||||
// so to make a reuseable widget, just make it a function
|
||||
// then you can use it by calling simply calling it
|
||||
|
||||
const Workspaces = () => Box({
|
||||
className: 'workspaces',
|
||||
connections: [[Hyprland, box => {
|
||||
@@ -161,6 +150,20 @@ const BatteryLabel = () => Box({
|
||||
],
|
||||
});
|
||||
|
||||
const SysTray = () => Box({
|
||||
connections: [[SystemTray, box => {
|
||||
box.children = SystemTray.items.map(item => Button({
|
||||
child: Icon(),
|
||||
onPrimaryClick: (_, event) => item.activate(event),
|
||||
onSecondaryClick: (_, event) => item.openMenu(event),
|
||||
connections: [[item, button => {
|
||||
button.child.icon = item.icon;
|
||||
button.tooltipMarkup = item.tooltipMarkup;
|
||||
}]],
|
||||
}));
|
||||
}]],
|
||||
});
|
||||
|
||||
// layout of the bar
|
||||
const Left = () => Box({
|
||||
children: [
|
||||
@@ -182,11 +185,12 @@ const Right = () => Box({
|
||||
Volume(),
|
||||
BatteryLabel(),
|
||||
Clock(),
|
||||
SysTray(),
|
||||
],
|
||||
});
|
||||
|
||||
const Bar = ({ monitor } = {}) => Window({
|
||||
name: `bar${monitor || ''}`, // name has to be unique
|
||||
name: `bar-${monitor}`, // name has to be unique
|
||||
className: 'bar',
|
||||
monitor,
|
||||
anchor: ['top', 'left', 'right'],
|
||||
|
||||
27
flake.lock
generated
27
flake.lock
generated
@@ -1,32 +1,12 @@
|
||||
{
|
||||
"nodes": {
|
||||
"dongsu8142-nur": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1690083492,
|
||||
"narHash": "sha256-UoIG+sl44U38FTmM2+m4X2Qi5aivjITcUxAkVHouZl4=",
|
||||
"owner": "dongsu8142",
|
||||
"repo": "nur",
|
||||
"rev": "7f5c7067a482e96fe3787e07a54e21041a4d15c0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "dongsu8142",
|
||||
"repo": "nur",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1690031011,
|
||||
"narHash": "sha256-kzK0P4Smt7CL53YCdZCBbt9uBFFhE0iNvCki20etAf4=",
|
||||
"lastModified": 1693471703,
|
||||
"narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "12303c652b881435065a98729eb7278313041e49",
|
||||
"rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -38,7 +18,6 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"dongsu8142-nur": "dongsu8142-nur",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
|
||||
28
flake.nix
28
flake.nix
@@ -1,31 +1,23 @@
|
||||
{
|
||||
description = "A customizable and extensible shell";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
dongsu8142-nur = {
|
||||
url = "github:dongsu8142/nur";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = inputs@{
|
||||
self,
|
||||
nixpkgs,
|
||||
...
|
||||
}: let
|
||||
lib = nixpkgs.lib;
|
||||
genSystems = lib.genAttrs [
|
||||
outputs = { nixpkgs, self }:
|
||||
let
|
||||
genSystems = nixpkgs.lib.genAttrs [
|
||||
"aarch64-linux"
|
||||
"x86_64-linux"
|
||||
];
|
||||
pkgsFor = genSystems (system:
|
||||
import nixpkgs {
|
||||
inherit system;
|
||||
}
|
||||
);
|
||||
in {
|
||||
pkgs = genSystems (system: import nixpkgs { inherit system; });
|
||||
in
|
||||
{
|
||||
packages = genSystems (system: {
|
||||
default = pkgsFor.${system}.callPackage ./nix/default.nix { inherit inputs; };
|
||||
default = pkgs.${system}.callPackage ./nix/ags.nix {
|
||||
gjs = pkgs.${system}.callPackage ./nix/gjs.nix { };
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
system,
|
||||
inputs,
|
||||
buildNpmPackage,
|
||||
fetchFromGitLab,
|
||||
nodePackages,
|
||||
meson,
|
||||
pkg-config,
|
||||
ninja,
|
||||
gobject-introspection,
|
||||
gtk3,
|
||||
libpulseaudio
|
||||
{ lib
|
||||
, stdenv
|
||||
, buildNpmPackage
|
||||
, fetchFromGitLab
|
||||
, nodePackages
|
||||
, meson
|
||||
, pkg-config
|
||||
, ninja
|
||||
, gobject-introspection
|
||||
, gtk3
|
||||
, libpulseaudio
|
||||
, gjs
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -40,7 +38,7 @@ stdenv.mkDerivation {
|
||||
|
||||
dontBuild = true;
|
||||
|
||||
npmDepsHash = "sha256-uNdmlQIwXoO8Ls0qjJnwRGqpfiJK1PajAvoiHfJXcxg=";
|
||||
npmDepsHash = "sha256-4BNbFi/Ltg/8tuicrrMBIdOhteEIs85Zqj9oI/hYbl0=";
|
||||
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
@@ -56,7 +54,7 @@ stdenv.mkDerivation {
|
||||
'';
|
||||
|
||||
patches = [
|
||||
./lib-path.patch
|
||||
./gvc-path.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -68,7 +66,7 @@ stdenv.mkDerivation {
|
||||
|
||||
buildInputs = [
|
||||
gobject-introspection
|
||||
inputs.dongsu8142-nur.packages.${system}.gtk-gjs
|
||||
gjs
|
||||
gtk3
|
||||
libpulseaudio
|
||||
];
|
||||
13
nix/fix-paths.patch
Normal file
13
nix/fix-paths.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/installed-tests/debugger-test.sh b/installed-tests/debugger-test.sh
|
||||
index 0d118490..54c5507e 100755
|
||||
--- a/installed-tests/debugger-test.sh
|
||||
+++ b/installed-tests/debugger-test.sh
|
||||
@@ -3,7 +3,7 @@
|
||||
if test "$GJS_USE_UNINSTALLED_FILES" = "1"; then
|
||||
gjs="$TOP_BUILDDIR/gjs-console"
|
||||
else
|
||||
- gjs=gjs-console
|
||||
+ gjs=@gjsConsole@
|
||||
fi
|
||||
|
||||
echo 1..1
|
||||
161
nix/gjs.nix
Normal file
161
nix/gjs.nix
Normal file
@@ -0,0 +1,161 @@
|
||||
{ fetchurl
|
||||
, lib
|
||||
, stdenv
|
||||
, meson
|
||||
, mesonEmulatorHook
|
||||
, ninja
|
||||
, pkg-config
|
||||
, gnome
|
||||
, gtk3
|
||||
, atk
|
||||
, gobject-introspection
|
||||
, spidermonkey_102
|
||||
, pango
|
||||
, cairo
|
||||
, readline
|
||||
, libsysprof-capture
|
||||
, glib
|
||||
, libxml2
|
||||
, dbus
|
||||
, gdk-pixbuf
|
||||
, networkmanager
|
||||
, harfbuzz
|
||||
, makeWrapper
|
||||
, wrapGAppsHook
|
||||
, which
|
||||
, xvfb-run
|
||||
, nixosTests
|
||||
, upower
|
||||
, glib-networking
|
||||
, gtk-layer-shell
|
||||
, libdbusmenu-gtk3
|
||||
}:
|
||||
|
||||
let
|
||||
testDeps = [
|
||||
gtk3 atk pango.out gdk-pixbuf harfbuzz
|
||||
];
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "gjs";
|
||||
version = "1.76.2";
|
||||
|
||||
outputs = [ "out" "dev" "installedTests" ];
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnome/sources/gjs/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-99jJ1lPqb9eK/kpQcg4EaqK/wHj9pjXdEwZ90ZnGJdQ=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Hard-code various paths
|
||||
./fix-paths.patch
|
||||
|
||||
# Allow installing installed tests to a separate output.
|
||||
./installed-tests-path.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
makeWrapper
|
||||
wrapGAppsHook
|
||||
which # for locale detection
|
||||
libxml2 # for xml-stripblanks
|
||||
dbus # for dbus-run-session
|
||||
gobject-introspection
|
||||
] ++ lib.optionals (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
|
||||
mesonEmulatorHook
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
cairo
|
||||
upower
|
||||
gnome.gnome-bluetooth
|
||||
gtk-layer-shell
|
||||
glib-networking
|
||||
networkmanager
|
||||
readline
|
||||
libsysprof-capture
|
||||
spidermonkey_102
|
||||
libdbusmenu-gtk3
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
xvfb-run
|
||||
] ++ testDeps;
|
||||
|
||||
propagatedBuildInputs = [
|
||||
glib
|
||||
];
|
||||
|
||||
mesonFlags = [
|
||||
"-Dinstalled_test_prefix=${placeholder "installedTests"}"
|
||||
] ++ lib.optionals (!stdenv.isLinux || stdenv.hostPlatform.isMusl) [
|
||||
"-Dprofiler=disabled"
|
||||
];
|
||||
|
||||
doCheck = !stdenv.isDarwin;
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs build/choose-tests-locale.sh
|
||||
substituteInPlace installed-tests/debugger-test.sh --subst-var-by gjsConsole $out/bin/gjs-console
|
||||
'' + lib.optionalString stdenv.hostPlatform.isMusl ''
|
||||
substituteInPlace installed-tests/js/meson.build \
|
||||
--replace "'Encoding'," "#'Encoding',"
|
||||
'';
|
||||
|
||||
preCheck = ''
|
||||
# Our gobject-introspection patches make the shared library paths absolute
|
||||
# in the GIR files. When running tests, the library is not yet installed,
|
||||
# though, so we need to replace the absolute path with a local one during build.
|
||||
# We are using a symlink that will be overridden during installation.
|
||||
mkdir -p $out/lib $installedTests/libexec/installed-tests/gjs
|
||||
ln -s $PWD/libgjs.so.0 $out/lib/libgjs.so.0
|
||||
ln -s $PWD/installed-tests/js/libgimarshallingtests.so $installedTests/libexec/installed-tests/gjs/libgimarshallingtests.so
|
||||
ln -s $PWD/installed-tests/js/libgjstesttools/libgjstesttools.so $installedTests/libexec/installed-tests/gjs/libgjstesttools.so
|
||||
ln -s $PWD/installed-tests/js/libregress.so $installedTests/libexec/installed-tests/gjs/libregress.so
|
||||
ln -s $PWD/installed-tests/js/libwarnlib.so $installedTests/libexec/installed-tests/gjs/libwarnlib.so
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
# TODO: make the glib setup hook handle moving the schemas in other outputs.
|
||||
installedTestsSchemaDatadir="$installedTests/share/gsettings-schemas/${pname}-${version}"
|
||||
mkdir -p "$installedTestsSchemaDatadir"
|
||||
mv "$installedTests/share/glib-2.0" "$installedTestsSchemaDatadir"
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
wrapProgram "$installedTests/libexec/installed-tests/gjs/minijasmine" \
|
||||
--prefix XDG_DATA_DIRS : "$installedTestsSchemaDatadir" \
|
||||
--prefix GI_TYPELIB_PATH : "${lib.makeSearchPath "lib/girepository-1.0" testDeps}"
|
||||
'';
|
||||
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
xvfb-run -s '-screen 0 800x600x24' \
|
||||
meson test --print-errorlogs
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
separateDebugInfo = stdenv.isLinux;
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
installed-tests = nixosTests.installed-tests.gjs;
|
||||
};
|
||||
|
||||
updateScript = gnome.updateScript {
|
||||
packageName = "gjs";
|
||||
versionPolicy = "odd-unstable";
|
||||
};
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "JavaScript bindings for GNOME";
|
||||
homepage = "https://gitlab.gnome.org/GNOME/gjs/blob/master/doc/Home.md";
|
||||
license = licenses.lgpl2Plus;
|
||||
maintainers = teams.gnome.members;
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
}
|
||||
37
nix/installed-tests-path.patch
Normal file
37
nix/installed-tests-path.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
diff --git a/installed-tests/meson.build b/installed-tests/meson.build
|
||||
index 04c7910f..9647908c 100644
|
||||
--- a/installed-tests/meson.build
|
||||
+++ b/installed-tests/meson.build
|
||||
@@ -1,7 +1,7 @@
|
||||
### Installed tests ############################################################
|
||||
|
||||
-installed_tests_execdir = get_option('prefix') / get_option('libexecdir') / 'installed-tests' / meson.project_name()
|
||||
-installed_tests_metadir = abs_datadir / 'installed-tests' / meson.project_name()
|
||||
+installed_tests_execdir = get_option('installed_test_prefix') / 'libexec' / 'installed-tests' / meson.project_name()
|
||||
+installed_tests_metadir = get_option('installed_test_prefix') / 'share' / 'installed-tests' / meson.project_name()
|
||||
|
||||
# Simple shell script tests #
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 9ab29475..42ffe07f 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -557,7 +557,7 @@ install_data('installed-tests/extra/lsan.supp',
|
||||
install_dir: get_option('datadir') / api_name / 'lsan')
|
||||
|
||||
if get_option('installed_tests')
|
||||
- schemadir = abs_datadir / 'glib-2.0' / 'schemas'
|
||||
+ schemadir = get_option('installed_test_prefix') / 'share' / 'glib-2.0' / 'schemas'
|
||||
install_data('installed-tests/js/org.gnome.GjsTest.gschema.xml', install_dir: schemadir)
|
||||
meson.add_install_script('build/compile-gschemas.py', schemadir)
|
||||
endif
|
||||
diff --git a/meson_options.txt b/meson_options.txt
|
||||
index 825ba77a..21f0323c 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -25,3 +25,5 @@ option('skip_gtk_tests', type: 'boolean', value: false,
|
||||
description: 'Skip tests that need a display connection')
|
||||
option('verbose_logs', type: 'boolean', value: false,
|
||||
description: 'Enable extra log messages that may decrease performance (not allowed in release builds)')
|
||||
+option('installed_test_prefix', type: 'string', value: '',
|
||||
+ description: 'Prefix for installed tests')
|
||||
3470
package-lock.json
generated
3470
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
41
package.json
41
package.json
@@ -1,22 +1,23 @@
|
||||
{
|
||||
"name": "ags",
|
||||
"version": "1.0.0",
|
||||
"description": "description",
|
||||
"main": "src/main.ts",
|
||||
"repository": "",
|
||||
"author": "Aylur",
|
||||
"license": "GPL",
|
||||
"dependencies": {
|
||||
"@girs/gvc-1.0": "^1.0.0-3.1.0",
|
||||
"@girs/nm-1.0": "^1.43.1-3.1.0",
|
||||
"typescript": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint": "^8.42.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "eslint ."
|
||||
}
|
||||
"name": "ags",
|
||||
"version": "1.0.0",
|
||||
"description": "description",
|
||||
"main": "src/main.ts",
|
||||
"repository": "",
|
||||
"author": "Aylur",
|
||||
"license": "GPL",
|
||||
"dependencies": {
|
||||
"@girs/dbusmenugtk3-0.4": "^0.4.0-3.2.0",
|
||||
"@girs/gvc-1.0": "^1.0.0-3.1.0",
|
||||
"@girs/nm-1.0": "^1.43.1-3.1.0",
|
||||
"typescript": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint": "^8.42.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "eslint ."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<file>service/mpris.js</file>
|
||||
<file>service/network.js</file>
|
||||
<file>service/notifications.js</file>
|
||||
<file>service/systemtray.js</file>
|
||||
|
||||
<file>dbus/types.js</file>
|
||||
<file>dbus/com.github.Aylur.ags.xml</file>
|
||||
@@ -45,5 +46,7 @@
|
||||
<file>dbus/org.freedesktop.UPower.Device.xml</file>
|
||||
<file>dbus/org.mpris.MediaPlayer2.Player.xml</file>
|
||||
<file>dbus/org.mpris.MediaPlayer2.xml</file>
|
||||
<file>dbus/org.kde.StatusNotifierWatcher.xml</file>
|
||||
<file>dbus/org.kde.StatusNotifierItem.xml</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
50
src/dbus/org.kde.StatusNotifierItem.xml
Normal file
50
src/dbus/org.kde.StatusNotifierItem.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<node>
|
||||
<interface name="org.kde.StatusNotifierItem">
|
||||
<property name="Category" type="s" access="read"/>
|
||||
<property name="Id" type="s" access="read"/>
|
||||
<property name="Title" type="s" access="read"/>
|
||||
<property name="Status" type="s" access="read"/>
|
||||
<property name="WindowId" type="i" access="read"/>
|
||||
<property name="IconThemePath" type="s" access="read"/>
|
||||
<property name="ItemIsMenu" type="b" access="read"/>
|
||||
<property name="Menu" type="o" access="read"/>
|
||||
<property name="IconName" type="s" access="read"/>
|
||||
<property name="IconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName"
|
||||
value="KDbusImageVector"/>
|
||||
</property>
|
||||
<property name="AttentionIconName" type="s" access="read"/>
|
||||
<property name="AttentionIconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName"
|
||||
value="KDbusImageVector"/>
|
||||
</property>
|
||||
<property name="ToolTip" type="(sa(iiay)ss)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName"
|
||||
value="KDbusToolTipStruct"/>
|
||||
</property>
|
||||
<method name="ContextMenu">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="Activate">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="SecondaryActivate">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="Scroll">
|
||||
<arg name="delta" type="i" direction="in"/>
|
||||
<arg name="orientation" type="s" direction="in"/>
|
||||
</method>
|
||||
<signal name="NewTitle"/>
|
||||
<signal name="NewIcon"/>
|
||||
<signal name="NewAttentionIcon"/>
|
||||
<signal name="NewOverlayIcon"/>
|
||||
<signal name="NewToolTip"/>
|
||||
<signal name="NewStatus">
|
||||
<arg name="status" type="s"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
||||
36
src/dbus/org.kde.StatusNotifierWatcher.xml
Normal file
36
src/dbus/org.kde.StatusNotifierWatcher.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<node>
|
||||
<interface name="org.kde.StatusNotifierWatcher">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="Watcher" />
|
||||
<method name="RegisterStatusNotifierItem">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="RegisterItem" />
|
||||
<arg name="service" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="RegisterStatusNotifierHost">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="RegisterHost" />
|
||||
<arg name="service" type="s" direction="in"/>
|
||||
</method>
|
||||
<property name="RegisteredStatusNotifierItems" type="as" access="read">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="RegisteredItems" />
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
|
||||
value="QStringList"/>
|
||||
</property>
|
||||
<property name="IsStatusNotifierHostRegistered" type="b" access="read">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="IsHostRegistered" />
|
||||
</property>
|
||||
<property name="ProtocolVersion" type="i" access="read"/>
|
||||
<signal name="StatusNotifierItemRegistered">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="ItemRegistered" />
|
||||
<arg type="s" direction="out" name="service" />
|
||||
</signal>
|
||||
<signal name="StatusNotifierItemUnregistered">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="ItemUnregistered" />
|
||||
<arg type="s" direction="out" name="service" />
|
||||
</signal>
|
||||
<signal name="StatusNotifierHostRegistered">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="HostRegistered" />
|
||||
</signal>
|
||||
<signal name="StatusNotifierHostUnregistered">
|
||||
<annotation name="org.gtk.GDBus.C.Name" value="HostUnregistered" />
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -45,6 +45,27 @@ export interface BatteryProxy extends Gio.DBusProxy {
|
||||
IsPresent: boolean
|
||||
}
|
||||
|
||||
export interface StatusNotifierItemProxy extends Gio.DBusProxy {
|
||||
new(...args: unknown[]): StatusNotifierItemProxy;
|
||||
Category: string;
|
||||
Id: string;
|
||||
Title: string;
|
||||
Status: string;
|
||||
WindowId: number;
|
||||
IconThemePath: string;
|
||||
ItemIsMenu: boolean;
|
||||
Menu: string;
|
||||
IconName: string;
|
||||
IconPixmap: [number, number, Uint8Array][];
|
||||
AttentionIconName: string;
|
||||
AttentionIconPixmap: [number, number, Uint8Array][];
|
||||
ToolTip: [string, [number, number, Uint8Array], string, string];
|
||||
ContextMenuAsync: (x: number, y: number) => Promise<void>;
|
||||
ActivateAsync: (x: number, y: number) => Promise<void>;
|
||||
SecondaryActivateAsync: (x: number, y: number) => Promise<void>;
|
||||
ScrollAsync: (delta: number, orientation: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface AgsProxy extends Gio.DBusProxy {
|
||||
new(...args: unknown[]): AgsProxy
|
||||
InspectorRemote: () => void;
|
||||
@@ -56,3 +77,25 @@ export interface AgsProxy extends Gio.DBusProxy {
|
||||
busName?: string,
|
||||
objPath?: string) => void
|
||||
}
|
||||
|
||||
export interface StatusNotifierItemProxy extends Gio.DBusProxy {
|
||||
new(...args: unknown[]): StatusNotifierItemProxy;
|
||||
Category: string;
|
||||
Id: string;
|
||||
Title: string;
|
||||
Status: string;
|
||||
WindowId: number;
|
||||
IconThemePath: string;
|
||||
ItemIsMenu: boolean;
|
||||
Menu: string;
|
||||
IconName: string;
|
||||
IconPixmap: [number, number, Uint8Array][];
|
||||
AttentionIconName: string;
|
||||
AttentionIconPixmap: [number, number, Uint8Array][];
|
||||
ToolTip: [string, [number, number, Uint8Array], string, string];
|
||||
ContextMenuAsync: (x: number, y: number) => Promise<void>;
|
||||
ActivateAsync: (x: number, y: number) => Promise<void>;
|
||||
SecondaryActivateAsync: (x: number, y: number) => Promise<void>;
|
||||
ScrollAsync: (delta: number, orientation: string) => Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import Hyprland from './service/hyprland.js';
|
||||
import Mpris from './service/mpris.js';
|
||||
import Network from './service/network.js';
|
||||
import Notifications from './service/notifications.js';
|
||||
import SystemTray from './service/systemtray.js';
|
||||
|
||||
export {
|
||||
Applications,
|
||||
@@ -18,6 +19,7 @@ export {
|
||||
Mpris,
|
||||
Network,
|
||||
Notifications,
|
||||
SystemTray,
|
||||
Service,
|
||||
};
|
||||
|
||||
@@ -30,5 +32,6 @@ Service.Mpris = Mpris;
|
||||
Service.Network = Network;
|
||||
Service.Notifications = Notifications;
|
||||
Service.Service = Service;
|
||||
Service.SystemTray = SystemTray;
|
||||
|
||||
export default Service;
|
||||
|
||||
267
src/service/systemtray.ts
Normal file
267
src/service/systemtray.ts
Normal file
@@ -0,0 +1,267 @@
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Gdk from 'gi://Gdk?version=3.0';
|
||||
import Gtk from 'gi://Gtk?version=3.0';
|
||||
import GdkPixbuf from 'gi://GdkPixbuf';
|
||||
import DbusmenuGtk3 from 'gi://DbusmenuGtk3';
|
||||
import Service from './service.js';
|
||||
import { StatusNotifierItemProxy } from '../dbus/types.js';
|
||||
import { bulkConnect, loadInterfaceXML } from '../utils.js';
|
||||
import Widget from '../widget.js';
|
||||
|
||||
const StatusNotifierWatcherIFace = loadInterfaceXML('org.kde.StatusNotifierWatcher');
|
||||
const StatusNotifierItemIFace = loadInterfaceXML('org.kde.StatusNotifierItem');
|
||||
const StatusNotifierItemProxy =
|
||||
Gio.DBusProxy.makeProxyWrapper(StatusNotifierItemIFace) as StatusNotifierItemProxy;
|
||||
|
||||
export class TrayItem extends Service {
|
||||
static {
|
||||
Service.register(this, {
|
||||
'removed': ['string'],
|
||||
'ready': [],
|
||||
});
|
||||
}
|
||||
|
||||
private _proxy: StatusNotifierItemProxy;
|
||||
private _busName: string;
|
||||
|
||||
menu?: DbusmenuGtk3.Menu;
|
||||
|
||||
constructor(busName: string, objectPath: string) {
|
||||
super();
|
||||
|
||||
this._busName = busName;
|
||||
|
||||
this._proxy = new StatusNotifierItemProxy(
|
||||
Gio.DBus.session,
|
||||
busName,
|
||||
objectPath,
|
||||
this._itemProxyAcquired.bind(this),
|
||||
null,
|
||||
Gio.DBusProxyFlags.NONE);
|
||||
}
|
||||
|
||||
activate(event: Gdk.Event) {
|
||||
this._proxy.ActivateAsync(event.get_root_coords()[1], event.get_root_coords()[2]);
|
||||
}
|
||||
|
||||
secondaryActivate(event: Gdk.Event) {
|
||||
this._proxy.SecondaryActivateAsync(event.get_root_coords()[1], event.get_root_coords()[2]);
|
||||
}
|
||||
|
||||
scroll(event: Gdk.EventScroll) {
|
||||
const direction =
|
||||
(event.direction == 0 || event.direction == 1) ? 'vertical' : 'horizontal';
|
||||
const delta =
|
||||
(event.direction == 0 || event.direction == 1) ? event.delta_y : event.delta_x;
|
||||
this._proxy.ScrollAsync(delta, direction);
|
||||
}
|
||||
|
||||
openMenu(event: Gdk.Event) {
|
||||
this.menu // DbusmenuGtk3 imports the gdk type from @girs
|
||||
? (this.menu as unknown as Gtk.Menu).popup_at_pointer(event)
|
||||
: this._proxy.ContextMenuAsync(event.get_root_coords()[1], event.get_root_coords()[2]);
|
||||
}
|
||||
|
||||
get category() { return this._proxy.Category; }
|
||||
get id() { return this._proxy.Id; }
|
||||
get title() { return this._proxy.Title; }
|
||||
get status() { return this._proxy.Status; }
|
||||
get windowId() { return this._proxy.WindowId; }
|
||||
get isMenu() { return this._proxy.ItemIsMenu; }
|
||||
|
||||
get tooltipMarkup() {
|
||||
if (!this._proxy.ToolTip)
|
||||
return '';
|
||||
|
||||
let tooltipMarkup = this._proxy.ToolTip[2];
|
||||
if (this._proxy.ToolTip[3] !== '')
|
||||
tooltipMarkup += '\n' + this._proxy.ToolTip[3];
|
||||
return tooltipMarkup;
|
||||
}
|
||||
|
||||
get icon() {
|
||||
let icon;
|
||||
if (this.status === 'NeedsAttention') {
|
||||
icon = this._proxy.AttentionIconName
|
||||
? this._proxy.AttentionIconName
|
||||
: this._getPixbuf(this._proxy.AttentionIconPixmap);
|
||||
}
|
||||
else {
|
||||
icon = this._proxy.IconName
|
||||
? this._proxy.IconName
|
||||
: this._getPixbuf(this._proxy.IconPixmap);
|
||||
}
|
||||
|
||||
return icon || 'image-missing';
|
||||
}
|
||||
|
||||
private _itemProxyAcquired(proxy: StatusNotifierItemProxy) {
|
||||
if (proxy.Menu) {
|
||||
const menu = Widget({
|
||||
// @ts-expect-error
|
||||
type: DbusmenuGtk3.Menu,
|
||||
dbus_name: proxy.g_name_owner,
|
||||
dbus_object: proxy.Menu,
|
||||
});
|
||||
this.menu = (menu as unknown) as DbusmenuGtk3.Menu;
|
||||
}
|
||||
|
||||
bulkConnect(proxy, [
|
||||
['notify::g-name-owner', () => {
|
||||
if (!proxy.g_name_owner)
|
||||
this.emit('removed', this._busName);
|
||||
}],
|
||||
['g-signal', () => {
|
||||
this._refreshAllProperties();
|
||||
this.emit('changed');
|
||||
}],
|
||||
['g-properties-changed', () => this.emit('changed')],
|
||||
]);
|
||||
|
||||
['Title', 'Icon', 'AttentionIcon', 'OverlayIcon', 'ToolTip', 'Status']
|
||||
.forEach(prop => proxy.connectSignal(`New${prop}`, () => {
|
||||
this.emit('changed');
|
||||
}));
|
||||
|
||||
this.emit('ready');
|
||||
}
|
||||
|
||||
private _refreshAllProperties() {
|
||||
const variant = this._proxy.g_connection.call_sync(
|
||||
this._proxy.g_name,
|
||||
this._proxy.g_object_path,
|
||||
'org.freedesktop.DBus.Properties',
|
||||
'GetAll',
|
||||
GLib.Variant.new('(s)', [this._proxy.g_interface_name]),
|
||||
GLib.VariantType.new('(a{sv})'),
|
||||
Gio.DBusCallFlags.NONE, -1,
|
||||
null,
|
||||
) as GLib.Variant<'(a{sv})'>;
|
||||
|
||||
const [properties] = variant.deep_unpack();
|
||||
Object.entries(properties).map(([propertyName, value]) => {
|
||||
this._proxy.set_cached_property(propertyName, value);
|
||||
});
|
||||
}
|
||||
|
||||
private _getPixbuf(pixMapArray: [number, number, Uint8Array][]) {
|
||||
if (!pixMapArray)
|
||||
return;
|
||||
|
||||
const pixMap = pixMapArray.sort((a, b) => a[0] - b[0]).pop();
|
||||
if (!pixMap)
|
||||
return;
|
||||
|
||||
const array = Uint8Array.from(pixMap[2]);
|
||||
for (let i = 0; i < 4 * pixMap[0] * pixMap[1]; i += 4) {
|
||||
const alpha = array[i];
|
||||
array[i] = array[i + 1];
|
||||
array[i + 1] = array[i + 2];
|
||||
array[i + 2] = array[i + 3];
|
||||
array[i + 3] = alpha;
|
||||
}
|
||||
return GdkPixbuf.Pixbuf.new_from_bytes(
|
||||
array,
|
||||
GdkPixbuf.Colorspace.RGB,
|
||||
true,
|
||||
8,
|
||||
pixMap[0],
|
||||
pixMap[1],
|
||||
pixMap[0] * 4,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SystemTrayService extends Service {
|
||||
static {
|
||||
Service.register(this, {
|
||||
'added': ['string'],
|
||||
'removed': ['string'],
|
||||
});
|
||||
}
|
||||
|
||||
private _dbus!: Gio.DBusExportedObject;
|
||||
private _items: Map<string, TrayItem>;
|
||||
|
||||
get IsStatusNotifierHostRegistered() { return true; }
|
||||
get ProtocolVersion() { return 0; }
|
||||
get RegisteredStatusNotifierItems() { return Array.from(this._items.keys()); }
|
||||
get items() { return this._items; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._items = new Map();
|
||||
this._register();
|
||||
}
|
||||
|
||||
private _register() {
|
||||
Gio.bus_own_name(
|
||||
Gio.BusType.SESSION,
|
||||
'org.kde.StatusNotifierWatcher',
|
||||
Gio.BusNameOwnerFlags.NONE,
|
||||
(connection: Gio.DBusConnection) => {
|
||||
this._dbus = Gio.DBusExportedObject
|
||||
.wrapJSObject(StatusNotifierWatcherIFace as string, this);
|
||||
|
||||
this._dbus.export(connection, '/StatusNotifierWatcher');
|
||||
},
|
||||
null,
|
||||
() => {
|
||||
print('Another system tray is already running');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
RegisterStatusNotifierItemAsync(serviceName: string[], invocation: Gio.DBusMethodInvocation) {
|
||||
let busName: string, objectPath: string;
|
||||
const [service] = serviceName;
|
||||
if (service.startsWith('/')) {
|
||||
objectPath = service;
|
||||
busName = invocation.get_sender();
|
||||
} else {
|
||||
busName = service;
|
||||
objectPath = '/StatusNotifierItem';
|
||||
}
|
||||
|
||||
invocation.return_value(null);
|
||||
|
||||
const item = new TrayItem(busName, objectPath);
|
||||
item.connect('ready', () => {
|
||||
this._items.set(busName, item);
|
||||
this.emit('added', busName);
|
||||
this.emit('changed');
|
||||
this._dbus.emit_signal(
|
||||
'StatusNotifierItemRegistered',
|
||||
new GLib.Variant('(s)', [busName + objectPath]),
|
||||
);
|
||||
});
|
||||
item.connect('removed', () => {
|
||||
this._items.delete(busName);
|
||||
this.emit('removed', busName);
|
||||
this.emit('changed');
|
||||
this._dbus.emit_signal(
|
||||
'StatusNotifierItemUnregistered',
|
||||
new GLib.Variant('(s)', [busName]),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getItem(name: string) {
|
||||
return this._items.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class SystemTray {
|
||||
static _instance: SystemTrayService;
|
||||
|
||||
static get instance() {
|
||||
Service.ensureInstance(SystemTray, SystemTrayService);
|
||||
return SystemTray._instance;
|
||||
}
|
||||
|
||||
static get items() { return Array.from(SystemTray.instance.items.values()); }
|
||||
static getItem(name: string) { return SystemTray._instance.getItem(name); }
|
||||
}
|
||||
|
||||
@@ -6,66 +6,56 @@ import { Context } from 'gi-types/cairo1';
|
||||
|
||||
export default class AgsIcon extends Gtk.Image {
|
||||
static {
|
||||
GObject.registerClass({
|
||||
GTypeName: 'AgsIcon',
|
||||
Properties: {
|
||||
'size': GObject.ParamSpec.int(
|
||||
'size', 'Size', 'Size',
|
||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
|
||||
0, 1024, 0,
|
||||
),
|
||||
'icon': GObject.ParamSpec.string(
|
||||
'icon', 'Icon', 'Icon',
|
||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
|
||||
'',
|
||||
),
|
||||
},
|
||||
}, this);
|
||||
GObject.registerClass({ GTypeName: 'AgsIcon' }, this);
|
||||
}
|
||||
|
||||
constructor(params: object | string) {
|
||||
constructor(params: object | string | GdkPixbuf.Pixbuf) {
|
||||
const {
|
||||
icon = '',
|
||||
size = 0,
|
||||
} = params as { icon: string, size: number };
|
||||
super(typeof params === 'string' ? { icon: params } : params);
|
||||
...rest
|
||||
} = params as { icon: string | GdkPixbuf.Pixbuf, size: number };
|
||||
super(typeof params === 'string' || params instanceof GdkPixbuf.Pixbuf ? {} : rest);
|
||||
|
||||
// set correct size after construct
|
||||
if (typeof params === 'object') {
|
||||
this.size = size;
|
||||
this.icon = icon;
|
||||
}
|
||||
this.size = size;
|
||||
this.icon = typeof params === 'string' || params instanceof GdkPixbuf.Pixbuf
|
||||
? params : icon;
|
||||
}
|
||||
|
||||
_size = 0;
|
||||
_previousSize = 0;
|
||||
get size() { return this._size || this._previousSize || 13; }
|
||||
set size(size: number) {
|
||||
size ||= 0;
|
||||
this._size = size;
|
||||
this.queue_draw();
|
||||
}
|
||||
|
||||
_file = false;
|
||||
_icon = '';
|
||||
_type!: 'file' | 'named' | 'pixbuf';
|
||||
_icon: string | GdkPixbuf.Pixbuf = '';
|
||||
get icon() { return this._icon; }
|
||||
set icon(icon: string) {
|
||||
set icon(icon: string | GdkPixbuf.Pixbuf) {
|
||||
if (!icon || this._icon === icon)
|
||||
return;
|
||||
|
||||
this._icon = icon;
|
||||
if (GLib.file_test(icon, GLib.FileTest.EXISTS)) {
|
||||
this._file = true;
|
||||
if (typeof icon === 'string') {
|
||||
if (GLib.file_test(icon, GLib.FileTest.EXISTS)) {
|
||||
this._type = 'file';
|
||||
this.set_from_pixbuf(
|
||||
GdkPixbuf.Pixbuf.new_from_file_at_size(icon, this.size, this.size));
|
||||
} else {
|
||||
this._type = 'named';
|
||||
this.icon_name = icon;
|
||||
this.pixel_size = this.size;
|
||||
}
|
||||
}
|
||||
else if (icon instanceof GdkPixbuf.Pixbuf) {
|
||||
this._type = 'pixbuf';
|
||||
this.set_from_pixbuf(
|
||||
GdkPixbuf.Pixbuf.new_from_file_at_size(
|
||||
icon, this.size, this.size,
|
||||
),
|
||||
);
|
||||
icon.scale_simple(this.size, this.size, GdkPixbuf.InterpType.BILINEAR));
|
||||
}
|
||||
else {
|
||||
this._file = false;
|
||||
this.icon_name = icon;
|
||||
this.pixel_size = this.size;
|
||||
logError(new Error(`expected Pixbuf or string for icon, but got ${typeof icon}`));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +71,20 @@ export default class AgsIcon extends Gtk.Image {
|
||||
|
||||
this._previousSize = size;
|
||||
|
||||
if (this._file) {
|
||||
this.set_from_pixbuf(
|
||||
GdkPixbuf.Pixbuf.new_from_file_at_size(this.icon, size, size),
|
||||
);
|
||||
} else {
|
||||
this.pixel_size = size;
|
||||
switch (this._type) {
|
||||
case 'file':
|
||||
this.set_from_pixbuf(
|
||||
GdkPixbuf.Pixbuf.new_from_file_at_size(this.icon as string, size, size));
|
||||
break;
|
||||
case 'pixbuf':
|
||||
this.set_from_pixbuf((this.icon as GdkPixbuf.Pixbuf).scale_simple(
|
||||
this.size, this.size, GdkPixbuf.InterpType.BILINEAR));
|
||||
break;
|
||||
case 'named':
|
||||
this.set_pixel_size(size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return super.vfunc_draw(cr);
|
||||
|
||||
@@ -67,7 +67,8 @@ export class AgsMenuItem extends Gtk.MenuItem {
|
||||
onSelect = '',
|
||||
onDeselect = '',
|
||||
...rest
|
||||
}: { [key: string]: Command }) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
}: { [key: string]: any }) {
|
||||
super(rest);
|
||||
|
||||
this.onActivate = onActivate;
|
||||
|
||||
@@ -126,20 +126,16 @@ export default class AgsWindow 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;
|
||||
|
||||
39
types/ambient.d.ts
vendored
39
types/ambient.d.ts
vendored
@@ -4,41 +4,41 @@ declare function log(msg: string, subsitutions?: any[]): void;
|
||||
declare function logError(err: Error, msg?: string): void;
|
||||
|
||||
declare const pkg: {
|
||||
version: string;
|
||||
name: string;
|
||||
version: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
declare const imports: {
|
||||
config: any;
|
||||
gi: any;
|
||||
searchPath: string[];
|
||||
config: any;
|
||||
gi: any;
|
||||
searchPath: string[];
|
||||
}
|
||||
|
||||
declare module console {
|
||||
export function error(obj: object, others?: object[]): void;
|
||||
export function error(msg: string, subsitutions?: any[]): void;
|
||||
export function error(obj: object, others?: object[]): void;
|
||||
export function error(msg: string, subsitutions?: any[]): void;
|
||||
}
|
||||
|
||||
declare interface String {
|
||||
format(...replacements: string[]): string;
|
||||
format(...replacements: number[]): string;
|
||||
format(...replacements: string[]): string;
|
||||
format(...replacements: number[]): string;
|
||||
}
|
||||
|
||||
declare interface Number {
|
||||
toFixed(digits: number): number;
|
||||
toFixed(digits: number): number;
|
||||
}
|
||||
|
||||
declare class TextDecoder {
|
||||
constructor(label?: string, options?: TextDecoderOptions);
|
||||
decode(input?: BufferSource, options?: TextDecodeOptions): string;
|
||||
readonly encoding: string;
|
||||
readonly fatal: boolean;
|
||||
readonly ignoreBOM: boolean;
|
||||
constructor(label?: string, options?: TextDecoderOptions);
|
||||
decode(input?: BufferSource, options?: TextDecodeOptions): string;
|
||||
readonly encoding: string;
|
||||
readonly fatal: boolean;
|
||||
readonly ignoreBOM: boolean;
|
||||
}
|
||||
|
||||
declare class TextEncoder {
|
||||
constructor();
|
||||
encode(input?: string): Uint8Array;
|
||||
constructor();
|
||||
encode(input?: string): Uint8Array;
|
||||
}
|
||||
|
||||
declare module 'gi://Gvc' {
|
||||
@@ -50,3 +50,8 @@ declare module 'gi://NM' {
|
||||
import NM10 from '@girs/nm-1.0';
|
||||
export default NM10;
|
||||
}
|
||||
|
||||
declare module 'gi://DbusmenuGtk3' {
|
||||
import Dbusmenu from '@girs/dbusmenugtk3-0.4';
|
||||
export default Dbusmenu;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user