diff --git a/README.md b/README.md
deleted file mode 100644
index ccbc579..0000000
--- a/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# This is my Hyprland dotfiles
-
-## To install all configs you need to create backup your configurations and start
-```bash
-./install_scripts/install.sh
-```
-### or
-```bash
-~/dotfiles/install_scripts/install.sh
-```
-## Full install commands
-```bash
-cd ~/
-git clone https://github.com/TolaMironcenko/hyprland_dotfiles.git dotfiles
-cd ~/dotfiles/install_scripts
-./install.sh
-```
-
-## Keybinds
-| key | doing |
-| --- | ----- |
-| mainMod | alt |
-| mainMod + q | close window |
-| mainMod + v | toggle floating window |
-| mainMod + return | open terminal (kitty as default) |
-| mainMod + d | open rofi launcher |
-| mainMod + shift + p | open rofi powermenu |
-| mainMod + c | open rofi greenclip |
-| mainMod + b | open hyprlock |
-| mainMod + shift + c | do screenshot in clipboard |
-| mainMod + [1 ... 0] | open workspase [1 ... 10] |
-| mainMod + x | open xpad |
-| mainMod + shift + x | open new note in xpad |
-| mainMod + a | open telegram-desktop |
-| mainMod + g | open google-chrome-stable |
-
-## To install system (Arch Linux) you can change file install_scripts/install-arch.sh
-### and start
-```bash
-./install-arch.sh
-```
diff --git a/ags/HyprPanel/.eslintignore b/ags/HyprPanel/.eslintignore
deleted file mode 100644
index 980d7f4..0000000
--- a/ags/HyprPanel/.eslintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-types
-node_modules
diff --git a/ags/HyprPanel/.eslintrc.js b/ags/HyprPanel/.eslintrc.js
deleted file mode 100644
index b650cfe..0000000
--- a/ags/HyprPanel/.eslintrc.js
+++ /dev/null
@@ -1,25 +0,0 @@
-module.exports = {
- parser: '@typescript-eslint/parser',
- parserOptions: {
- project: 'tsconfig.json',
- tsconfigRootDir: __dirname,
- sourceType: 'module',
- },
- plugins: ['@typescript-eslint', 'import'],
- extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
- root: true,
- ignorePatterns: ['.eslintrc.js', 'types/**/*.ts', 'scripts/**/*.js'],
- env: {
- es6: true,
- browser: true,
- },
- rules: {
- '@typescript-eslint/interface-name-prefix': 'off',
- '@typescript-eslint/explicit-function-return-type': 'error',
- '@typescript-eslint/explicit-module-boundary-types': 'error',
- '@typescript-eslint/no-explicit-any': 'error',
- 'import/extensions': ['off'],
- 'import/no-unresolved': 'off',
- quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: true }],
- },
-};
diff --git a/ags/HyprPanel/.github/ISSUE_TEMPLATE/bug_report.md b/ags/HyprPanel/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index e41ef8d..0000000
--- a/ags/HyprPanel/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-name: Bug report
-about: Create a report to help HyprPanel improve
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Describe the bug**
-A clear and concise description of what the bug is.
-
-**To Reproduce**
-Steps to reproduce the behavior:
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Desktop (please complete the following information):**
- - Distribution: [e.g. Arch Linux]
- - Window Manager/Desktop Environment: [e.g. Hyprland]
-
-**Additional context**
-Add any other context about the problem here.
diff --git a/ags/HyprPanel/.github/ISSUE_TEMPLATE/feature_request.md b/ags/HyprPanel/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index bbcbbe7..0000000
--- a/ags/HyprPanel/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/ags/HyprPanel/.github/workflows/ci.yml b/ags/HyprPanel/.github/workflows/ci.yml
deleted file mode 100644
index 27ec51a..0000000
--- a/ags/HyprPanel/.github/workflows/ci.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: CI
-
-on:
- pull_request:
- branches:
- - master
-
-jobs:
- code_quality:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout main repository
- uses: actions/checkout@v3
-
- - name: Clone ags-types to temp dir
- uses: actions/checkout@v3
- with:
- repository: Jas-SinghFSU/ags-types
- path: temp-ags-types
-
- - name: Copy types to types/
- run: |
- rm -rf types
- mkdir -p types
- cp -R temp-ags-types/types/* types/
- rm -rf temp-ags-types
-
- - name: Node Setup
- uses: actions/setup-node@v3
- with:
- node-version: '21'
-
- - name: Install Dependencies
- run: npm install
-
- - name: ESLint
- run: npm run lint
-
- - name: Type Check
- run: npx tsc --noEmit --pretty --extendedDiagnostics
diff --git a/ags/HyprPanel/.gitignore b/ags/HyprPanel/.gitignore
deleted file mode 100644
index 9144fba..0000000
--- a/ags/HyprPanel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.weather.json
-node_modules
diff --git a/ags/HyprPanel/.gitmodules b/ags/HyprPanel/.gitmodules
deleted file mode 100644
index b165aa5..0000000
--- a/ags/HyprPanel/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "external/ags-types"]
- path = external/ags-types
- url = https://github.com/Jas-SinghFSU/ags-types.git
diff --git a/ags/HyprPanel/.prettierignore b/ags/HyprPanel/.prettierignore
deleted file mode 100644
index 97843e6..0000000
--- a/ags/HyprPanel/.prettierignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.eslintrc.js
-types/**/*.ts
diff --git a/ags/HyprPanel/.prettierrc b/ags/HyprPanel/.prettierrc
deleted file mode 100644
index 6e88f12..0000000
--- a/ags/HyprPanel/.prettierrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "singleQuote": true,
- "semi": true,
- "trailingComma": "all",
- "printWidth": 120,
- "tabWidth": 4,
- "useTabs": false
-}
diff --git a/ags/HyprPanel/LICENSE b/ags/HyprPanel/LICENSE
deleted file mode 100644
index 75c0349..0000000
--- a/ags/HyprPanel/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Jas Singh
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/ags/HyprPanel/README.md b/ags/HyprPanel/README.md
deleted file mode 100644
index bca09ea..0000000
--- a/ags/HyprPanel/README.md
+++ /dev/null
@@ -1,317 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-# HyprPanel 🚀
-
-A panel built for Hyprland with [AGS](https://github.com/Aylur/ags)
-
-
-
-
-## Installation
-
-The [HyprPanel Wiki](https://hyprpanel.com/getting_started/installation.html) contains in depth instructions for installing the panel and all of its dependencies. The instructions below are general instructions for installing the panel.
-
-## Requirements
-
-Bun
-
-```sh
-curl -fsSL https://bun.sh/install | bash && \
- sudo ln -s $HOME/.bun/bin/bun /usr/local/bin/bun
-```
-
-Additional dependencies:
-
-```sh
-pipewire
-libgtop
-bluez
-bluez-utils
-grimblast
-gpu-screen-recorder
-hyprpicker
-btop
-networkmanager
-matugen
-wl-clipboard
-swww
-dart-sass
-brightnessctl
-gnome-bluetooth-3.0
-```
-
-Optional Dependencies:
-
-```sh
-## Used for Tracking GPU Usage in your Dashboard (NVidia only)
-python
-python-gpustat
-
-## Only if a pywal hook from wallpaper changes applied through settings is desired
-pywal
-
-## To check for pacman updates in the default script used in the updates module
-pacman-contrib
-
-## To switch between power profiles in battery module
-power-profiles-daemon
-```
-
-### Arch
-
-pacman:
-
-```bash
-sudo pacman -S pipewire libgtop bluez bluez-utils btop networkmanager dart-sass wl-clipboard brightnessctl swww python gnome-bluetooth-3.0 pacman-contrib power-profiles-daemon
-```
-
-AUR:
-
-```bash
-yay -S grimblast-git gpu-screen-recorder hyprpicker matugen-bin python-gpustat aylurs-gtk-shell-git
-```
-
-### Fedora
-
-COPR - Add [solopasha/hyprland](https://copr.fedorainfracloud.org/coprs/solopasha/hyprland/) for most hyprland-related dependencies, and [hues-sueh/packages](https://copr.fedorainfracloud.org/coprs/heus-sueh/packages/) for matugen. Both provide the `swww` package, so prioritise the former repo:
-
-```bash
-sudo dnf copr enable solopasha/hyprland
-sudo dnf copr enable heus-sueh/packages
-sudo dnf config-manager --save --setopt=copr:copr.fedorainfracloud.org:heus-sueh:packages.priority=200
-```
-
-DNF:
-
-```bash
-sudo dnf install pipewire libgtop2 bluez bluez-tools grimblast hyprpicker btop NetworkManager wl-clipboard swww brightnessctl gnome-bluetooth aylurs-gtk-shell power-profiles-daemon gvfs
-```
-
-bun:
-
-```bash
-bun install -g sass
-```
-
-flatpak:
-
-```bash
-flatpak install flathub --system com.dec05eba.gpu_screen_recorder
-```
-
-#### Optional Dependencies
-
-pip:
-
-```bash
-sudo dnf install python python3-pip; pip install gpustat pywal
-```
-
-### NixOS
-
-For NixOS/Home-Manager, see [NixOS & Home-Manager instructions](#nixos--home-manager).
-
-## Instructions
-
-### AGS
-
-Once everything is installed you need to put the contents of this repo in `~/.config/ags`.
-If you already have something in `~/.config/ags`, it's recommended that you back it up with:
-
-```bash
-mv $HOME/.config/ags $HOME/.config/ags.bkup
-```
-
-Otherwise you can use this command to install the panel:
-
-```bash
-git clone https://github.com/Jas-SinghFSU/HyprPanel.git && \
- ln -s $(pwd)/HyprPanel $HOME/.config/ags
-```
-
-### Nerd Fonts
-
-Additionally, you need to ensure that you have a [Nerd Font](https://www.nerdfonts.com/font-downloads) installed for your icons to render properly.
-
-### Launch the panel
-
-Afterwards you can run the panel with the following command in your terminal:
-
-```bash
-ags
-```
-
-Or you can add it to your Hyprland config (hyprland.conf) to auto-start with:
-
-```bash
-exec-once = ags
-```
-
-### NixOS & Home-Manager
-
-Alternatively, if you're using NixOS and/or Home-Manager, you can setup AGS using the provided Nix Flake. First, add the repository to your Flake's inputs, and enable the overlay.
-
-```nix
-# flake.nix
-
-{
- inputs.hyprpanel.url = "github:Jas-SinghFSU/HyprPanel";
- # ...
-
- outputs = { self, nixpkgs, ... }@inputs:
- let
- # ...
- system = "x86_64-linux"; # change to whatever your system should be.
- pkgs = import nixpkgs {
- inherit system;
- # ...
- overlays = [
- inputs.hyprpanel.overlay
- ];
- };
- in {
- # ...
- }
-}
-```
-
-Once you've set up the overlay, you can reference HyprPanel with `pkgs.hyprpanel` as if it were any other Nix package. This means you can reference it as a NixOS system/user package, a Home-Manager user package, or as a direct reference in your Hyprland configuration (if your configuration is managed by Home-Manager). The first three methods will add it to your `$PATH` (first globally, second two user-only), however the final will not.
-
-```nix
-# configuration.nix
-
-# install it as a system package
-environment.systemPackages = with pkgs; [
- # ...
- hyprpanel
- # ...
-];
-
-# or install it as a user package
-users.users..packages = with pkgs; [
- # ...
- hyprpanel
- # ...
-];
-
-
-# home.nix
-
-# install it as a user package with home-manager
-home.packages = with pkgs; [
- # ...
- hyprpanel
- # ...
-];
-
-# or reference it directly in your Hyprland configuration
-wayland.windowManager.hyprland.settings.exec-once = [
- "${pkgs.hyprpanel}/bin/hyprpanel"
-];
-
-```
-
-### Notifications
-
-HyprPanel handles notifications through the AGS built-in notification service. If you're already using a notification daemon such as Dunst or Mako, you may have to stop them to prevent conflicts with HyprPanel.
-
-> NOTE: If your system is in a language other than English, the resource monitor in the dashboard may not work properly.
-
-## Configuration
-
-The HyprPanel comes with a configuration menu which is available by opening the Dashboard menu (click the button in the bar with the default - Arch - icon) and then clicking the Gear icon.
-
-### Size
-
-The panel is automatically scaled based on your font size in `Configuration > General`.
-
-### Specifying bar layouts per monitor
-
-To specify layouts for each monitor you can create a JSON object such as:
-
-```JSON
-{
- "0": {
- "left": [
- "dashboard",
- "workspaces",
- "windowtitle"
- ],
- "middle": [
- "media"
- ],
- "right": [
- "volume",
- "clock",
- "notifications"
- ]
- },
- "1": {
- "left": [
- "dashboard",
- "workspaces",
- "windowtitle"
- ],
- "middle": [
- "media"
- ],
- "right": [
- "volume",
- "clock",
- "notifications"
- ]
- },
- "2": {
- "left": [
- "dashboard",
- "workspaces",
- "windowtitle"
- ],
- "middle": [
- "media"
- ],
- "right": [
- "volume",
- "network",
- "bluetooth",
- "systray",
- "clock",
- "notifications"
- ]
- }
-}
-```
-
-Where each monitor is defined by its index (0, 1, 2 in this case) and each section (left, middle, right) contains one or more of the following modules:
-
-```js
-'battery';
-'dashboard';
-'workspaces';
-'windowtitle';
-'media';
-'notifications';
-'volume';
-'network';
-'bluetooth';
-'clock';
-'systray';
-```
-
-Since the text-box in the options dialog isn't sufficient, it is recommended that you create this JSON configuration in a text editor elsewhere and paste it into the layout text-box under Configuration > Bar > "Bar Layouts for Monitors".
-
-### Additional Configuration
-
-#### GPU Tracking
-
-If you have an NVidia GPU, you can track your GPU usage in your Dashboard by going to your `Settings > Configuration > Dashboard Menu > Track GPU` and turning it on.
diff --git a/ags/HyprPanel/assets/21210205.png b/ags/HyprPanel/assets/21210205.png
deleted file mode 100644
index c1f3edc..0000000
Binary files a/ags/HyprPanel/assets/21210205.png and /dev/null differ
diff --git a/ags/HyprPanel/assets/HyprPanel.png b/ags/HyprPanel/assets/HyprPanel.png
deleted file mode 100644
index 3ea158a..0000000
Binary files a/ags/HyprPanel/assets/HyprPanel.png and /dev/null differ
diff --git a/ags/HyprPanel/assets/Mocha_Wolf.png b/ags/HyprPanel/assets/Mocha_Wolf.png
deleted file mode 100644
index 219857c..0000000
Binary files a/ags/HyprPanel/assets/Mocha_Wolf.png and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Bold.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Bold.ttf
deleted file mode 100644
index 3bed27f..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Bold.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-ExtraBold.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-ExtraBold.ttf
deleted file mode 100644
index 99cfe5b..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-ExtraBold.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-ExtraLight.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-ExtraLight.ttf
deleted file mode 100644
index 1e8103b..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-ExtraLight.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Light.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Light.ttf
deleted file mode 100644
index 82dcd0b..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Light.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Medium.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Medium.ttf
deleted file mode 100644
index d134c56..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Medium.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Regular.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Regular.ttf
deleted file mode 100644
index de31c48..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Regular.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-SemiBold.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-SemiBold.ttf
deleted file mode 100644
index 059f6b3..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-SemiBold.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Thin.ttf b/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Thin.ttf
deleted file mode 100644
index 8aad716..0000000
Binary files a/ags/HyprPanel/assets/fonts/JetBrainsMonoNerdFontPropo-Thin.ttf and /dev/null differ
diff --git a/ags/HyprPanel/assets/hp1.png b/ags/HyprPanel/assets/hp1.png
deleted file mode 100644
index e42b363..0000000
Binary files a/ags/HyprPanel/assets/hp1.png and /dev/null differ
diff --git a/ags/HyprPanel/assets/hp2.png b/ags/HyprPanel/assets/hp2.png
deleted file mode 100644
index a912e32..0000000
Binary files a/ags/HyprPanel/assets/hp2.png and /dev/null differ
diff --git a/ags/HyprPanel/assets/hyprpanel.png b/ags/HyprPanel/assets/hyprpanel.png
deleted file mode 100644
index b4707c0..0000000
Binary files a/ags/HyprPanel/assets/hyprpanel.png and /dev/null differ
diff --git a/ags/HyprPanel/assets/solar_system_mocha.png b/ags/HyprPanel/assets/solar_system_mocha.png
deleted file mode 100644
index 14ca154..0000000
Binary files a/ags/HyprPanel/assets/solar_system_mocha.png and /dev/null differ
diff --git a/ags/HyprPanel/config.js b/ags/HyprPanel/config.js
deleted file mode 100644
index 01d6ae8..0000000
--- a/ags/HyprPanel/config.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import GLib from 'gi://GLib';
-
-const main = '/tmp/ags/hyprpanel/main.js';
-const entry = `${App.configDir}/main.ts`;
-const bundler = GLib.getenv('AGS_BUNDLER') || 'bun';
-
-const v = {
- ags: pkg.version?.split('.').map(Number) || [],
- expect: [1, 8, 1],
-};
-
-try {
- switch (bundler) {
- case 'bun':
- await Utils.execAsync([
- 'bun',
- 'build',
- entry,
- '--outfile',
- main,
- '--external',
- 'resource://*',
- '--external',
- 'gi://*',
- '--external',
- 'file://*',
- ]);
- break;
-
- case 'esbuild':
- await Utils.execAsync([
- 'esbuild',
- '--bundle',
- entry,
- '--format=esm',
- `--outfile=${main}`,
- '--external:resource://*',
- '--external:gi://*',
- '--external:file://*',
- ]);
- break;
-
- default:
- throw `"${bundler}" is not a valid bundler`;
- }
-
- if (v.ags[1] < v.expect[1] || v.ags[2] < v.expect[2]) {
- print(`HyprPanel needs atleast v${v.expect.join('.')} of AGS, yours is v${v.ags.join('.')}`);
- App.quit();
- }
-
- await import(`file://${main}`);
-} catch (error) {
- console.error(error);
- App.quit();
-}
-
-export {};
diff --git a/ags/HyprPanel/customModules/PollVar.ts b/ags/HyprPanel/customModules/PollVar.ts
deleted file mode 100644
index 2381e89..0000000
--- a/ags/HyprPanel/customModules/PollVar.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import GLib from 'gi://GLib?version=2.0';
-import { GenericFunction } from 'lib/types/customModules/generic';
-import { Bind } from 'lib/types/variable';
-import { Variable as VariableType } from 'types/variable';
-
-/**
- * @param {VariableType} targetVariable - The Variable to update with the function's result.
- * @param {Array} trackers - Array of trackers to watch.
- * @param {Bind} pollingInterval - The polling interval in milliseconds.
- * @param {GenericFunction} someFunc - The function to execute at each interval, which updates the Variable.
- * @param {...P} params - Parameters to pass to someFunc.
- */
-export const pollVariable = >(
- targetVariable: VariableType,
- trackers: Array,
- pollingInterval: Bind,
- someFunc: F,
- ...params: P
-): void => {
- let intervalInstance: number | null = null;
-
- const intervalFn = (pollIntrvl: number): void => {
- if (intervalInstance !== null) {
- GLib.source_remove(intervalInstance);
- }
-
- intervalInstance = Utils.interval(pollIntrvl, () => {
- targetVariable.value = someFunc(...params);
- });
- };
-
- Utils.merge([pollingInterval, ...trackers], (pollIntrvl: number) => {
- intervalFn(pollIntrvl);
- });
-};
-
-/**
- * @param {VariableType} targetVariable - The Variable to update with the result of the command.
- * @param {Array} trackers - Array of trackers to watch.
- * @param {Bind} pollingInterval - The polling interval in milliseconds.
- * @param {string} someCommand - The bash command to execute.
- * @param {GenericFunction} someFunc - The function to execute after processing the command result;
- * with the first argument being the result of the command execution.
- * @param {...P} params - Additional parameters to pass to someFunc.
- */
-export const pollVariableBash = >(
- targetVariable: VariableType,
- trackers: Array,
- pollingInterval: Bind,
- someCommand: string,
- someFunc: F,
- ...params: P
-): void => {
- let intervalInstance: number | null = null;
-
- const intervalFn = (pollIntrvl: number): void => {
- if (intervalInstance !== null) {
- GLib.source_remove(intervalInstance);
- }
-
- intervalInstance = Utils.interval(pollIntrvl, () => {
- Utils.execAsync(`bash -c "${someCommand}"`)
- .then((res: string) => {
- try {
- targetVariable.value = someFunc(res, ...params);
- } catch (error) {
- console.warn(`An error occurred when running interval bash function: ${error}`);
- }
- })
- .catch((err) => console.error(`Error running command "${someCommand}": ${err}`));
- });
- };
-
- Utils.merge([pollingInterval, ...trackers], (pollIntrvl: number) => {
- intervalFn(pollIntrvl);
- });
-};
diff --git a/ags/HyprPanel/customModules/config.ts b/ags/HyprPanel/customModules/config.ts
deleted file mode 100644
index 36e2c4c..0000000
--- a/ags/HyprPanel/customModules/config.ts
+++ /dev/null
@@ -1,595 +0,0 @@
-import { Option } from 'widget/settings/shared/Option';
-import { Header } from 'widget/settings/shared/Header';
-
-import options from 'options';
-import Scrollable from 'types/widgets/scrollable';
-import { Attribute, GtkWidget } from 'lib/types/widget';
-
-export const CustomModuleSettings = (): Scrollable =>
- Widget.Scrollable({
- vscroll: 'automatic',
- hscroll: 'automatic',
- class_name: 'menu-theme-page customModules paged-container',
- child: Widget.Box({
- class_name: 'menu-theme-page paged-container',
- vertical: true,
- children: [
- /*
- ************************************
- * GENERAL *
- ************************************
- */
- Header('General'),
- Option({
- opt: options.bar.customModules.scrollSpeed,
- title: 'Scrolling Speed',
- type: 'number',
- }),
-
- /*
- ************************************
- * RAM *
- ************************************
- */
- Header('RAM'),
- Option({
- opt: options.theme.bar.buttons.modules.ram.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.ram.icon,
- title: 'Ram Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.ram.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.ram.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.ram.labelType,
- title: 'Label Type',
- type: 'enum',
- enums: ['used/total', 'used', 'free', 'percentage'],
- }),
- Option({
- opt: options.bar.customModules.ram.round,
- title: 'Round',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.ram.pollingInterval,
- title: 'Polling Interval',
- type: 'number',
- min: 100,
- max: 60 * 24 * 1000,
- increment: 1000,
- }),
- Option({
- opt: options.bar.customModules.ram.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.ram.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.ram.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
-
- /*
- ************************************
- * CPU *
- ************************************
- */
- Header('CPU'),
- Option({
- opt: options.theme.bar.buttons.modules.cpu.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.cpu.icon,
- title: 'Cpu Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.cpu.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.cpu.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.cpu.round,
- title: 'Round',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.cpu.pollingInterval,
- title: 'Polling Interval',
- type: 'number',
- min: 100,
- max: 60 * 24 * 1000,
- increment: 1000,
- }),
- Option({
- opt: options.bar.customModules.cpu.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.cpu.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.cpu.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.cpu.scrollUp,
- title: 'Scroll Up',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.cpu.scrollDown,
- title: 'Scroll Down',
- type: 'string',
- }),
-
- /*
- ************************************
- * STORAGE *
- ************************************
- */
- Header('Storage'),
- Option({
- opt: options.theme.bar.buttons.modules.storage.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.storage.icon,
- title: 'Storage Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.storage.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.storage.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.storage.labelType,
- title: 'Label Type',
- type: 'enum',
- enums: ['used/total', 'used', 'free', 'percentage'],
- }),
- Option({
- opt: options.bar.customModules.storage.round,
- title: 'Round',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.storage.pollingInterval,
- title: 'Polling Interval',
- type: 'number',
- min: 100,
- max: 60 * 24 * 1000,
- increment: 1000,
- }),
- Option({
- opt: options.bar.customModules.storage.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.storage.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.storage.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
-
- /*
- ************************************
- * NETSTAT *
- ************************************
- */
- Header('Netstat'),
- Option({
- opt: options.theme.bar.buttons.modules.netstat.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.netstat.networkInterface,
- title: 'Network Interface',
- subtitle:
- "Name of the network interface to poll.\nHINT: Get list of interfaces with 'cat /proc/net/dev'",
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.netstat.icon,
- title: 'Netstat Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.netstat.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.netstat.rateUnit,
- title: 'Rate Unit',
- type: 'enum',
- enums: ['GiB', 'MiB', 'KiB', 'auto'],
- }),
- Option({
- opt: options.theme.bar.buttons.modules.netstat.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.netstat.labelType,
- title: 'Label Type',
- type: 'enum',
- enums: ['full', 'in', 'out'],
- }),
- Option({
- opt: options.bar.customModules.netstat.round,
- title: 'Round',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.netstat.pollingInterval,
- title: 'Polling Interval',
- type: 'number',
- min: 100,
- max: 60 * 24 * 1000,
- increment: 1000,
- }),
- Option({
- opt: options.bar.customModules.netstat.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.netstat.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.netstat.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
-
- /*
- ************************************
- * KEYBOARD LAYOUT *
- ************************************
- */
- Header('Keyboard Layout'),
- Option({
- opt: options.theme.bar.buttons.modules.kbLayout.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.icon,
- title: 'Keyboard Layout Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.labelType,
- title: 'Label Type',
- type: 'enum',
- enums: ['layout', 'code'],
- }),
- Option({
- opt: options.theme.bar.buttons.modules.kbLayout.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.scrollUp,
- title: 'Scroll Up',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.kbLayout.scrollDown,
- title: 'Scroll Down',
- type: 'string',
- }),
-
- /*
- ************************************
- * UPDATES *
- ************************************
- */
- Header('Updates'),
- Option({
- opt: options.theme.bar.buttons.modules.updates.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.updates.updateCommand,
- title: 'Check Updates Command',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.icon,
- title: 'Updates Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.updates.padZero,
- title: 'Pad with 0',
- type: 'boolean',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.updates.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.pollingInterval,
- title: 'Polling Interval',
- type: 'number',
- subtitle: "WARNING: Be careful of your package manager's rate limit.",
- min: 100,
- max: 60 * 24 * 1000,
- increment: 1000,
- }),
- Option({
- opt: options.bar.customModules.updates.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.scrollUp,
- title: 'Scroll Up',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.updates.scrollDown,
- title: 'Scroll Down',
- type: 'string',
- }),
-
- /*
- ************************************
- * SUBMAP *
- ************************************
- */
- Header('Submap'),
- Option({
- opt: options.theme.bar.buttons.modules.submap.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.submap.showSubmapName,
- title: 'Show Submap Name',
- subtitle:
- 'When enabled, the name of the current submap will be displayed' +
- ' instead of the Submap Enabled or Disabled text.',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.submap.enabledIcon,
- title: 'Enabled Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.disabledIcon,
- title: 'Disabled Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.enabledText,
- title: 'Enabled Text',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.disabledText,
- title: 'Disabled Text',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.submap.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.scrollUp,
- title: 'Scroll Up',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.submap.scrollDown,
- title: 'Scroll Down',
- type: 'string',
- }),
-
- /*
- ************************************
- * WEATHER *
- ************************************
- */
- Header('Weather'),
- Option({
- opt: options.theme.bar.buttons.modules.weather.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.weather.label,
- title: 'Show Label',
- type: 'boolean',
- }),
- Option({
- opt: options.bar.customModules.weather.unit,
- title: 'Units',
- type: 'enum',
- enums: ['imperial', 'metric'],
- }),
- Option({
- opt: options.theme.bar.buttons.modules.weather.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.weather.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.weather.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.weather.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.weather.scrollUp,
- title: 'Scroll Up',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.weather.scrollDown,
- title: 'Scroll Down',
- type: 'string',
- }),
-
- /*
- ************************************
- * POWER *
- ************************************
- */
- Header('Power'),
- Option({
- opt: options.theme.bar.buttons.modules.power.enableBorder,
- title: 'Button Border',
- type: 'boolean',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.power.spacing,
- title: 'Spacing',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.power.icon,
- title: 'Power Button Icon',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.power.leftClick,
- title: 'Left Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.power.rightClick,
- title: 'Right Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.power.middleClick,
- title: 'Middle Click',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.power.scrollUp,
- title: 'Scroll Up',
- type: 'string',
- }),
- Option({
- opt: options.bar.customModules.power.scrollDown,
- title: 'Scroll Down',
- type: 'string',
- }),
- ],
- }),
- });
diff --git a/ags/HyprPanel/customModules/cpu/computeCPU.ts b/ags/HyprPanel/customModules/cpu/computeCPU.ts
deleted file mode 100644
index 460b1db..0000000
--- a/ags/HyprPanel/customModules/cpu/computeCPU.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// @ts-expect-error: This import is a special directive that tells the compiler to use the GTop library
-import GTop from 'gi://GTop';
-
-let previousCpuData = new GTop.glibtop_cpu();
-GTop.glibtop_get_cpu(previousCpuData);
-
-export const computeCPU = (): number => {
- const currentCpuData = new GTop.glibtop_cpu();
- GTop.glibtop_get_cpu(currentCpuData);
-
- // Calculate the differences from the previous to current data
- const totalDiff = currentCpuData.total - previousCpuData.total;
- const idleDiff = currentCpuData.idle - previousCpuData.idle;
-
- const cpuUsagePercentage = totalDiff > 0 ? ((totalDiff - idleDiff) / totalDiff) * 100 : 0;
-
- previousCpuData = currentCpuData;
-
- return cpuUsagePercentage;
-};
diff --git a/ags/HyprPanel/customModules/cpu/index.ts b/ags/HyprPanel/customModules/cpu/index.ts
deleted file mode 100644
index a3848e4..0000000
--- a/ags/HyprPanel/customModules/cpu/index.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import options from 'options';
-
-// Module initializer
-import { module } from '../module';
-
-import Button from 'types/widgets/button';
-
-// Utility Methods
-import { inputHandler } from 'customModules/utils';
-import { computeCPU } from './computeCPU';
-import { pollVariable } from 'customModules/PollVar';
-import { BarBoxChild } from 'lib/types/bar';
-import { Attribute, Child } from 'lib/types/widget';
-
-// All the user configurable options for the cpu module that are needed
-const { label, round, leftClick, rightClick, middleClick, scrollUp, scrollDown, pollingInterval, icon } =
- options.bar.customModules.cpu;
-
-export const cpuUsage = Variable(0);
-
-pollVariable(
- // Variable to poll and update with the result of the function passed in
- cpuUsage,
- // Variables that should trigger the polling function to update when they change
- [round.bind('value')],
- // Interval at which to poll
- pollingInterval.bind('value'),
- // Function to execute to get the network data
- computeCPU,
-);
-
-export const Cpu = (): BarBoxChild => {
- const renderLabel = (cpuUsg: number, rnd: boolean): string => {
- return rnd ? `${Math.round(cpuUsg)}%` : `${cpuUsg.toFixed(2)}%`;
- };
-
- const cpuModule = module({
- textIcon: icon.bind('value'),
- label: Utils.merge([cpuUsage.bind('value'), round.bind('value')], (cpuUsg, rnd) => {
- return renderLabel(cpuUsg, rnd);
- }),
- tooltipText: 'CPU',
- boxClass: 'cpu',
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- cmd: scrollUp,
- },
- onScrollDown: {
- cmd: scrollDown,
- },
- });
- },
- },
- });
-
- return cpuModule;
-};
diff --git a/ags/HyprPanel/customModules/kblayout/getLayout.ts b/ags/HyprPanel/customModules/kblayout/getLayout.ts
deleted file mode 100644
index 9c42071..0000000
--- a/ags/HyprPanel/customModules/kblayout/getLayout.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import {
- HyprctlDeviceLayout,
- HyprctlKeyboard,
- KbLabelType,
- LayoutKeys,
- LayoutValues,
-} from 'lib/types/customModules/kbLayout';
-import { layoutMap } from './layouts';
-
-export const getKeyboardLayout = (obj: string, format: KbLabelType): LayoutKeys | LayoutValues => {
- const hyprctlDevices: HyprctlDeviceLayout = JSON.parse(obj);
- const keyboards = hyprctlDevices['keyboards'];
-
- if (keyboards.length === 0) {
- return format === 'code' ? 'Unknown' : 'Unknown Layout';
- }
-
- let mainKb = keyboards.find((kb: HyprctlKeyboard) => kb.main);
-
- if (!mainKb) {
- mainKb = keyboards[keyboards.length - 1];
- }
-
- const layout: LayoutKeys = mainKb['active_keymap'] as LayoutKeys;
- const foundLayout: LayoutValues = layoutMap[layout];
-
- return format === 'code' ? foundLayout || layout : layout;
-};
diff --git a/ags/HyprPanel/customModules/kblayout/index.ts b/ags/HyprPanel/customModules/kblayout/index.ts
deleted file mode 100644
index 8c566e5..0000000
--- a/ags/HyprPanel/customModules/kblayout/index.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-const hyprland = await Service.import('hyprland');
-
-import options from 'options';
-import { module } from '../module';
-
-import { inputHandler } from 'customModules/utils';
-import Gtk from 'types/@girs/gtk-3.0/gtk-3.0';
-import Button from 'types/widgets/button';
-import Label from 'types/widgets/label';
-import { getKeyboardLayout } from './getLayout';
-import { BarBoxChild } from 'lib/types/bar';
-import { Attribute, Child } from 'lib/types/widget';
-
-const { label, labelType, icon, leftClick, rightClick, middleClick, scrollUp, scrollDown } =
- options.bar.customModules.kbLayout;
-
-export const KbInput = (): BarBoxChild => {
- const keyboardModule = module({
- textIcon: icon.bind('value'),
- tooltipText: '',
- labelHook: (self: Label): void => {
- self.hook(
- hyprland,
- () => {
- Utils.execAsync('hyprctl devices -j')
- .then((obj) => {
- self.label = getKeyboardLayout(obj, labelType.value);
- })
- .catch((err) => {
- console.error(err);
- });
- },
- 'keyboard-layout',
- );
-
- self.hook(labelType, () => {
- Utils.execAsync('hyprctl devices -j')
- .then((obj) => {
- self.label = getKeyboardLayout(obj, labelType.value);
- })
- .catch((err) => {
- console.error(err);
- });
- });
- },
-
- boxClass: 'kblayout',
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- cmd: scrollUp,
- },
- onScrollDown: {
- cmd: scrollDown,
- },
- });
- },
- },
- });
-
- return keyboardModule;
-};
diff --git a/ags/HyprPanel/customModules/kblayout/layouts.ts b/ags/HyprPanel/customModules/kblayout/layouts.ts
deleted file mode 100644
index ccd37c6..0000000
--- a/ags/HyprPanel/customModules/kblayout/layouts.ts
+++ /dev/null
@@ -1,585 +0,0 @@
-export const layoutMap = {
- 'Abkhazian (Russia)': 'RU (Ab)',
- Akan: 'GH (Akan)',
- Albanian: 'AL',
- 'Albanian (Plisi)': 'AL (Plisi)',
- 'Albanian (Veqilharxhi)': 'AL (Veqilharxhi)',
- Amharic: 'ET',
- Arabic: 'ARA',
- 'Arabic (Algeria)': 'DZ (Ar)',
- 'Arabic (AZERTY, Eastern Arabic numerals)': 'ARA (Azerty Digits)',
- 'Arabic (AZERTY)': 'ARA (Azerty)',
- 'Arabic (Buckwalter)': 'ARA (Buckwalter)',
- 'Arabic (Eastern Arabic numerals)': 'ARA (Digits)',
- 'Arabic (Macintosh)': 'ARA (Mac)',
- 'Arabic (Morocco)': 'MA',
- 'Arabic (OLPC)': 'ARA (Olpc)',
- 'Arabic (Pakistan)': 'PK (Ara)',
- 'Arabic (QWERTY, Eastern Arabic numerals)': 'ARA (Qwerty Digits)',
- 'Arabic (QWERTY)': 'ARA (Qwerty)',
- 'Arabic (Syria)': 'SY',
- Armenian: 'AM',
- 'Armenian (alt. eastern)': 'AM (Eastern-Alt)',
- 'Armenian (alt. phonetic)': 'AM (Phonetic-Alt)',
- 'Armenian (eastern)': 'AM (Eastern)',
- 'Armenian (phonetic)': 'AM (Phonetic)',
- 'Armenian (western)': 'AM (Western)',
- 'Asturian (Spain, with bottom-dot H and L)': 'ES (Ast)',
- Avatime: 'GH (Avn)',
- Azerbaijani: 'AZ',
- 'Azerbaijani (Cyrillic)': 'AZ (Cyrillic)',
- 'Azerbaijani (Iran)': 'IR (Azb)',
- Bambara: 'ML',
- Bangla: 'BD',
- 'Bangla (India, Baishakhi InScript)': 'IN (Ben Inscript)',
- 'Bangla (India, Baishakhi)': 'IN (Ben Baishakhi)',
- 'Bangla (India, Bornona)': 'IN (Ben Bornona)',
- 'Bangla (India, Gitanjali)': 'IN (Ben Gitanjali)',
- 'Bangla (India, Probhat)': 'IN (Ben Probhat)',
- 'Bangla (India)': 'IN (Ben)',
- 'Bangla (Probhat)': 'BD (Probhat)',
- Bashkirian: 'RU (Bak)',
- Belarusian: 'BY',
- 'Belarusian (intl.)': 'BY (Intl)',
- 'Belarusian (Latin)': 'BY (Latin)',
- 'Belarusian (legacy)': 'BY (Legacy)',
- 'Belarusian (phonetic)': 'BY (Phonetic)',
- Belgian: 'BE',
- 'Belgian (alt.)': 'BE (Oss)',
- 'Belgian (ISO, alt.)': 'BE (Iso-Alternate)',
- 'Belgian (Latin-9 only, alt.)': 'BE (Oss Latin9)',
- 'Belgian (no dead keys)': 'BE (Nodeadkeys)',
- 'Belgian (Wang 724 AZERTY)': 'BE (Wang)',
- 'Berber (Algeria, Latin)': 'DZ',
- 'Berber (Algeria, Tifinagh)': 'DZ (Ber)',
- 'Berber (Morocco, Tifinagh alt.)': 'MA (Tifinagh-Alt)',
- 'Berber (Morocco, Tifinagh extended phonetic)': 'MA (Tifinagh-Extended-Phonetic)',
- 'Berber (Morocco, Tifinagh extended)': 'MA (Tifinagh-Extended)',
- 'Berber (Morocco, Tifinagh phonetic, alt.)': 'MA (Tifinagh-Alt-Phonetic)',
- 'Berber (Morocco, Tifinagh phonetic)': 'MA (Tifinagh-Phonetic)',
- 'Berber (Morocco, Tifinagh)': 'MA (Tifinagh)',
- Bosnian: 'BA',
- 'Bosnian (US, with Bosnian digraphs)': 'BA (Unicodeus)',
- 'Bosnian (US)': 'BA (Us)',
- 'Bosnian (with Bosnian digraphs)': 'BA (Unicode)',
- 'Bosnian (with guillemets)': 'BA (Alternatequotes)',
- Braille: 'BRAI',
- 'Braille (left-handed inverted thumb)': 'BRAI (Left Hand Invert)',
- 'Braille (left-handed)': 'BRAI (Left Hand)',
- 'Braille (right-handed inverted thumb)': 'BRAI (Right Hand Invert)',
- 'Braille (right-handed)': 'BRAI (Right Hand)',
- 'Breton (France)': 'FR (Bre)',
- Bulgarian: 'BG',
- 'Bulgarian (enhanced)': 'BG (Bekl)',
- 'Bulgarian (new phonetic)': 'BG (Bas Phonetic)',
- 'Bulgarian (traditional phonetic)': 'BG (Phonetic)',
- Burmese: 'MM',
- 'Burmese Zawgyi': 'MM (Zawgyi)',
- 'Cameroon (AZERTY, intl.)': 'CM (Azerty)',
- 'Cameroon (Dvorak, intl.)': 'CM (Dvorak)',
- 'Cameroon Multilingual (QWERTY, intl.)': 'CM (Qwerty)',
- 'Canadian (CSA)': 'CA (Multix)',
- 'Catalan (Spain, with middle-dot L)': 'ES (Cat)',
- Cherokee: 'US (Chr)',
- Chinese: 'CN',
- Chuvash: 'RU (Cv)',
- 'Chuvash (Latin)': 'RU (Cv Latin)',
- CloGaelach: 'IE (CloGaelach)',
- 'Crimean Tatar (Turkish Alt-Q)': 'UA (Crh Alt)',
- 'Crimean Tatar (Turkish F)': 'UA (Crh F)',
- 'Crimean Tatar (Turkish Q)': 'UA (Crh)',
- Croatian: 'HR',
- 'Croatian (US, with Croatian digraphs)': 'HR (Unicodeus)',
- 'Croatian (US)': 'HR (Us)',
- 'Croatian (with Croatian digraphs)': 'HR (Unicode)',
- 'Croatian (with guillemets)': 'HR (Alternatequotes)',
- Czech: 'CZ',
- 'Czech (QWERTY, extended backslash)': 'CZ (Qwerty Bksl)',
- 'Czech (QWERTY, Macintosh)': 'CZ (Qwerty-Mac)',
- 'Czech (QWERTY)': 'CZ (Qwerty)',
- 'Czech (UCW, only accented letters)': 'CZ (Ucw)',
- 'Czech (US, Dvorak, UCW support)': 'CZ (Dvorak-Ucw)',
- 'Czech (with <\\|> key)': 'CZ (Bksl)',
- Danish: 'DK',
- 'Danish (Dvorak)': 'DK (Dvorak)',
- 'Danish (Macintosh, no dead keys)': 'DK (Mac Nodeadkeys)',
- 'Danish (Macintosh)': 'DK (Mac)',
- 'Danish (no dead keys)': 'DK (Nodeadkeys)',
- 'Danish (Windows)': 'DK (Winkeys)',
- Dari: 'AF',
- 'Dari (Afghanistan, OLPC)': 'AF (Fa-Olpc)',
- Dhivehi: 'MV',
- Dutch: 'NL',
- 'Dutch (Macintosh)': 'NL (Mac)',
- 'Dutch (standard)': 'NL (Std)',
- 'Dutch (US)': 'NL (Us)',
- Dzongkha: 'BT',
- 'English (Australian)': 'AU',
- 'English (Cameroon)': 'CM',
- 'English (Canada)': 'CA (Eng)',
- 'English (classic Dvorak)': 'US (Dvorak-Classic)',
- 'English (Colemak-DH ISO)': 'US (Colemak Dh Iso)',
- 'English (Colemak-DH)': 'US (Colemak Dh)',
- 'English (Colemak)': 'US (Colemak)',
- 'English (Dvorak, alt. intl.)': 'US (Dvorak-Alt-Intl)',
- 'English (Dvorak, intl., with dead keys)': 'US (Dvorak-Intl)',
- 'English (Dvorak, left-handed)': 'US (Dvorak-L)',
- 'English (Dvorak, Macintosh)': 'US (Dvorak-Mac)',
- 'English (Dvorak, right-handed)': 'US (Dvorak-R)',
- 'English (Dvorak)': 'US (Dvorak)',
- 'English (Ghana, GILLBT)': 'GH (Gillbt)',
- 'English (Ghana, multilingual)': 'GH (Generic)',
- 'English (Ghana)': 'GH',
- 'English (India, with rupee)': 'IN (Eng)',
- 'English (intl., with AltGr dead keys)': 'US (Altgr-Intl)',
- 'English (Macintosh)': 'US (Mac)',
- 'English (Mali, US, intl.)': 'ML (Us-Intl)',
- 'English (Mali, US, Macintosh)': 'ML (Us-Mac)',
- 'English (Nigeria)': 'NG',
- 'English (Norman)': 'US (Norman)',
- 'English (programmer Dvorak)': 'US (Dvp)',
- 'English (South Africa)': 'ZA',
- 'English (the divide/multiply toggle the layout)': 'US (Olpc2)',
- 'English (UK, Colemak-DH)': 'GB (Colemak Dh)',
- 'English (UK, Colemak)': 'GB (Colemak)',
- 'English (UK, Dvorak, with UK punctuation)': 'GB (Dvorakukp)',
- 'English (UK, Dvorak)': 'GB (Dvorak)',
- 'English (UK, extended, Windows)': 'GB (Extd)',
- 'English (UK, intl., with dead keys)': 'GB (Intl)',
- 'English (UK, Macintosh, intl.)': 'GB (Mac Intl)',
- 'English (UK, Macintosh)': 'GB (Mac)',
- 'English (UK)': 'GB',
- 'English (US, alt. intl.)': 'US (Alt-Intl)',
- 'English (US, euro on 5)': 'US (Euro)',
- 'English (US, intl., with dead keys)': 'US (Intl)',
- 'English (US, Symbolic)': 'US (Symbolic)',
- 'English (US)': 'US',
- 'English (Workman, intl., with dead keys)': 'US (Workman-Intl)',
- 'English (Workman)': 'US (Workman)',
- Esperanto: 'EPO',
- 'Esperanto (Brazil, Nativo)': 'BR (Nativo-Epo)',
- 'Esperanto (legacy)': 'EPO (Legacy)',
- 'Esperanto (Portugal, Nativo)': 'PT (Nativo-Epo)',
- Estonian: 'EE',
- 'Estonian (Dvorak)': 'EE (Dvorak)',
- 'Estonian (no dead keys)': 'EE (Nodeadkeys)',
- 'Estonian (US)': 'EE (Us)',
- Ewe: 'GH (Ewe)',
- Faroese: 'FO',
- 'Faroese (no dead keys)': 'FO (Nodeadkeys)',
- Filipino: 'PH',
- 'Filipino (Capewell-Dvorak, Baybayin)': 'PH (Capewell-Dvorak-Bay)',
- 'Filipino (Capewell-Dvorak, Latin)': 'PH (Capewell-Dvorak)',
- 'Filipino (Capewell-QWERF 2006, Baybayin)': 'PH (Capewell-Qwerf2k6-Bay)',
- 'Filipino (Capewell-QWERF 2006, Latin)': 'PH (Capewell-Qwerf2k6)',
- 'Filipino (Colemak, Baybayin)': 'PH (Colemak-Bay)',
- 'Filipino (Colemak, Latin)': 'PH (Colemak)',
- 'Filipino (Dvorak, Baybayin)': 'PH (Dvorak-Bay)',
- 'Filipino (Dvorak, Latin)': 'PH (Dvorak)',
- 'Filipino (QWERTY, Baybayin)': 'PH (Qwerty-Bay)',
- Finnish: 'FI',
- 'Finnish (classic, no dead keys)': 'FI (Nodeadkeys)',
- 'Finnish (classic)': 'FI (Classic)',
- 'Finnish (Macintosh)': 'FI (Mac)',
- 'Finnish (Windows)': 'FI (Winkeys)',
- French: 'FR',
- 'French (alt., Latin-9 only)': 'FR (Oss Latin9)',
- 'French (alt., no dead keys)': 'FR (Oss Nodeadkeys)',
- 'French (alt.)': 'FR (Oss)',
- 'French (AZERTY, AFNOR)': 'FR (Afnor)',
- 'French (AZERTY)': 'FR (Azerty)',
- 'French (BEPO, AFNOR)': 'FR (Bepo Afnor)',
- 'French (BEPO, Latin-9 only)': 'FR (Bepo Latin9)',
- 'French (BEPO)': 'FR (Bepo)',
- 'French (Cameroon)': 'CM (French)',
- 'French (Canada, Dvorak)': 'CA (Fr-Dvorak)',
- 'French (Canada, legacy)': 'CA (Fr-Legacy)',
- 'French (Canada)': 'CA',
- 'French (Democratic Republic of the Congo)': 'CD',
- 'French (Dvorak)': 'FR (Dvorak)',
- 'French (legacy, alt., no dead keys)': 'FR (Latin9 Nodeadkeys)',
- 'French (legacy, alt.)': 'FR (Latin9)',
- 'French (Macintosh)': 'FR (Mac)',
- 'French (Mali, alt.)': 'ML (Fr-Oss)',
- 'French (Morocco)': 'MA (French)',
- 'French (no dead keys)': 'FR (Nodeadkeys)',
- 'French (Switzerland, Macintosh)': 'CH (Fr Mac)',
- 'French (Switzerland, no dead keys)': 'CH (Fr Nodeadkeys)',
- 'French (Switzerland)': 'CH (Fr)',
- 'French (Togo)': 'TG',
- 'French (US)': 'FR (Us)',
- 'Friulian (Italy)': 'IT (Fur)',
- Fula: 'GH (Fula)',
- Ga: 'GH (Ga)',
- Georgian: 'GE',
- 'Georgian (ergonomic)': 'GE (Ergonomic)',
- 'Georgian (France, AZERTY Tskapo)': 'FR (Geo)',
- 'Georgian (Italy)': 'IT (Geo)',
- 'Georgian (MESS)': 'GE (Mess)',
- German: 'DE',
- 'German (Austria, Macintosh)': 'AT (Mac)',
- 'German (Austria, no dead keys)': 'AT (Nodeadkeys)',
- 'German (Austria)': 'AT',
- 'German (dead acute)': 'DE (Deadacute)',
- 'German (dead grave acute)': 'DE (Deadgraveacute)',
- 'German (dead tilde)': 'DE (Deadtilde)',
- 'German (Dvorak)': 'DE (Dvorak)',
- 'German (E1)': 'DE (E1)',
- 'German (E2)': 'DE (E2)',
- 'German (Macintosh, no dead keys)': 'DE (Mac Nodeadkeys)',
- 'German (Macintosh)': 'DE (Mac)',
- 'German (Neo 2)': 'DE (Neo)',
- 'German (no dead keys)': 'DE (Nodeadkeys)',
- 'German (QWERTY)': 'DE (Qwerty)',
- 'German (Switzerland, legacy)': 'CH (Legacy)',
- 'German (Switzerland, Macintosh)': 'CH (De Mac)',
- 'German (Switzerland, no dead keys)': 'CH (De Nodeadkeys)',
- 'German (Switzerland)': 'CH',
- 'German (T3)': 'DE (T3)',
- 'German (US)': 'DE (Us)',
- Greek: 'GR',
- 'Greek (extended)': 'GR (Extended)',
- 'Greek (no dead keys)': 'GR (Nodeadkeys)',
- 'Greek (polytonic)': 'GR (Polytonic)',
- 'Greek (simple)': 'GR (Simple)',
- Gujarati: 'IN (Guj)',
- 'Hanyu Pinyin Letters (with AltGr dead keys)': 'CN (Altgr-Pinyin)',
- 'Hausa (Ghana)': 'GH (Hausa)',
- 'Hausa (Nigeria)': 'NG (Hausa)',
- Hawaiian: 'US (Haw)',
- Hebrew: 'IL',
- 'Hebrew (Biblical, Tiro)': 'IL (Biblical)',
- 'Hebrew (lyx)': 'IL (Lyx)',
- 'Hebrew (phonetic)': 'IL (Phonetic)',
- 'Hindi (Bolnagri)': 'IN (Bolnagri)',
- 'Hindi (KaGaPa, phonetic)': 'IN (Hin-Kagapa)',
- 'Hindi (Wx)': 'IN (Hin-Wx)',
- Hungarian: 'HU',
- 'Hungarian (no dead keys)': 'HU (Nodeadkeys)',
- 'Hungarian (QWERTY, 101-key, comma, dead keys)': 'HU (101 Qwerty Comma Dead)',
- 'Hungarian (QWERTY, 101-key, comma, no dead keys)': 'HU (101 Qwerty Comma Nodead)',
- 'Hungarian (QWERTY, 101-key, dot, dead keys)': 'HU (101 Qwerty Dot Dead)',
- 'Hungarian (QWERTY, 101-key, dot, no dead keys)': 'HU (101 Qwerty Dot Nodead)',
- 'Hungarian (QWERTY, 102-key, comma, dead keys)': 'HU (102 Qwerty Comma Dead)',
- 'Hungarian (QWERTY, 102-key, comma, no dead keys)': 'HU (102 Qwerty Comma Nodead)',
- 'Hungarian (QWERTY, 102-key, dot, dead keys)': 'HU (102 Qwerty Dot Dead)',
- 'Hungarian (QWERTY, 102-key, dot, no dead keys)': 'HU (102 Qwerty Dot Nodead)',
- 'Hungarian (QWERTY)': 'HU (Qwerty)',
- 'Hungarian (QWERTZ, 101-key, comma, dead keys)': 'HU (101 Qwertz Comma Dead)',
- 'Hungarian (QWERTZ, 101-key, comma, no dead keys)': 'HU (101 Qwertz Comma Nodead)',
- 'Hungarian (QWERTZ, 101-key, dot, dead keys)': 'HU (101 Qwertz Dot Dead)',
- 'Hungarian (QWERTZ, 101-key, dot, no dead keys)': 'HU (101 Qwertz Dot Nodead)',
- 'Hungarian (QWERTZ, 102-key, comma, dead keys)': 'HU (102 Qwertz Comma Dead)',
- 'Hungarian (QWERTZ, 102-key, comma, no dead keys)': 'HU (102 Qwertz Comma Nodead)',
- 'Hungarian (QWERTZ, 102-key, dot, dead keys)': 'HU (102 Qwertz Dot Dead)',
- 'Hungarian (QWERTZ, 102-key, dot, no dead keys)': 'HU (102 Qwertz Dot Nodead)',
- 'Hungarian (standard)': 'HU (Standard)',
- Icelandic: 'IS',
- 'Icelandic (Dvorak)': 'IS (Dvorak)',
- 'Icelandic (Macintosh, legacy)': 'IS (Mac Legacy)',
- 'Icelandic (Macintosh)': 'IS (Mac)',
- Igbo: 'NG (Igbo)',
- Indian: 'IN',
- 'Indic IPA': 'IN (Iipa)',
- 'Indonesian (Arab Melayu, extended phonetic)': 'ID (Melayu-Phoneticx)',
- 'Indonesian (Arab Melayu, phonetic)': 'ID (Melayu-Phonetic)',
- 'Indonesian (Arab Pegon, phonetic)': 'ID (Pegon-Phonetic)',
- 'Indonesian (Latin)': 'ID',
- Inuktitut: 'CA (Ike)',
- Iraqi: 'IQ',
- Irish: 'IE',
- 'Irish (UnicodeExpert)': 'IE (UnicodeExpert)',
- Italian: 'IT',
- 'Italian (IBM 142)': 'IT (Ibm)',
- 'Italian (intl., with dead keys)': 'IT (Intl)',
- 'Italian (Macintosh)': 'IT (Mac)',
- 'Italian (no dead keys)': 'IT (Nodeadkeys)',
- 'Italian (US)': 'IT (Us)',
- 'Italian (Windows)': 'IT (Winkeys)',
- Japanese: 'JP',
- 'Japanese (Dvorak)': 'JP (Dvorak)',
- 'Japanese (Kana 86)': 'JP (Kana86)',
- 'Japanese (Kana)': 'JP (Kana)',
- 'Japanese (Macintosh)': 'JP (Mac)',
- 'Japanese (OADG 109A)': 'JP (OADG109A)',
- Javanese: 'ID (Javanese)',
- 'Kabyle (AZERTY, with dead keys)': 'DZ (Azerty-Deadkeys)',
- 'Kabyle (QWERTY, UK, with dead keys)': 'DZ (Qwerty-Gb-Deadkeys)',
- 'Kabyle (QWERTY, US, with dead keys)': 'DZ (Qwerty-Us-Deadkeys)',
- Kalmyk: 'RU (Xal)',
- Kannada: 'IN (Kan)',
- 'Kannada (KaGaPa, phonetic)': 'IN (Kan-Kagapa)',
- Kashubian: 'PL (Csb)',
- Kazakh: 'KZ',
- 'Kazakh (extended)': 'KZ (Ext)',
- 'Kazakh (Latin)': 'KZ (Latin)',
- 'Kazakh (with Russian)': 'KZ (Kazrus)',
- 'Khmer (Cambodia)': 'KH',
- Kikuyu: 'KE (Kik)',
- Komi: 'RU (Kom)',
- Korean: 'KR',
- 'Korean (101/104-key compatible)': 'KR (Kr104)',
- 'Kurdish (Iran, Arabic-Latin)': 'IR (Ku Ara)',
- 'Kurdish (Iran, F)': 'IR (Ku F)',
- 'Kurdish (Iran, Latin Alt-Q)': 'IR (Ku Alt)',
- 'Kurdish (Iran, Latin Q)': 'IR (Ku)',
- 'Kurdish (Iraq, Arabic-Latin)': 'IQ (Ku Ara)',
- 'Kurdish (Iraq, F)': 'IQ (Ku F)',
- 'Kurdish (Iraq, Latin Alt-Q)': 'IQ (Ku Alt)',
- 'Kurdish (Iraq, Latin Q)': 'IQ (Ku)',
- 'Kurdish (Syria, F)': 'SY (Ku F)',
- 'Kurdish (Syria, Latin Alt-Q)': 'SY (Ku Alt)',
- 'Kurdish (Syria, Latin Q)': 'SY (Ku)',
- 'Kurdish (Turkey, F)': 'TR (Ku F)',
- 'Kurdish (Turkey, Latin Alt-Q)': 'TR (Ku Alt)',
- 'Kurdish (Turkey, Latin Q)': 'TR (Ku)',
- Kyrgyz: 'KG',
- 'Kyrgyz (phonetic)': 'KG (Phonetic)',
- Lao: 'LA',
- 'Lao (STEA)': 'LA (Stea)',
- Latvian: 'LV',
- 'Latvian (adapted)': 'LV (Adapted)',
- 'Latvian (apostrophe)': 'LV (Apostrophe)',
- 'Latvian (ergonomic, ŪGJRMV)': 'LV (Ergonomic)',
- 'Latvian (F)': 'LV (Fkey)',
- 'Latvian (modern)': 'LV (Modern)',
- 'Latvian (tilde)': 'LV (Tilde)',
- Lithuanian: 'LT',
- 'Lithuanian (IBM LST 1205-92)': 'LT (Ibm)',
- 'Lithuanian (LEKP)': 'LT (Lekp)',
- 'Lithuanian (LEKPa)': 'LT (Lekpa)',
- 'Lithuanian (Ratise)': 'LT (Ratise)',
- 'Lithuanian (standard)': 'LT (Std)',
- 'Lithuanian (US)': 'LT (Us)',
- 'Lower Sorbian': 'DE (Dsb)',
- 'Lower Sorbian (QWERTZ)': 'DE (Dsb Qwertz)',
- Macedonian: 'MK',
- 'Macedonian (no dead keys)': 'MK (Nodeadkeys)',
- 'Malay (Jawi, Arabic Keyboard)': 'MY',
- 'Malay (Jawi, phonetic)': 'MY (Phonetic)',
- Malayalam: 'IN (Mal)',
- 'Malayalam (enhanced InScript, with rupee)': 'IN (Mal Enhanced)',
- 'Malayalam (Lalitha)': 'IN (Mal Lalitha)',
- Maltese: 'MT',
- 'Maltese (UK, with AltGr overrides)': 'MT (Alt-Gb)',
- 'Maltese (US, with AltGr overrides)': 'MT (Alt-Us)',
- 'Maltese (US)': 'MT (Us)',
- 'Manipuri (Eeyek)': 'IN (Eeyek)',
- Maori: 'MAO',
- 'Marathi (enhanced InScript)': 'IN (Marathi)',
- 'Marathi (KaGaPa, phonetic)': 'IN (Mar-Kagapa)',
- Mari: 'RU (Chm)',
- Mmuock: 'CM (Mmuock)',
- Moldavian: 'MD',
- 'Moldavian (Gagauz)': 'MD (Gag)',
- Mon: 'MM (Mnw)',
- 'Mon (A1)': 'MM (Mnw-A1)',
- Mongolian: 'MN',
- 'Mongolian (Bichig)': 'CN (Mon Trad)',
- 'Mongolian (Galik)': 'CN (Mon Trad Galik)',
- 'Mongolian (Manchu Galik)': 'CN (Mon Manchu Galik)',
- 'Mongolian (Manchu)': 'CN (Mon Trad Manchu)',
- 'Mongolian (Todo Galik)': 'CN (Mon Todo Galik)',
- 'Mongolian (Todo)': 'CN (Mon Trad Todo)',
- 'Mongolian (Xibe)': 'CN (Mon Trad Xibe)',
- Montenegrin: 'ME',
- 'Montenegrin (Cyrillic, with guillemets)': 'ME (Cyrillicalternatequotes)',
- 'Montenegrin (Cyrillic, ZE and ZHE swapped)': 'ME (Cyrillicyz)',
- 'Montenegrin (Cyrillic)': 'ME (Cyrillic)',
- 'Montenegrin (Latin, QWERTY)': 'ME (Latinyz)',
- 'Montenegrin (Latin, Unicode, QWERTY)': 'ME (Latinunicodeyz)',
- 'Montenegrin (Latin, Unicode)': 'ME (Latinunicode)',
- 'Montenegrin (Latin, with guillemets)': 'ME (Latinalternatequotes)',
- "N'Ko (AZERTY)": 'GN',
- Nepali: 'NP',
- 'Northern Saami (Finland)': 'FI (Smi)',
- 'Northern Saami (Norway, no dead keys)': 'NO (Smi Nodeadkeys)',
- 'Northern Saami (Norway)': 'NO (Smi)',
- 'Northern Saami (Sweden)': 'SE (Smi)',
- Norwegian: 'NO',
- 'Norwegian (Colemak)': 'NO (Colemak)',
- 'Norwegian (Dvorak)': 'NO (Dvorak)',
- 'Norwegian (Macintosh, no dead keys)': 'NO (Mac Nodeadkeys)',
- 'Norwegian (Macintosh)': 'NO (Mac)',
- 'Norwegian (no dead keys)': 'NO (Nodeadkeys)',
- 'Norwegian (Windows)': 'NO (Winkeys)',
- Occitan: 'FR (Oci)',
- Ogham: 'IE (Ogam)',
- 'Ogham (IS434)': 'IE (Ogam Is434)',
- 'Ol Chiki': 'IN (Olck)',
- 'Old Turkic': 'TR (Otk)',
- 'Old Turkic (F)': 'TR (Otkf)',
- Oriya: 'IN (Ori)',
- 'Oriya (Bolnagri)': 'IN (Ori-Bolnagri)',
- 'Oriya (Wx)': 'IN (Ori-Wx)',
- 'Ossetian (Georgia)': 'GE (Os)',
- 'Ossetian (legacy)': 'RU (Os Legacy)',
- 'Ossetian (Windows)': 'RU (Os Winkeys)',
- 'Ottoman (F)': 'TR (Otf)',
- 'Ottoman (Q)': 'TR (Ot)',
- 'Pannonian Rusyn': 'RS (Rue)',
- Pashto: 'AF (Ps)',
- 'Pashto (Afghanistan, OLPC)': 'AF (Ps-Olpc)',
- Persian: 'IR',
- 'Persian (with Persian keypad)': 'IR (Pes Keypad)',
- Polish: 'PL',
- 'Polish (British keyboard)': 'GB (Pl)',
- 'Polish (Dvorak, with Polish quotes on key 1)': 'PL (Dvorak Altquotes)',
- 'Polish (Dvorak, with Polish quotes on quotemark key)': 'PL (Dvorak Quotes)',
- 'Polish (Dvorak)': 'PL (Dvorak)',
- 'Polish (legacy)': 'PL (Legacy)',
- 'Polish (programmer Dvorak)': 'PL (Dvp)',
- 'Polish (QWERTZ)': 'PL (Qwertz)',
- Portuguese: 'PT',
- 'Portuguese (Brazil, Dvorak)': 'BR (Dvorak)',
- 'Portuguese (Brazil, IBM/Lenovo ThinkPad)': 'BR (Thinkpad)',
- 'Portuguese (Brazil, Nativo for US keyboards)': 'BR (Nativo-Us)',
- 'Portuguese (Brazil, Nativo)': 'BR (Nativo)',
- 'Portuguese (Brazil, no dead keys)': 'BR (Nodeadkeys)',
- 'Portuguese (Brazil)': 'BR',
- 'Portuguese (Macintosh, no dead keys)': 'PT (Mac Nodeadkeys)',
- 'Portuguese (Macintosh)': 'PT (Mac)',
- 'Portuguese (Nativo for US keyboards)': 'PT (Nativo-Us)',
- 'Portuguese (Nativo)': 'PT (Nativo)',
- 'Portuguese (no dead keys)': 'PT (Nodeadkeys)',
- 'Punjabi (Gurmukhi Jhelum)': 'IN (Jhelum)',
- 'Punjabi (Gurmukhi)': 'IN (Guru)',
- Romanian: 'RO',
- 'Romanian (Germany, no dead keys)': 'DE (Ro Nodeadkeys)',
- 'Romanian (Germany)': 'DE (Ro)',
- 'Romanian (standard)': 'RO (Std)',
- 'Romanian (Windows)': 'RO (Winkeys)',
- Russian: 'RU',
- 'Russian (Belarus)': 'BY (Ru)',
- 'Russian (Czech, phonetic)': 'CZ (Rus)',
- 'Russian (DOS)': 'RU (Dos)',
- 'Russian (engineering, EN)': 'RU (Ruchey En)',
- 'Russian (engineering, RU)': 'RU (Ruchey Ru)',
- 'Russian (Georgia)': 'GE (Ru)',
- 'Russian (Germany, phonetic)': 'DE (Ru)',
- 'Russian (Kazakhstan, with Kazakh)': 'KZ (Ruskaz)',
- 'Russian (legacy)': 'RU (Legacy)',
- 'Russian (Macintosh)': 'RU (Mac)',
- 'Russian (phonetic, AZERTY)': 'RU (Phonetic Azerty)',
- 'Russian (phonetic, Dvorak)': 'RU (Phonetic Dvorak)',
- 'Russian (phonetic, French)': 'RU (Phonetic Fr)',
- 'Russian (phonetic, Windows)': 'RU (Phonetic Winkeys)',
- 'Russian (phonetic, YAZHERTY)': 'RU (Phonetic YAZHERTY)',
- 'Russian (phonetic)': 'RU (Phonetic)',
- 'Russian (Poland, phonetic Dvorak)': 'PL (Ru Phonetic Dvorak)',
- 'Russian (Sweden, phonetic, no dead keys)': 'SE (Rus Nodeadkeys)',
- 'Russian (Sweden, phonetic)': 'SE (Rus)',
- 'Russian (typewriter, legacy)': 'RU (Typewriter-Legacy)',
- 'Russian (typewriter)': 'RU (Typewriter)',
- 'Russian (Ukraine, standard RSTU)': 'UA (Rstu Ru)',
- 'Russian (US, phonetic)': 'US (Rus)',
- 'Saisiyat (Taiwan)': 'TW (Saisiyat)',
- Samogitian: 'LT (Sgs)',
- 'Sanskrit (KaGaPa, phonetic)': 'IN (San-Kagapa)',
- 'Scottish Gaelic': 'GB (Gla)',
- Serbian: 'RS',
- 'Serbian (Cyrillic, with guillemets)': 'RS (Alternatequotes)',
- 'Serbian (Cyrillic, ZE and ZHE swapped)': 'RS (Yz)',
- 'Serbian (Latin, QWERTY)': 'RS (Latinyz)',
- 'Serbian (Latin, Unicode, QWERTY)': 'RS (Latinunicodeyz)',
- 'Serbian (Latin, Unicode)': 'RS (Latinunicode)',
- 'Serbian (Latin, with guillemets)': 'RS (Latinalternatequotes)',
- 'Serbian (Latin)': 'RS (Latin)',
- 'Serbian (Russia)': 'RU (Srp)',
- 'Serbo-Croatian (US)': 'US (Hbs)',
- Shan: 'MM (Shn)',
- 'Shan (Zawgyi Tai)': 'MM (Zgt)',
- Sicilian: 'IT (Scn)',
- Silesian: 'PL (Szl)',
- Sindhi: 'PK (Snd)',
- 'Sinhala (phonetic)': 'LK',
- 'Sinhala (US)': 'LK (Us)',
- Slovak: 'SK',
- 'Slovak (extended backslash)': 'SK (Bksl)',
- 'Slovak (QWERTY, extended backslash)': 'SK (Qwerty Bksl)',
- 'Slovak (QWERTY)': 'SK (Qwerty)',
- Slovenian: 'SI',
- 'Slovenian (US)': 'SI (Us)',
- 'Slovenian (with guillemets)': 'SI (Alternatequotes)',
- Spanish: 'ES',
- 'Spanish (dead tilde)': 'ES (Deadtilde)',
- 'Spanish (Dvorak)': 'ES (Dvorak)',
- 'Spanish (Latin American, Colemak)': 'LATAM (Colemak)',
- 'Spanish (Latin American, dead tilde)': 'LATAM (Deadtilde)',
- 'Spanish (Latin American, Dvorak)': 'LATAM (Dvorak)',
- 'Spanish (Latin American, no dead keys)': 'LATAM (Nodeadkeys)',
- 'Spanish (Latin American)': 'LATAM',
- 'Spanish (Macintosh)': 'ES (Mac)',
- 'Spanish (no dead keys)': 'ES (Nodeadkeys)',
- 'Spanish (Windows)': 'ES (Winkeys)',
- 'Swahili (Kenya)': 'KE',
- 'Swahili (Tanzania)': 'TZ',
- Swedish: 'SE',
- 'Swedish (Dvorak, intl.)': 'SE (Us Dvorak)',
- 'Swedish (Dvorak)': 'SE (Dvorak)',
- 'Swedish (Macintosh)': 'SE (Mac)',
- 'Swedish (no dead keys)': 'SE (Nodeadkeys)',
- 'Swedish (Svdvorak)': 'SE (Svdvorak)',
- 'Swedish (US)': 'SE (Us)',
- 'Swedish Sign Language': 'SE (Swl)',
- Syriac: 'SY (Syc)',
- 'Syriac (phonetic)': 'SY (Syc Phonetic)',
- Taiwanese: 'TW',
- 'Taiwanese (indigenous)': 'TW (Indigenous)',
- Tajik: 'TJ',
- 'Tajik (legacy)': 'TJ (Legacy)',
- 'Tamil (InScript, with Arabic numerals)': 'IN (Tam)',
- 'Tamil (InScript, with Tamil numerals)': 'IN (Tam Tamilnumbers)',
- "Tamil (Sri Lanka, TamilNet '99, TAB encoding)": 'LK (Tam TAB)',
- "Tamil (Sri Lanka, TamilNet '99)": 'LK (Tam Unicode)',
- "Tamil (TamilNet '99 with Tamil numerals)": 'IN (Tamilnet Tamilnumbers)',
- "Tamil (TamilNet '99, TAB encoding)": 'IN (Tamilnet TAB)',
- "Tamil (TamilNet '99, TSCII encoding)": 'IN (Tamilnet TSCII)',
- "Tamil (TamilNet '99)": 'IN (Tamilnet)',
- Tarifit: 'MA (Rif)',
- Tatar: 'RU (Tt)',
- Telugu: 'IN (Tel)',
- 'Telugu (KaGaPa, phonetic)': 'IN (Tel-Kagapa)',
- 'Telugu (Sarala)': 'IN (Tel-Sarala)',
- Thai: 'TH',
- 'Thai (Pattachote)': 'TH (Pat)',
- 'Thai (TIS-820.2538)': 'TH (Tis)',
- Tibetan: 'CN (Tib)',
- 'Tibetan (with ASCII numerals)': 'CN (Tib Asciinum)',
- Tswana: 'BW',
- Turkish: 'TR',
- 'Turkish (Alt-Q)': 'TR (Alt)',
- 'Turkish (E)': 'TR (E)',
- 'Turkish (F)': 'TR (F)',
- 'Turkish (Germany)': 'DE (Tr)',
- 'Turkish (intl., with dead keys)': 'TR (Intl)',
- Turkmen: 'TM',
- 'Turkmen (Alt-Q)': 'TM (Alt)',
- Udmurt: 'RU (Udm)',
- Ukrainian: 'UA',
- 'Ukrainian (homophonic)': 'UA (Homophonic)',
- 'Ukrainian (legacy)': 'UA (Legacy)',
- 'Ukrainian (macOS)': 'UA (MacOS)',
- 'Ukrainian (phonetic)': 'UA (Phonetic)',
- 'Ukrainian (standard RSTU)': 'UA (Rstu)',
- 'Ukrainian (typewriter)': 'UA (Typewriter)',
- 'Ukrainian (Windows)': 'UA (Winkeys)',
- 'Urdu (alt. phonetic)': 'IN (Urd-Phonetic3)',
- 'Urdu (Pakistan, CRULP)': 'PK (Urd-Crulp)',
- 'Urdu (Pakistan, NLA)': 'PK (Urd-Nla)',
- 'Urdu (Pakistan)': 'PK',
- 'Urdu (phonetic)': 'IN (Urd-Phonetic)',
- 'Urdu (Windows)': 'IN (Urd-Winkeys)',
- Uyghur: 'CN (Ug)',
- Uzbek: 'UZ',
- 'Uzbek (Afghanistan, OLPC)': 'AF (Uz-Olpc)',
- 'Uzbek (Afghanistan)': 'AF (Uz)',
- 'Uzbek (Latin)': 'UZ (Latin)',
- Vietnamese: 'VN',
- 'Vietnamese (France)': 'VN (Fr)',
- 'Vietnamese (US)': 'VN (Us)',
- Wolof: 'SN',
- Yakut: 'RU (Sah)',
- Yoruba: 'NG (Yoruba)',
- 'Unknown Layout': 'Unknown',
-} as const;
diff --git a/ags/HyprPanel/customModules/module.ts b/ags/HyprPanel/customModules/module.ts
deleted file mode 100644
index 5438ade..0000000
--- a/ags/HyprPanel/customModules/module.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import { BarBoxChild, Module } from 'lib/types/bar';
-import { BarButtonStyles } from 'lib/types/options';
-import { Bind } from 'lib/types/variable';
-import { GtkWidget } from 'lib/types/widget';
-import options from 'options';
-import Gtk from 'types/@girs/gtk-3.0/gtk-3.0';
-
-const { style } = options.theme.bar.buttons;
-
-const undefinedVar = Variable(undefined);
-
-export const module = ({
- icon,
- textIcon,
- label,
- tooltipText,
- boxClass,
- props = {},
- showLabelBinding = undefinedVar.bind('value'),
- showLabel,
- labelHook,
- hook,
-}: Module): BarBoxChild => {
- const getIconWidget = (): GtkWidget | undefined => {
- let iconWidget: Gtk.Widget | undefined;
-
- if (icon !== undefined) {
- iconWidget = Widget.Icon({
- class_name: `txt-icon bar-button-icon module-icon ${boxClass}`,
- icon: icon,
- }) as unknown as Gtk.Widget;
- } else if (textIcon !== undefined) {
- iconWidget = Widget.Label({
- class_name: `txt-icon bar-button-icon module-icon ${boxClass}`,
- label: textIcon,
- }) as unknown as Gtk.Widget;
- }
-
- return iconWidget;
- };
-
- return {
- component: Widget.Box({
- className: Utils.merge(
- [style.bind('value'), showLabelBinding],
- (style: BarButtonStyles, shwLabel: boolean) => {
- const shouldShowLabel = shwLabel || showLabel;
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `${boxClass} ${styleMap[style]} ${!shouldShowLabel ? 'no-label' : ''}`;
- },
- ),
- tooltip_text: tooltipText,
- children: Utils.merge([showLabelBinding], (showLabelBinding): Gtk.Widget[] => {
- const childrenArray: Gtk.Widget[] = [];
- const iconWidget = getIconWidget();
-
- if (iconWidget !== undefined) {
- childrenArray.push(iconWidget);
- }
-
- if (showLabelBinding) {
- childrenArray.push(
- Widget.Label({
- class_name: `bar-button-label module-label ${boxClass}`,
- label: label,
- setup: labelHook,
- }) as unknown as Gtk.Widget,
- );
- }
- return childrenArray;
- }) as Bind,
- setup: hook,
- }),
- tooltip_text: tooltipText,
- isVisible: true,
- boxClass,
- props,
- };
-};
diff --git a/ags/HyprPanel/customModules/netstat/computeNetwork.ts b/ags/HyprPanel/customModules/netstat/computeNetwork.ts
deleted file mode 100644
index e1b2dcd..0000000
--- a/ags/HyprPanel/customModules/netstat/computeNetwork.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import GLib from 'gi://GLib';
-import { Variable as VariableType } from 'types/variable';
-import { NetworkResourceData } from 'lib/types/customModules/network';
-import { GET_DEFAULT_NETSTAT_DATA } from 'lib/types/defaults/netstat';
-import { RateUnit } from 'lib/types/bar';
-
-let previousNetUsage = { rx: 0, tx: 0, time: 0 };
-
-const formatRate = (rate: number, type: string, round: boolean): string => {
- const fixed = round ? 0 : 2;
-
- switch (true) {
- case type === 'KiB':
- return `${(rate / 1e3).toFixed(fixed)} KiB/s`;
- case type === 'MiB':
- return `${(rate / 1e6).toFixed(fixed)} MiB/s`;
- case type === 'GiB':
- return `${(rate / 1e9).toFixed(fixed)} GiB/s`;
- case rate >= 1e9:
- return `${(rate / 1e9).toFixed(fixed)} GiB/s`;
- case rate >= 1e6:
- return `${(rate / 1e6).toFixed(fixed)} MiB/s`;
- case rate >= 1e3:
- return `${(rate / 1e3).toFixed(fixed)} KiB/s`;
- default:
- return `${rate.toFixed(fixed)} bytes/s`;
- }
-};
-
-interface NetworkUsage {
- name: string;
- rx: number;
- tx: number;
-}
-
-const parseInterfaceData = (line: string): NetworkUsage | null => {
- const trimmedLine = line.trim();
- if (!trimmedLine || trimmedLine.startsWith('Inter-') || trimmedLine.startsWith('face')) {
- return null;
- }
-
- const [iface, rx, , , , , , , , tx] = trimmedLine.split(/\s+/);
- const rxValue = parseInt(rx, 10);
- const txValue = parseInt(tx, 10);
- const cleanedIface = iface.replace(':', '');
-
- return { name: cleanedIface, rx: rxValue, tx: txValue };
-};
-
-const isValidInterface = (iface: NetworkUsage | null, interfaceName: string): boolean => {
- if (!iface) return false;
- if (interfaceName) return iface.name === interfaceName;
- return iface.name !== 'lo' && iface.rx > 0 && iface.tx > 0;
-};
-
-const getNetworkUsage = (interfaceName: string = ''): NetworkUsage => {
- const [success, data] = GLib.file_get_contents('/proc/net/dev');
- if (!success) {
- console.error('Failed to read /proc/net/dev');
- return { name: '', rx: 0, tx: 0 };
- }
-
- const lines = new TextDecoder('utf-8').decode(data).split('\n');
- for (const line of lines) {
- const iface = parseInterfaceData(line);
- if (isValidInterface(iface, interfaceName)) {
- return iface!;
- }
- }
-
- return { name: '', rx: 0, tx: 0 };
-};
-
-export const computeNetwork = (
- round: VariableType,
- interfaceNameVar: VariableType,
- dataType: VariableType,
-): NetworkResourceData => {
- const rateUnit = dataType.value;
- const interfaceName = interfaceNameVar ? interfaceNameVar.value : '';
-
- const DEFAULT_NETSTAT_DATA = GET_DEFAULT_NETSTAT_DATA(rateUnit);
- try {
- const { rx, tx, name } = getNetworkUsage(interfaceName);
- const currentTime = Date.now();
-
- if (!name) {
- return DEFAULT_NETSTAT_DATA;
- }
-
- if (previousNetUsage.time === 0) {
- previousNetUsage = { rx, tx, time: currentTime };
- return DEFAULT_NETSTAT_DATA;
- }
-
- const timeDiff = Math.max((currentTime - previousNetUsage.time) / 1000, 1);
- const rxRate = (rx - previousNetUsage.rx) / timeDiff;
- const txRate = (tx - previousNetUsage.tx) / timeDiff;
-
- previousNetUsage = { rx, tx, time: currentTime };
-
- return {
- in: formatRate(rxRate, rateUnit, round.value),
- out: formatRate(txRate, rateUnit, round.value),
- };
- } catch (error) {
- console.error('Error calculating network usage:', error);
- return DEFAULT_NETSTAT_DATA;
- }
-};
diff --git a/ags/HyprPanel/customModules/netstat/index.ts b/ags/HyprPanel/customModules/netstat/index.ts
deleted file mode 100644
index abfe2ca..0000000
--- a/ags/HyprPanel/customModules/netstat/index.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import options from 'options';
-import { module } from '../module';
-import { inputHandler } from 'customModules/utils';
-import { computeNetwork } from './computeNetwork';
-import { BarBoxChild, NetstatLabelType } from 'lib/types/bar';
-import Button from 'types/widgets/button';
-import { NetworkResourceData } from 'lib/types/customModules/network';
-import { NETWORK_LABEL_TYPES } from 'lib/types/defaults/bar';
-import { GET_DEFAULT_NETSTAT_DATA } from 'lib/types/defaults/netstat';
-import { pollVariable } from 'customModules/PollVar';
-import { Attribute, Child } from 'lib/types/widget';
-
-const {
- label,
- labelType,
- networkInterface,
- rateUnit,
- icon,
- round,
- leftClick,
- rightClick,
- middleClick,
- pollingInterval,
-} = options.bar.customModules.netstat;
-
-export const networkUsage = Variable(GET_DEFAULT_NETSTAT_DATA(rateUnit.value));
-
-pollVariable(
- // Variable to poll and update with the result of the function passed in
- networkUsage,
- // Variables that should trigger the polling function to update when they change
- [rateUnit.bind('value'), networkInterface.bind('value'), round.bind('value')],
- // Interval at which to poll
- pollingInterval.bind('value'),
- // Function to execute to get the network data
- computeNetwork,
- // Optional parameters to pass to the function
- // round is a boolean that determines whether to round the values
- round,
- // Optional parameters to pass to the function
- // networkInterface is the interface name to filter the data
- networkInterface,
- // Optional parameters to pass to the function
- // rateUnit is the unit to display the data in
- // e.g. KiB, MiB, GiB, etc.
- rateUnit,
-);
-
-export const Netstat = (): BarBoxChild => {
- const renderNetworkLabel = (lblType: NetstatLabelType, network: NetworkResourceData): string => {
- switch (lblType) {
- case 'in':
- return `↓ ${network.in}`;
- case 'out':
- return `↑ ${network.out}`;
- default:
- return `↓ ${network.in} ↑ ${network.out}`;
- }
- };
-
- const netstatModule = module({
- textIcon: icon.bind('value'),
- label: Utils.merge(
- [networkUsage.bind('value'), labelType.bind('value')],
- (network: NetworkResourceData, lblTyp: NetstatLabelType) => renderNetworkLabel(lblTyp, network),
- ),
- tooltipText: labelType.bind('value').as((lblTyp) => {
- return lblTyp === 'full' ? 'Ingress / Egress' : lblTyp === 'in' ? 'Ingress' : 'Egress';
- }),
- boxClass: 'netstat',
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- fn: () => {
- labelType.value = NETWORK_LABEL_TYPES[
- (NETWORK_LABEL_TYPES.indexOf(labelType.value) + 1) % NETWORK_LABEL_TYPES.length
- ] as NetstatLabelType;
- },
- },
- onScrollDown: {
- fn: () => {
- labelType.value = NETWORK_LABEL_TYPES[
- (NETWORK_LABEL_TYPES.indexOf(labelType.value) - 1 + NETWORK_LABEL_TYPES.length) %
- NETWORK_LABEL_TYPES.length
- ] as NetstatLabelType;
- },
- },
- });
- },
- },
- });
-
- return netstatModule;
-};
diff --git a/ags/HyprPanel/customModules/power/index.ts b/ags/HyprPanel/customModules/power/index.ts
deleted file mode 100644
index da678ad..0000000
--- a/ags/HyprPanel/customModules/power/index.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import options from 'options';
-import { module } from '../module';
-
-import { inputHandler } from 'customModules/utils';
-import Button from 'types/widgets/button';
-import { Attribute, Child } from 'lib/types/widget';
-import { BarBoxChild } from 'lib/types/bar';
-
-const { icon, leftClick, rightClick, middleClick, scrollUp, scrollDown } = options.bar.customModules.power;
-
-export const Power = (): BarBoxChild => {
- const powerModule = module({
- tooltipText: 'Power Menu',
- textIcon: icon.bind('value'),
- boxClass: 'powermodule',
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- cmd: scrollUp,
- },
- onScrollDown: {
- cmd: scrollDown,
- },
- });
- },
- },
- });
-
- return powerModule;
-};
diff --git a/ags/HyprPanel/customModules/ram/computeRam.ts b/ags/HyprPanel/customModules/ram/computeRam.ts
deleted file mode 100644
index b8026c2..0000000
--- a/ags/HyprPanel/customModules/ram/computeRam.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-const GLib = imports.gi.GLib;
-
-import { divide } from 'customModules/utils';
-import { GenericResourceData } from 'lib/types/customModules/generic';
-import { Variable as VariableType } from 'types/variable';
-
-export const calculateRamUsage = (round: VariableType): GenericResourceData => {
- try {
- const [success, meminfoBytes] = GLib.file_get_contents('/proc/meminfo');
-
- if (!success || !meminfoBytes) {
- throw new Error('Failed to read /proc/meminfo or file content is null.');
- }
-
- const meminfo = new TextDecoder('utf-8').decode(meminfoBytes);
-
- const totalMatch = meminfo.match(/MemTotal:\s+(\d+)/);
- const availableMatch = meminfo.match(/MemAvailable:\s+(\d+)/);
-
- if (!totalMatch || !availableMatch) {
- throw new Error('Failed to parse /proc/meminfo for memory values.');
- }
-
- const totalRamInBytes = parseInt(totalMatch[1], 10) * 1024;
- const availableRamInBytes = parseInt(availableMatch[1], 10) * 1024;
-
- let usedRam = totalRamInBytes - availableRamInBytes;
- usedRam = isNaN(usedRam) || usedRam < 0 ? 0 : usedRam;
-
- return {
- percentage: divide([totalRamInBytes, usedRam], round.value),
- total: totalRamInBytes,
- used: usedRam,
- free: availableRamInBytes,
- };
- } catch (error) {
- console.error('Error calculating RAM usage:', error);
- return { total: 0, used: 0, percentage: 0, free: 0 };
- }
-};
diff --git a/ags/HyprPanel/customModules/ram/index.ts b/ags/HyprPanel/customModules/ram/index.ts
deleted file mode 100644
index b651aaa..0000000
--- a/ags/HyprPanel/customModules/ram/index.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import options from 'options';
-
-// Module initializer
-import { module } from '../module';
-
-// Types
-import { GenericResourceData } from 'lib/types/customModules/generic';
-import Button from 'types/widgets/button';
-
-// Helper Methods
-import { calculateRamUsage } from './computeRam';
-
-// Utility Methods
-import { formatTooltip, inputHandler, renderResourceLabel } from 'customModules/utils';
-import { BarBoxChild, ResourceLabelType } from 'lib/types/bar';
-
-// Global Constants
-import { LABEL_TYPES } from 'lib/types/defaults/bar';
-import { pollVariable } from 'customModules/PollVar';
-import { Attribute, Child } from 'lib/types/widget';
-
-// All the user configurable options for the ram module that are needed
-const { label, labelType, round, leftClick, rightClick, middleClick, pollingInterval, icon } =
- options.bar.customModules.ram;
-
-const defaultRamData: GenericResourceData = { total: 0, used: 0, percentage: 0, free: 0 };
-const ramUsage = Variable(defaultRamData);
-
-pollVariable(ramUsage, [round.bind('value')], pollingInterval.bind('value'), calculateRamUsage, round);
-
-export const Ram = (): BarBoxChild => {
- const ramModule = module({
- textIcon: icon.bind('value'),
- label: Utils.merge(
- [ramUsage.bind('value'), labelType.bind('value'), round.bind('value')],
- (rmUsg: GenericResourceData, lblTyp: ResourceLabelType, round: boolean) => {
- const returnValue = renderResourceLabel(lblTyp, rmUsg, round);
-
- return returnValue;
- },
- ),
- tooltipText: labelType.bind('value').as((lblTyp) => {
- return formatTooltip('RAM', lblTyp);
- }),
- boxClass: 'ram',
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- fn: () => {
- labelType.value = LABEL_TYPES[
- (LABEL_TYPES.indexOf(labelType.value) + 1) % LABEL_TYPES.length
- ] as ResourceLabelType;
- },
- },
- onScrollDown: {
- fn: () => {
- labelType.value = LABEL_TYPES[
- (LABEL_TYPES.indexOf(labelType.value) - 1 + LABEL_TYPES.length) % LABEL_TYPES.length
- ] as ResourceLabelType;
- },
- },
- });
- },
- },
- });
-
- return ramModule;
-};
diff --git a/ags/HyprPanel/customModules/storage/computeStorage.ts b/ags/HyprPanel/customModules/storage/computeStorage.ts
deleted file mode 100644
index 49cbc14..0000000
--- a/ags/HyprPanel/customModules/storage/computeStorage.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// @ts-expect-error is a special directive that tells the compiler to use the GTop library
-import GTop from 'gi://GTop';
-
-import { divide } from 'customModules/utils';
-import { Variable as VariableType } from 'types/variable';
-import { GenericResourceData } from 'lib/types/customModules/generic';
-
-export const computeStorage = (round: VariableType): GenericResourceData => {
- try {
- const currentFsUsage = new GTop.glibtop_fsusage();
-
- GTop.glibtop_get_fsusage(currentFsUsage, '/');
-
- const total = currentFsUsage.blocks * currentFsUsage.block_size;
- const available = currentFsUsage.bavail * currentFsUsage.block_size;
- const used = total - available;
-
- return {
- total,
- used,
- free: available,
- percentage: divide([total, used], round.value),
- };
- } catch (error) {
- console.error('Error calculating RAM usage:', error);
- return { total: 0, used: 0, percentage: 0, free: 0 };
- }
-};
diff --git a/ags/HyprPanel/customModules/storage/index.ts b/ags/HyprPanel/customModules/storage/index.ts
deleted file mode 100644
index 9cfeb85..0000000
--- a/ags/HyprPanel/customModules/storage/index.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import options from 'options';
-import { module } from '../module';
-
-import { formatTooltip, inputHandler, renderResourceLabel } from 'customModules/utils';
-import { computeStorage } from './computeStorage';
-import { BarBoxChild, ResourceLabelType } from 'lib/types/bar';
-import { GenericResourceData } from 'lib/types/customModules/generic';
-import Button from 'types/widgets/button';
-import { LABEL_TYPES } from 'lib/types/defaults/bar';
-import { pollVariable } from 'customModules/PollVar';
-import { Attribute, Child } from 'lib/types/widget';
-
-const { label, labelType, icon, round, leftClick, rightClick, middleClick, pollingInterval } =
- options.bar.customModules.storage;
-
-const defaultStorageData = { total: 0, used: 0, percentage: 0, free: 0 };
-
-const storageUsage = Variable(defaultStorageData);
-
-pollVariable(storageUsage, [round.bind('value')], pollingInterval.bind('value'), computeStorage, round);
-
-export const Storage = (): BarBoxChild => {
- const storageModule = module({
- textIcon: icon.bind('value'),
- label: Utils.merge(
- [storageUsage.bind('value'), labelType.bind('value'), round.bind('value')],
- (storage: GenericResourceData, lblTyp: ResourceLabelType, round: boolean) => {
- return renderResourceLabel(lblTyp, storage, round);
- },
- ),
- tooltipText: labelType.bind('value').as((lblTyp) => {
- return formatTooltip('Storage', lblTyp);
- }),
- boxClass: 'storage',
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- fn: () => {
- labelType.value = LABEL_TYPES[
- (LABEL_TYPES.indexOf(labelType.value) + 1) % LABEL_TYPES.length
- ] as ResourceLabelType;
- },
- },
- onScrollDown: {
- fn: () => {
- labelType.value = LABEL_TYPES[
- (LABEL_TYPES.indexOf(labelType.value) - 1 + LABEL_TYPES.length) % LABEL_TYPES.length
- ] as ResourceLabelType;
- },
- },
- });
- },
- },
- });
-
- return storageModule;
-};
diff --git a/ags/HyprPanel/customModules/submap/helpers.ts b/ags/HyprPanel/customModules/submap/helpers.ts
deleted file mode 100644
index 0c38718..0000000
--- a/ags/HyprPanel/customModules/submap/helpers.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Variable } from 'types/variable';
-
-const hyprland = await Service.import('hyprland');
-
-export const isSubmapEnabled = (submap: string, enabled: string, disabled: string): string => {
- return submap !== 'default' ? enabled : disabled;
-};
-
-export const getInitialSubmap = (submapStatus: Variable): void => {
- let submap = hyprland.message('submap');
-
- const newLineCarriage = /\n/g;
- submap = submap.replace(newLineCarriage, '');
-
- if (submap === 'unknown request') {
- submap = 'default';
- }
-
- submapStatus.value = submap;
-};
diff --git a/ags/HyprPanel/customModules/submap/index.ts b/ags/HyprPanel/customModules/submap/index.ts
deleted file mode 100644
index c83316e..0000000
--- a/ags/HyprPanel/customModules/submap/index.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-const hyprland = await Service.import('hyprland');
-import options from 'options';
-import { module } from '../module';
-
-import { inputHandler } from 'customModules/utils';
-import Button from 'types/widgets/button';
-import { Variable as VariableType } from 'types/variable';
-import { Attribute, Child } from 'lib/types/widget';
-import { BarBoxChild } from 'lib/types/bar';
-import { capitalizeFirstLetter } from 'lib/utils';
-import { getInitialSubmap, isSubmapEnabled } from './helpers';
-
-const {
- label,
- showSubmapName,
- enabledIcon,
- disabledIcon,
- enabledText,
- disabledText,
- leftClick,
- rightClick,
- middleClick,
- scrollUp,
- scrollDown,
-} = options.bar.customModules.submap;
-
-const submapStatus: VariableType = Variable('default');
-
-hyprland.connect('submap', (_, currentSubmap) => {
- if (currentSubmap.length === 0) {
- submapStatus.value = 'default';
- } else {
- submapStatus.value = currentSubmap;
- }
-});
-
-getInitialSubmap(submapStatus);
-
-export const Submap = (): BarBoxChild => {
- const submapModule = module({
- textIcon: Utils.merge(
- [submapStatus.bind('value'), enabledIcon.bind('value'), disabledIcon.bind('value')],
- (status, enabled, disabled) => {
- return isSubmapEnabled(status, enabled, disabled);
- },
- ),
- tooltipText: Utils.merge(
- [
- submapStatus.bind('value'),
- enabledText.bind('value'),
- disabledText.bind('value'),
- showSubmapName.bind('value'),
- ],
- (status, enabled, disabled, showSmName) => {
- if (showSmName) {
- return capitalizeFirstLetter(status);
- }
- return isSubmapEnabled(status, enabled, disabled);
- },
- ),
- boxClass: 'submap',
- label: Utils.merge(
- [
- submapStatus.bind('value'),
- enabledText.bind('value'),
- disabledText.bind('value'),
- showSubmapName.bind('value'),
- ],
- (status, enabled, disabled, showSmName) => {
- if (showSmName) {
- return capitalizeFirstLetter(status);
- }
- return isSubmapEnabled(status, enabled, disabled);
- },
- ),
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- cmd: scrollUp,
- },
- onScrollDown: {
- cmd: scrollDown,
- },
- });
- },
- },
- });
-
- return submapModule;
-};
diff --git a/ags/HyprPanel/customModules/theme.ts b/ags/HyprPanel/customModules/theme.ts
deleted file mode 100644
index 2ac92ff..0000000
--- a/ags/HyprPanel/customModules/theme.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-import { Option } from 'widget/settings/shared/Option';
-import { Header } from 'widget/settings/shared/Header';
-
-import options from 'options';
-import Scrollable from 'types/widgets/scrollable';
-import { Attribute, GtkWidget } from 'lib/types/widget';
-
-export const CustomModuleTheme = (): Scrollable => {
- return Widget.Scrollable({
- vscroll: 'automatic',
- hscroll: 'automatic',
- class_name: 'menu-theme-page customModules paged-container',
- child: Widget.Box({
- class_name: 'bar-theme-page paged-container',
- vertical: true,
- children: [
- Header('RAM'),
- Option({ opt: options.theme.bar.buttons.modules.ram.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.ram.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.ram.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.ram.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.ram.border, title: 'Border', type: 'color' }),
-
- Header('CPU'),
- Option({ opt: options.theme.bar.buttons.modules.cpu.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.cpu.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.cpu.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.cpu.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.cpu.border, title: 'Border', type: 'color' }),
-
- Header('Storage'),
- Option({ opt: options.theme.bar.buttons.modules.storage.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.storage.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.storage.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.storage.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.storage.border, title: 'Border', type: 'color' }),
-
- Header('Netstat'),
- Option({ opt: options.theme.bar.buttons.modules.netstat.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.netstat.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.netstat.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.netstat.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.netstat.border, title: 'Border', type: 'color' }),
-
- Header('Keyboard Layout'),
- Option({ opt: options.theme.bar.buttons.modules.kbLayout.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.kbLayout.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.kbLayout.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.kbLayout.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.kbLayout.border, title: 'Border', type: 'color' }),
-
- Header('Updates'),
- Option({ opt: options.theme.bar.buttons.modules.updates.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.updates.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.updates.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.updates.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.updates.border, title: 'Border', type: 'color' }),
-
- Header('Submap'),
- Option({ opt: options.theme.bar.buttons.modules.submap.text, title: 'Text', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.submap.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.submap.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.submap.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.submap.border, title: 'Border', type: 'color' }),
-
- Header('Weather'),
- Option({ opt: options.theme.bar.buttons.modules.weather.icon, title: 'Icon', type: 'color' }),
- Option({ opt: options.theme.bar.buttons.modules.weather.text, title: 'Text', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.weather.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.weather.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.weather.border, title: 'Border', type: 'color' }),
-
- Header('Power'),
- Option({ opt: options.theme.bar.buttons.modules.power.icon, title: 'Icon', type: 'color' }),
- Option({
- opt: options.theme.bar.buttons.modules.power.background,
- title: 'Label Background',
- type: 'color',
- }),
- Option({
- opt: options.theme.bar.buttons.modules.power.icon_background,
- title: 'Icon Background',
- subtitle:
- "Applies a background color to the icon section of the button.\nRequires 'split' button styling.",
- type: 'color',
- }),
- Option({ opt: options.theme.bar.buttons.modules.power.border, title: 'Border', type: 'color' }),
- ],
- }),
- });
-};
diff --git a/ags/HyprPanel/customModules/updates/index.ts b/ags/HyprPanel/customModules/updates/index.ts
deleted file mode 100644
index 4be5ee8..0000000
--- a/ags/HyprPanel/customModules/updates/index.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import options from 'options';
-import { module } from '../module';
-
-import { inputHandler } from 'customModules/utils';
-import Button from 'types/widgets/button';
-import { Variable as VariableType } from 'types/variable';
-import { pollVariableBash } from 'customModules/PollVar';
-import { Attribute, Child } from 'lib/types/widget';
-import { BarBoxChild } from 'lib/types/bar';
-
-const {
- updateCommand,
- label,
- padZero,
- pollingInterval,
- icon,
- leftClick,
- rightClick,
- middleClick,
- scrollUp,
- scrollDown,
-} = options.bar.customModules.updates;
-
-const pendingUpdates: VariableType = Variable(' 0');
-
-const processUpdateCount = (updateCount: string): string => {
- if (!padZero.value) return updateCount;
- return `${updateCount.padStart(2, '0')}`;
-};
-
-pollVariableBash(
- pendingUpdates,
- [padZero.bind('value')],
- pollingInterval.bind('value'),
- updateCommand.value,
- processUpdateCount,
-);
-
-export const Updates = (): BarBoxChild => {
- const updatesModule = module({
- textIcon: icon.bind('value'),
- tooltipText: pendingUpdates.bind('value').as((v) => `${v} updates available`),
- boxClass: 'updates',
- label: pendingUpdates.bind('value'),
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- cmd: scrollUp,
- },
- onScrollDown: {
- cmd: scrollDown,
- },
- });
- },
- },
- });
-
- return updatesModule;
-};
diff --git a/ags/HyprPanel/customModules/utils.ts b/ags/HyprPanel/customModules/utils.ts
deleted file mode 100644
index b68258e..0000000
--- a/ags/HyprPanel/customModules/utils.ts
+++ /dev/null
@@ -1,197 +0,0 @@
-import { ResourceLabelType } from 'lib/types/bar';
-import { GenericResourceData, Postfix } from 'lib/types/customModules/generic';
-import { InputHandlerEvents, RunAsyncCommand } from 'lib/types/customModules/utils';
-import { ThrottleFn, ThrottleFnCallback } from 'lib/types/utils';
-import { Attribute, Child, EventArgs } from 'lib/types/widget';
-import { Binding } from 'lib/utils';
-import { openMenu } from 'modules/bar/utils';
-import options from 'options';
-import Gdk from 'types/@girs/gdk-3.0/gdk-3.0';
-import { Variable as VariableType } from 'types/variable';
-import Button from 'types/widgets/button';
-
-const { scrollSpeed } = options.bar.customModules;
-
-export const runAsyncCommand: RunAsyncCommand = (cmd, events, fn): void => {
- if (cmd.startsWith('menu:')) {
- const menuName = cmd.split(':')[1].trim().toLowerCase();
- openMenu(events.clicked, events.event, `${menuName}menu`);
-
- return;
- }
-
- Utils.execAsync(`bash -c "${cmd}"`)
- .then((output) => {
- if (fn !== undefined) {
- fn(output);
- }
- })
- .catch((err) => console.error(`Error running command "${cmd}": ${err})`));
-};
-
-export function throttle(func: T, limit: number): T {
- let inThrottle: boolean;
- return function (this: ThisParameterType, ...args: Parameters) {
- if (!inThrottle) {
- func.apply(this, args);
- inThrottle = true;
- setTimeout(() => {
- inThrottle = false;
- }, limit);
- }
- } as T;
-}
-
-export const throttledScrollHandler = (interval: number): ThrottleFn =>
- throttle((cmd: string, events: EventArgs, fn: ThrottleFnCallback) => {
- runAsyncCommand(cmd, events, fn);
- }, 200 / interval);
-
-const dummyVar = Variable('');
-
-export const inputHandler = (
- self: Button,
- { onPrimaryClick, onSecondaryClick, onMiddleClick, onScrollUp, onScrollDown }: InputHandlerEvents,
-): void => {
- const sanitizeInput = (input: VariableType): string => {
- if (input === undefined) {
- return '';
- }
- return input.value;
- };
-
- const updateHandlers = (): void => {
- const interval = scrollSpeed.value;
- const throttledHandler = throttledScrollHandler(interval);
-
- self.on_primary_click = (clicked: Button, event: Gdk.Event): void =>
- runAsyncCommand(sanitizeInput(onPrimaryClick?.cmd || dummyVar), { clicked, event }, onPrimaryClick.fn);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void =>
- runAsyncCommand(sanitizeInput(onSecondaryClick?.cmd || dummyVar), { clicked, event }, onSecondaryClick.fn);
-
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void =>
- runAsyncCommand(sanitizeInput(onMiddleClick?.cmd || dummyVar), { clicked, event }, onMiddleClick.fn);
-
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void =>
- throttledHandler(sanitizeInput(onScrollUp?.cmd || dummyVar), { clicked, event }, onScrollUp.fn);
-
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void =>
- throttledHandler(sanitizeInput(onScrollDown?.cmd || dummyVar), { clicked, event }, onScrollDown.fn);
- };
-
- // Initial setup of event handlers
- updateHandlers();
-
- const sanitizeVariable = (someVar: VariableType | undefined): Binding => {
- if (someVar === undefined || typeof someVar.bind !== 'function') {
- return dummyVar.bind('value');
- }
- return someVar.bind('value');
- };
-
- // Re-run the update whenever scrollSpeed changes
- Utils.merge(
- [
- scrollSpeed.bind('value'),
- sanitizeVariable(onPrimaryClick),
- sanitizeVariable(onSecondaryClick),
- sanitizeVariable(onMiddleClick),
- sanitizeVariable(onScrollUp),
- sanitizeVariable(onScrollDown),
- ],
- updateHandlers,
- );
-};
-
-export const divide = ([total, used]: number[], round: boolean): number => {
- const percentageTotal = (used / total) * 100;
- if (round) {
- return total > 0 ? Math.round(percentageTotal) : 0;
- }
- return total > 0 ? parseFloat(percentageTotal.toFixed(2)) : 0;
-};
-
-export const formatSizeInKiB = (sizeInBytes: number, round: boolean): number => {
- const sizeInGiB = sizeInBytes / 1024 ** 1;
- return round ? Math.round(sizeInGiB) : parseFloat(sizeInGiB.toFixed(2));
-};
-export const formatSizeInMiB = (sizeInBytes: number, round: boolean): number => {
- const sizeInGiB = sizeInBytes / 1024 ** 2;
- return round ? Math.round(sizeInGiB) : parseFloat(sizeInGiB.toFixed(2));
-};
-export const formatSizeInGiB = (sizeInBytes: number, round: boolean): number => {
- const sizeInGiB = sizeInBytes / 1024 ** 3;
- return round ? Math.round(sizeInGiB) : parseFloat(sizeInGiB.toFixed(2));
-};
-export const formatSizeInTiB = (sizeInBytes: number, round: boolean): number => {
- const sizeInGiB = sizeInBytes / 1024 ** 4;
- return round ? Math.round(sizeInGiB) : parseFloat(sizeInGiB.toFixed(2));
-};
-
-export const autoFormatSize = (sizeInBytes: number, round: boolean): number => {
- // auto convert to GiB, MiB, KiB, TiB, or bytes
- if (sizeInBytes >= 1024 ** 4) return formatSizeInTiB(sizeInBytes, round);
- if (sizeInBytes >= 1024 ** 3) return formatSizeInGiB(sizeInBytes, round);
- if (sizeInBytes >= 1024 ** 2) return formatSizeInMiB(sizeInBytes, round);
- if (sizeInBytes >= 1024 ** 1) return formatSizeInKiB(sizeInBytes, round);
-
- return sizeInBytes;
-};
-
-export const getPostfix = (sizeInBytes: number): Postfix => {
- if (sizeInBytes >= 1024 ** 4) return 'TiB';
- if (sizeInBytes >= 1024 ** 3) return 'GiB';
- if (sizeInBytes >= 1024 ** 2) return 'MiB';
- if (sizeInBytes >= 1024 ** 1) return 'KiB';
-
- return 'B';
-};
-
-export const renderResourceLabel = (lblType: ResourceLabelType, rmUsg: GenericResourceData, round: boolean): string => {
- const { used, total, percentage, free } = rmUsg;
-
- const formatFunctions = {
- TiB: formatSizeInTiB,
- GiB: formatSizeInGiB,
- MiB: formatSizeInMiB,
- KiB: formatSizeInKiB,
- B: (size: number): number => size,
- };
-
- // Get them datas in proper GiB, MiB, KiB, TiB, or bytes
- const totalSizeFormatted = autoFormatSize(total, round);
- // get the postfix: one of [TiB, GiB, MiB, KiB, B]
- const postfix = getPostfix(total);
-
- // Determine which format function to use
- const formatUsed = formatFunctions[postfix] || formatFunctions['B'];
- const usedSizeFormatted = formatUsed(used, round);
-
- if (lblType === 'used/total') {
- return `${usedSizeFormatted}/${totalSizeFormatted} ${postfix}`;
- }
- if (lblType === 'used') {
- return `${autoFormatSize(used, round)} ${getPostfix(used)}`;
- }
- if (lblType === 'free') {
- return `${autoFormatSize(free, round)} ${getPostfix(free)}`;
- }
-
- return `${percentage}%`;
-};
-
-export const formatTooltip = (dataType: string, lblTyp: ResourceLabelType): string => {
- switch (lblTyp) {
- case 'used':
- return `Used ${dataType}`;
- case 'free':
- return `Free ${dataType}`;
- case 'used/total':
- return `Used/Total ${dataType}`;
- case 'percentage':
- return `Percentage ${dataType} Usage`;
- default:
- return '';
- }
-};
diff --git a/ags/HyprPanel/customModules/weather/index.ts b/ags/HyprPanel/customModules/weather/index.ts
deleted file mode 100644
index b40995c..0000000
--- a/ags/HyprPanel/customModules/weather/index.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import options from 'options';
-import { module } from '../module';
-
-import { inputHandler } from 'customModules/utils';
-import Button from 'types/widgets/button';
-import { getWeatherStatusTextIcon, globalWeatherVar } from 'globals/weather';
-import { Attribute, Child } from 'lib/types/widget';
-import { BarBoxChild } from 'lib/types/bar';
-
-const { label, unit, leftClick, rightClick, middleClick, scrollUp, scrollDown } = options.bar.customModules.weather;
-
-export const Weather = (): BarBoxChild => {
- const weatherModule = module({
- textIcon: Utils.merge([globalWeatherVar.bind('value')], (wthr) => {
- const weatherStatusIcon = getWeatherStatusTextIcon(wthr);
- return weatherStatusIcon;
- }),
- tooltipText: globalWeatherVar.bind('value').as((v) => `Weather Status: ${v.current.condition.text}`),
- boxClass: 'weather-custom',
- label: Utils.merge([globalWeatherVar.bind('value'), unit.bind('value')], (wthr, unt) => {
- if (unt === 'imperial') {
- return `${Math.ceil(wthr.current.temp_f)}° F`;
- } else {
- return `${Math.ceil(wthr.current.temp_c)}° C`;
- }
- }),
- showLabelBinding: label.bind('value'),
- props: {
- setup: (self: Button) => {
- inputHandler(self, {
- onPrimaryClick: {
- cmd: leftClick,
- },
- onSecondaryClick: {
- cmd: rightClick,
- },
- onMiddleClick: {
- cmd: middleClick,
- },
- onScrollUp: {
- cmd: scrollUp,
- },
- onScrollDown: {
- cmd: scrollDown,
- },
- });
- },
- },
- });
-
- return weatherModule;
-};
diff --git a/ags/HyprPanel/directoryMonitorService.ts b/ags/HyprPanel/directoryMonitorService.ts
deleted file mode 100644
index 2e1a74a..0000000
--- a/ags/HyprPanel/directoryMonitorService.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import Service from 'resource:///com/github/Aylur/ags/service.js';
-import App from 'resource:///com/github/Aylur/ags/app.js';
-import { monitorFile } from 'resource:///com/github/Aylur/ags/utils.js';
-import Gio from 'gi://Gio';
-import { FileInfo } from 'types/@girs/gio-2.0/gio-2.0.cjs';
-
-class DirectoryMonitorService extends Service {
- static {
- Service.register(this, {}, {});
- }
-
- constructor() {
- super();
- this.recursiveDirectoryMonitor(`${App.configDir}/scss`);
- }
-
- recursiveDirectoryMonitor(directoryPath: string): void {
- monitorFile(directoryPath, (_, eventType) => {
- if (eventType === Gio.FileMonitorEvent.CHANGES_DONE_HINT) {
- this.emit('changed');
- }
- });
-
- const directory = Gio.File.new_for_path(directoryPath);
- const enumerator = directory.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
-
- let fileInfo: FileInfo;
- while ((fileInfo = enumerator.next_file(null) as FileInfo) !== null) {
- const childPath = directoryPath + '/' + fileInfo.get_name();
- if (fileInfo.get_file_type() === Gio.FileType.DIRECTORY) {
- this.recursiveDirectoryMonitor(childPath);
- }
- }
- }
-}
-
-const service = new DirectoryMonitorService();
-export default service;
diff --git a/ags/HyprPanel/flake.lock b/ags/HyprPanel/flake.lock
deleted file mode 100644
index 2417d92..0000000
--- a/ags/HyprPanel/flake.lock
+++ /dev/null
@@ -1,78 +0,0 @@
-{
- "nodes": {
- "ags": {
- "inputs": {
- "nixpkgs": "nixpkgs",
- "systems": "systems"
- },
- "locked": {
- "lastModified": 1727303518,
- "narHash": "sha256-lO5JMynTxNZxg/+E4/Y9reeLGIz/M8cEue+Re4cP6qo=",
- "owner": "Aylur",
- "repo": "ags",
- "rev": "cd543afec4d9ed708990e5ba52184716809bf248",
- "type": "github"
- },
- "original": {
- "owner": "Aylur",
- "repo": "ags",
- "type": "github"
- }
- },
- "nixpkgs": {
- "locked": {
- "lastModified": 1725634671,
- "narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_2": {
- "locked": {
- "lastModified": 1727634051,
- "narHash": "sha256-S5kVU7U82LfpEukbn/ihcyNt2+EvG7Z5unsKW9H/yFA=",
- "owner": "nixos",
- "repo": "nixpkgs",
- "rev": "06cf0e1da4208d3766d898b7fdab6513366d45b9",
- "type": "github"
- },
- "original": {
- "owner": "nixos",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "root": {
- "inputs": {
- "ags": "ags",
- "nixpkgs": "nixpkgs_2"
- }
- },
- "systems": {
- "locked": {
- "lastModified": 1689347949,
- "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
- "owner": "nix-systems",
- "repo": "default-linux",
- "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default-linux",
- "type": "github"
- }
- }
- },
- "root": "root",
- "version": 7
-}
diff --git a/ags/HyprPanel/flake.nix b/ags/HyprPanel/flake.nix
deleted file mode 100644
index 685fed7..0000000
--- a/ags/HyprPanel/flake.nix
+++ /dev/null
@@ -1,78 +0,0 @@
-{
- description = "A Bar/Panel for Hyprland with extensive customizability.";
-
- inputs = {
- nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
- ags.url = "github:Aylur/ags";
- };
-
- outputs = inputs: let
- systems = [
- "x86_64-linux"
- "x86_64-darwin"
- "aarch64-darwin"
- "aarch64-linux"
- ];
- forEachSystem = inputs.nixpkgs.lib.genAttrs systems;
- pkgsFor = forEachSystem (
- system:
- import inputs.nixpkgs {
- inherit system;
- config.allowUnfree = true;
- }
- );
-
- devShellFor = system:
- inputs.nixpkgs.lib.genAttrs ["default"] (
- _:
- inputs.nixpkgs.legacyPackages.${system}.mkShell {
- buildInputs = [
- pkgsFor.${system}.esbuild
- pkgsFor.${system}.fish
- pkgsFor.${system}.typescript
- pkgsFor.${system}.bun
- pkgsFor.${system}.libnotify
- pkgsFor.${system}.dart-sass
- pkgsFor.${system}.fd
- pkgsFor.${system}.btop
- pkgsFor.${system}.bluez
- pkgsFor.${system}.libgtop
- pkgsFor.${system}.gobject-introspection
- pkgsFor.${system}.glib
- pkgsFor.${system}.bluez-tools
- pkgsFor.${system}.grimblast
- pkgsFor.${system}.gpu-screen-recorder
- pkgsFor.${system}.brightnessctl
- pkgsFor.${system}.gnome-bluetooth
- pkgsFor.${system}.python3
- pkgsFor.${system}.matugen
- inputs.ags.packages.${system}.agsWithTypes
- ];
- nativeBuildInputs = with pkgsFor.${system}; [
- nixfmt-rfc-style
- nil
- ];
- shellHook = ''
- export GDK_BACKEND=wayland
- export GI_TYPELIB_PATH=${pkgsFor.${system}.libgtop}/lib/girepository-1.0:${pkgsFor.${system}.glib}/lib/girepository-1.0:$GI_TYPELIB_PATH
- '';
- }
- );
- in {
- devShells = forEachSystem devShellFor;
-
- overlay = final: prev: {
- hyprpanel =
- if final ? callPackage
- then (final.callPackage ./nix {inherit inputs;}).desktop.script
- else inputs.self.packages.${prev.stdenv.system}.default;
- };
- packages = forEachSystem (
- system: let
- pkgs = pkgsFor.${system};
- in {
- default = (pkgs.callPackage ./nix {inherit inputs;}).desktop.script;
- }
- );
- };
-}
diff --git a/ags/HyprPanel/globals.d.ts b/ags/HyprPanel/globals.d.ts
deleted file mode 100644
index 8e44a87..0000000
--- a/ags/HyprPanel/globals.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-// globals.d.ts
-/* eslint-disable no-var */
-
-import { Options, Variable as VariableType } from 'types/variable';
-
-declare global {
- var useTheme: (filePath: string) => void;
- var isWindowVisible: (windowName: string) => boolean;
- var globalWeatherVar: VariableType;
- var options: Options;
- var removingNotifications: VariableType;
-}
-
-export {};
diff --git a/ags/HyprPanel/globals/dropdown.ts b/ags/HyprPanel/globals/dropdown.ts
deleted file mode 100644
index b1178bf..0000000
--- a/ags/HyprPanel/globals/dropdown.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Variable as VariableType } from 'types/variable';
-
-type GlobalEventBoxes = {
- [key: string]: unknown;
-};
-export const globalEventBoxes: VariableType = Variable({});
diff --git a/ags/HyprPanel/globals/network.ts b/ags/HyprPanel/globals/network.ts
deleted file mode 100644
index 44fbf77..0000000
--- a/ags/HyprPanel/globals/network.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export const WIFI_STATUS_MAP = {
- unknown: 'Status Unknown',
- unmanaged: 'Unmanaged',
- unavailable: 'Unavailable',
- disconnected: 'Disconnected',
- prepare: 'Preparing Connecting',
- config: 'Connecting',
- need_auth: 'Needs Authentication',
- ip_config: 'Requesting IP',
- ip_check: 'Checking Access',
- secondaries: 'Waiting on Secondaries',
- activated: 'Connected',
- deactivating: 'Disconnecting',
- failed: 'Connection Failed',
-} as const;
diff --git a/ags/HyprPanel/globals/notification.ts b/ags/HyprPanel/globals/notification.ts
deleted file mode 100644
index f382bc4..0000000
--- a/ags/HyprPanel/globals/notification.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import icons from 'modules/icons/index';
-import { Notification } from 'types/service/notifications';
-
-export const removingNotifications = Variable(false);
-
-export const getNotificationIcon = (app_name: string, app_icon: string, app_entry: string): string => {
- let icon: string = icons.fallback.notification;
-
- if (Utils.lookUpIcon(app_name) || Utils.lookUpIcon(app_name.toLowerCase() || '')) {
- icon = Utils.lookUpIcon(app_name)
- ? app_name
- : Utils.lookUpIcon(app_name.toLowerCase())
- ? app_name.toLowerCase()
- : '';
- }
-
- if (Utils.lookUpIcon(app_icon) && icon === '') {
- icon = app_icon;
- }
-
- if (Utils.lookUpIcon(app_entry || '') && icon === '') {
- icon = app_entry || '';
- }
-
- return icon;
-};
-
-export const closeNotifications = async (notifications: Notification[], delay: number): Promise => {
- removingNotifications.value = true;
- for (const notif of notifications) {
- notif.close();
- await new Promise((resolve) => setTimeout(resolve, delay));
- }
- removingNotifications.value = false;
-};
-
-globalThis['removingNotifications'] = removingNotifications;
diff --git a/ags/HyprPanel/globals/useTheme.ts b/ags/HyprPanel/globals/useTheme.ts
deleted file mode 100644
index 15c2322..0000000
--- a/ags/HyprPanel/globals/useTheme.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import Gio from 'gi://Gio';
-import { bash, Notify } from 'lib/utils';
-import icons from 'lib/icons';
-import { filterConfigForThemeOnly, loadJsonFile, saveConfigToFile } from 'widget/settings/shared/FileChooser';
-
-export const hexColorPattern = /^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
-
-globalThis.useTheme = (filePath: string): void => {
- const importedConfig = loadJsonFile(filePath);
-
- if (!importedConfig) {
- return;
- }
-
- Notify({
- summary: `Importing Theme`,
- body: `Importing: ${filePath}`,
- iconName: icons.ui.info,
- timeout: 7000,
- });
-
- const tmpConfigFile = Gio.File.new_for_path(`${TMP}/config.json`);
- const optionsConfigFile = Gio.File.new_for_path(OPTIONS);
-
- const [tmpSuccess, tmpContent] = tmpConfigFile.load_contents(null);
- const [optionsSuccess, optionsContent] = optionsConfigFile.load_contents(null);
-
- if (!tmpSuccess || !optionsSuccess) {
- console.error('Failed to read existing configuration files.');
- return;
- }
-
- let tmpConfig = JSON.parse(new TextDecoder('utf-8').decode(tmpContent));
- let optionsConfig = JSON.parse(new TextDecoder('utf-8').decode(optionsContent));
-
- const filteredConfig = filterConfigForThemeOnly(importedConfig);
- tmpConfig = { ...tmpConfig, ...filteredConfig };
- optionsConfig = { ...optionsConfig, ...filteredConfig };
-
- saveConfigToFile(tmpConfig, `${TMP}/config.json`);
- saveConfigToFile(optionsConfig, OPTIONS);
- bash('pkill ags && ags');
-};
diff --git a/ags/HyprPanel/globals/utilities.ts b/ags/HyprPanel/globals/utilities.ts
deleted file mode 100644
index 438c666..0000000
--- a/ags/HyprPanel/globals/utilities.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-globalThis.isWindowVisible = (windowName: string): boolean => {
- const appWindow = App.getWindow(windowName);
-
- if (appWindow === undefined) {
- return false;
- }
- return appWindow.visible;
-};
diff --git a/ags/HyprPanel/globals/variables.ts b/ags/HyprPanel/globals/variables.ts
deleted file mode 100644
index ea2eb5d..0000000
--- a/ags/HyprPanel/globals/variables.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Opt } from 'lib/option';
-import { HexColor, MatugenTheme, RecursiveOptionsObject } from 'lib/types/options';
-
-export const isOpt = (value: unknown): value is Opt =>
- typeof value === 'object' && value !== null && 'value' in value && value instanceof Opt;
-
-export const isOptString = (value: unknown): value is Opt => {
- return value instanceof Opt && typeof value.value === 'string';
-};
-
-export const isOptNumber = (value: unknown): value is Opt => {
- return value instanceof Opt && typeof value.value === 'number';
-};
-
-export const isOptBoolean = (value: unknown): value is Opt => {
- return value instanceof Opt && typeof value.value === 'boolean';
-};
-
-export const isOptMatugenTheme = (value: unknown): value is Opt => {
- return value instanceof Opt && typeof value.value === 'object' && 'specificProperty' in value.value; // Replace 'specificProperty' with an actual property of MatugenTheme
-};
-
-export const isRecursiveOptionsObject = (value: unknown): value is RecursiveOptionsObject => {
- return typeof value === 'object' && value !== null && !(value instanceof Opt);
-};
-
-export const isHexColor = (val: unknown): val is HexColor => {
- return typeof val === 'string' && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(val);
-};
diff --git a/ags/HyprPanel/globals/weather.ts b/ags/HyprPanel/globals/weather.ts
deleted file mode 100644
index 3da7ba1..0000000
--- a/ags/HyprPanel/globals/weather.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import options from 'options';
-import { UnitType, Weather, WeatherIconTitle, WeatherIcon } from 'lib/types/weather.js';
-import { DEFAULT_WEATHER } from 'lib/types/defaults/weather.js';
-import GLib from 'gi://GLib?version=2.0';
-import { weatherIcons } from 'modules/icons/weather.js';
-
-const { key, interval, location } = options.menus.clock.weather;
-
-export const globalWeatherVar = Variable(DEFAULT_WEATHER);
-
-let weatherIntervalInstance: null | number = null;
-
-const weatherIntervalFn = (weatherInterval: number, loc: string, weatherKey: string): void => {
- if (weatherIntervalInstance !== null) {
- GLib.source_remove(weatherIntervalInstance);
- }
-
- const formattedLocation = loc.replace(' ', '%20');
-
- weatherIntervalInstance = Utils.interval(weatherInterval, () => {
- Utils.execAsync(
- `curl "https://api.weatherapi.com/v1/forecast.json?key=${weatherKey}&q=${formattedLocation}&days=1&aqi=no&alerts=no"`,
- )
- .then((res) => {
- try {
- if (typeof res !== 'string') {
- return (globalWeatherVar.value = DEFAULT_WEATHER);
- }
-
- const parsedWeather = JSON.parse(res);
-
- if (Object.keys(parsedWeather).includes('error')) {
- return (globalWeatherVar.value = DEFAULT_WEATHER);
- }
-
- return (globalWeatherVar.value = parsedWeather);
- } catch (error) {
- globalWeatherVar.value = DEFAULT_WEATHER;
- console.warn(`Failed to parse weather data: ${error}`);
- }
- })
- .catch((err) => {
- console.error(`Failed to fetch weather: ${err}`);
- globalWeatherVar.value = DEFAULT_WEATHER;
- });
- });
-};
-
-Utils.merge([key.bind('value'), interval.bind('value'), location.bind('value')], (weatherKey, weatherInterval, loc) => {
- if (!weatherKey) {
- return (globalWeatherVar.value = DEFAULT_WEATHER);
- }
- weatherIntervalFn(weatherInterval, loc, weatherKey);
-});
-
-export const getTemperature = (wthr: Weather, unt: UnitType): string => {
- if (unt === 'imperial') {
- return `${Math.ceil(wthr.current.temp_f)}° F`;
- } else {
- return `${Math.ceil(wthr.current.temp_c)}° C`;
- }
-};
-
-export const getWeatherIcon = (fahren: number): Record => {
- const icons = {
- 100: '',
- 75: '',
- 50: '',
- 25: '',
- 0: '',
- } as const;
- const colors = {
- 100: 'weather-color red',
- 75: 'weather-color orange',
- 50: 'weather-color lavender',
- 25: 'weather-color blue',
- 0: 'weather-color sky',
- } as const;
-
- type IconKeys = keyof typeof icons;
-
- const threshold: IconKeys =
- fahren < 0 ? 0 : ([100, 75, 50, 25, 0] as IconKeys[]).find((threshold) => threshold <= fahren) || 0;
-
- const icon = icons[threshold || 50];
- const color = colors[threshold || 50];
-
- return {
- icon,
- color,
- };
-};
-
-export const getWindConditions = (wthr: Weather, unt: UnitType): string => {
- if (unt === 'imperial') {
- return `${Math.floor(wthr.current.wind_mph)} mph`;
- }
- return `${Math.floor(wthr.current.wind_kph)} kph`;
-};
-
-export const getRainChance = (wthr: Weather): string => `${wthr.forecast.forecastday[0].day.daily_chance_of_rain}%`;
-
-export const isValidWeatherIconTitle = (title: string): title is WeatherIconTitle => {
- return title in weatherIcons;
-};
-
-export const getWeatherStatusTextIcon = (wthr: Weather): WeatherIcon => {
- let iconQuery = wthr.current.condition.text.trim().toLowerCase().replaceAll(' ', '_');
-
- if (!wthr.current.is_day && iconQuery === 'partly_cloudy') {
- iconQuery = 'partly_cloudy_night';
- }
-
- if (isValidWeatherIconTitle(iconQuery)) {
- return weatherIcons[iconQuery];
- } else {
- console.warn(`Unknown weather icon title: ${iconQuery}`);
- return weatherIcons['warning'];
- }
-};
-
-globalThis['globalWeatherVar'] = globalWeatherVar;
diff --git a/ags/HyprPanel/globals/window.ts b/ags/HyprPanel/globals/window.ts
deleted file mode 100644
index ae823bb..0000000
--- a/ags/HyprPanel/globals/window.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export const WINDOW_LAYOUTS: string[] = [
- 'center',
- 'top',
- 'top-right',
- 'top-center',
- 'top-left',
- 'bottom-left',
- 'bottom-center',
- 'bottom-right',
-];
diff --git a/ags/HyprPanel/install_fonts.sh b/ags/HyprPanel/install_fonts.sh
deleted file mode 100755
index c40b022..0000000
--- a/ags/HyprPanel/install_fonts.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-SOURCE_DIR="./assets/fonts"
-DEST_DIR="$HOME/.local/share/fonts"
-DEST_PATH="$DEST_DIR/NFP"
-
-if [ ! -d "$SOURCE_DIR" ]; then
- echo "Source directory '$SOURCE_DIR' does not exist."
- exit 1
-fi
-
-if [ ! -d "$DEST_PATH" ]; then
- echo "Destination directory '$DEST_PATH' does not exist. Creating it..."
- mkdir -p "$DEST_PATH"
-fi
-
-if [ -z "$(ls -A "$SOURCE_DIR")" ]; then
- echo "Source directory '$SOURCE_DIR' is empty. No files to copy."
- exit 1
-fi
-
-echo "Copying fonts from '$SOURCE_DIR' to '$DEST_PATH'..."
-cp -r "$SOURCE_DIR"/* "$DEST_PATH"
-
-echo "Updating font cache..."
-fc-cache -fv
-
-echo "Fonts installed successfully."
diff --git a/ags/HyprPanel/lib/constants/colors.ts b/ags/HyprPanel/lib/constants/colors.ts
deleted file mode 100644
index 95ac5cf..0000000
--- a/ags/HyprPanel/lib/constants/colors.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-export const namedColors = new Set([
- 'alice blue',
- 'antique white',
- 'aqua',
- 'aquamarine',
- 'azure',
- 'beige',
- 'bisque',
- 'black',
- 'blanched almond',
- 'blue',
- 'blue violet',
- 'brown',
- 'burlywood',
- 'cadet blue',
- 'chartreuse',
- 'chocolate',
- 'coral',
- 'cornflower blue',
- 'cornsilk',
- 'crimson',
- 'cyan',
- 'dark blue',
- 'dark cyan',
- 'dark goldenrod',
- 'dark gray',
- 'dark green',
- 'dark khaki',
- 'dark magenta',
- 'dark olive green',
- 'dark orange',
- 'dark orchid',
- 'dark red',
- 'dark salmon',
- 'dark sea green',
- 'dark slate blue',
- 'dark slate gray',
- 'dark turquoise',
- 'dark violet',
- 'deep pink',
- 'deep sky blue',
- 'dim gray',
- 'dodger blue',
- 'firebrick',
- 'floral white',
- 'forest green',
- 'fuchsia',
- 'gainsboro',
- 'ghost white',
- 'gold',
- 'goldenrod',
- 'gray',
- 'green',
- 'green yellow',
- 'honeydew',
- 'hot pink',
- 'indian red',
- 'indigo',
- 'ivory',
- 'khaki',
- 'lavender',
- 'lavender blush',
- 'lawn green',
- 'lemon chiffon',
- 'light blue',
- 'light coral',
- 'light cyan',
- 'light goldenrod yellow',
- 'light green',
- 'light grey',
- 'light pink',
- 'light salmon',
- 'light sea green',
- 'light sky blue',
- 'light slate gray',
- 'light steel blue',
- 'light yellow',
- 'lime',
- 'lime green',
- 'linen',
- 'magenta',
- 'maroon',
- 'medium aquamarine',
- 'medium blue',
- 'medium orchid',
- 'medium purple',
- 'medium sea green',
- 'medium slate blue',
- 'medium spring green',
- 'medium turquoise',
- 'medium violet red',
- 'midnight blue',
- 'mint cream',
- 'misty rose',
- 'moccasin',
- 'navajo white',
- 'navy',
- 'old lace',
- 'olive',
- 'olive drab',
- 'orange',
- 'orange red',
- 'orchid',
- 'pale goldenrod',
- 'pale green',
- 'pale turquoise',
- 'pale violet red',
- 'papaya whip',
- 'peach puff',
- 'peru',
- 'pink',
- 'plum',
- 'powder blue',
- 'purple',
- 'red',
- 'rosy brown',
- 'royal blue',
- 'saddle brown',
- 'salmon',
- 'sandy brown',
- 'sea green',
- 'seashell',
- 'sienna',
- 'silver',
- 'sky blue',
- 'slate blue',
- 'slate gray',
- 'snow',
- 'spring green',
- 'steel blue',
- 'tan',
- 'teal',
- 'thistle',
- 'tomato',
- 'turquoise',
- 'violet',
- 'wheat',
- 'white',
- 'white smoke',
- 'yellow',
- 'yellow green',
-]);
diff --git a/ags/HyprPanel/lib/icons.ts b/ags/HyprPanel/lib/icons.ts
deleted file mode 100644
index 8813940..0000000
--- a/ags/HyprPanel/lib/icons.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-export const substitutes = {
- 'transmission-gtk': 'transmission',
- 'blueberry.py': 'blueberry',
- Caprine: 'facebook-messenger',
- 'com.raggesilver.BlackBox-symbolic': 'terminal-symbolic',
- 'org.wezfurlong.wezterm-symbolic': 'terminal-symbolic',
- 'audio-headset-bluetooth': 'audio-headphones-symbolic',
- 'audio-card-analog-usb': 'audio-speakers-symbolic',
- 'audio-card-analog-pci': 'audio-card-symbolic',
- 'preferences-system': 'emblem-system-symbolic',
- 'com.github.Aylur.ags-symbolic': 'controls-symbolic',
- 'com.github.Aylur.ags': 'controls-symbolic',
-} as const;
-
-export default {
- missing: 'image-missing-symbolic',
- nix: {
- nix: 'nix-snowflake-symbolic',
- },
- app: {
- terminal: 'terminal-symbolic',
- },
- fallback: {
- executable: 'application-x-executable',
- notification: 'dialog-information-symbolic',
- video: 'video-x-generic-symbolic',
- audio: 'audio-x-generic-symbolic',
- },
- ui: {
- close: 'window-close-symbolic',
- colorpicker: 'color-select-symbolic',
- info: 'info-symbolic',
- link: 'external-link-symbolic',
- lock: 'system-lock-screen-symbolic',
- menu: 'open-menu-symbolic',
- refresh: 'view-refresh-symbolic',
- search: 'system-search-symbolic',
- settings: 'emblem-system-symbolic',
- themes: 'preferences-desktop-theme-symbolic',
- tick: 'object-select-symbolic',
- time: 'hourglass-symbolic',
- toolbars: 'toolbars-symbolic',
- warning: 'dialog-warning-symbolic',
- avatar: 'avatar-default-symbolic',
- arrow: {
- right: 'pan-end-symbolic',
- left: 'pan-start-symbolic',
- down: 'pan-down-symbolic',
- up: 'pan-up-symbolic',
- },
- },
- audio: {
- mic: {
- muted: 'microphone-disabled-symbolic',
- low: 'microphone-sensitivity-low-symbolic',
- medium: 'microphone-sensitivity-medium-symbolic',
- high: 'microphone-sensitivity-high-symbolic',
- },
- volume: {
- muted: 'audio-volume-muted-symbolic',
- low: 'audio-volume-low-symbolic',
- medium: 'audio-volume-medium-symbolic',
- high: 'audio-volume-high-symbolic',
- overamplified: 'audio-volume-overamplified-symbolic',
- },
- type: {
- headset: 'audio-headphones-symbolic',
- speaker: 'audio-speakers-symbolic',
- card: 'audio-card-symbolic',
- },
- mixer: 'mixer-symbolic',
- },
- powerprofile: {
- balanced: 'power-profile-balanced-symbolic',
- 'power-saver': 'power-profile-power-saver-symbolic',
- performance: 'power-profile-performance-symbolic',
- },
- asusctl: {
- profile: {
- Balanced: 'power-profile-balanced-symbolic',
- Quiet: 'power-profile-power-saver-symbolic',
- Performance: 'power-profile-performance-symbolic',
- },
- mode: {
- Integrated: 'processor-symbolic',
- Hybrid: 'controller-symbolic',
- },
- },
- battery: {
- charging: 'battery-flash-symbolic',
- warning: 'battery-empty-symbolic',
- },
- bluetooth: {
- enabled: 'bluetooth-active-symbolic',
- disabled: 'bluetooth-disabled-symbolic',
- },
- brightness: {
- indicator: 'display-brightness-symbolic',
- keyboard: 'keyboard-brightness-symbolic',
- screen: 'display-brightness-symbolic',
- },
- powermenu: {
- sleep: 'weather-clear-night-symbolic',
- reboot: 'system-reboot-symbolic',
- logout: 'system-log-out-symbolic',
- shutdown: 'system-shutdown-symbolic',
- },
- recorder: {
- recording: 'media-record-symbolic',
- },
- notifications: {
- noisy: 'org.gnome.Settings-notifications-symbolic',
- silent: 'notifications-disabled-symbolic',
- message: 'chat-bubbles-symbolic',
- },
- trash: {
- full: 'user-trash-full-symbolic',
- empty: 'user-trash-symbolic',
- },
- mpris: {
- shuffle: {
- enabled: 'media-playlist-shuffle-symbolic',
- disabled: 'media-playlist-consecutive-symbolic',
- },
- loop: {
- none: 'media-playlist-repeat-symbolic',
- track: 'media-playlist-repeat-song-symbolic',
- playlist: 'media-playlist-repeat-symbolic',
- },
- playing: 'media-playback-pause-symbolic',
- paused: 'media-playback-start-symbolic',
- stopped: 'media-playback-start-symbolic',
- prev: 'media-skip-backward-symbolic',
- next: 'media-skip-forward-symbolic',
- },
- system: {
- cpu: 'org.gnome.SystemMonitor-symbolic',
- ram: 'drive-harddisk-solidstate-symbolic',
- temp: 'temperature-symbolic',
- },
- color: {
- dark: 'dark-mode-symbolic',
- light: 'light-mode-symbolic',
- },
-};
diff --git a/ags/HyprPanel/lib/option.ts b/ags/HyprPanel/lib/option.ts
deleted file mode 100644
index c261657..0000000
--- a/ags/HyprPanel/lib/option.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-import { isHexColor } from 'globals/variables';
-import { Variable } from 'resource:///com/github/Aylur/ags/variable.js';
-import { MkOptionsResult } from './types/options';
-
-type OptProps = {
- persistent?: boolean;
-};
-
-export class Opt extends Variable {
- static {
- Service.register(this);
- }
-
- constructor(initial: T, { persistent = false }: OptProps = {}) {
- super(initial);
- this.initial = initial;
- this.persistent = persistent;
- }
-
- initial: T;
- id = '';
- persistent: boolean;
- toString(): string {
- return `${this.value}`;
- }
- toJSON(): string {
- return `opt:${this.value}`;
- }
-
- getValue = (): T => {
- return super.getValue();
- };
- init(cacheFile: string): void {
- const cacheV = JSON.parse(Utils.readFile(cacheFile) || '{}')[this.id];
- if (cacheV !== undefined) this.value = cacheV;
-
- this.connect('changed', () => {
- const cache = JSON.parse(Utils.readFile(cacheFile) || '{}');
- cache[this.id] = this.value;
- Utils.writeFileSync(JSON.stringify(cache, null, 2), cacheFile);
- });
- }
-
- reset(): string | undefined {
- if (this.persistent) return;
-
- if (JSON.stringify(this.value) !== JSON.stringify(this.initial)) {
- this.value = this.initial;
- return this.id;
- }
- }
-
- doResetColor(): string | undefined {
- if (this.persistent) return;
-
- const isColor = isHexColor(this.value as string);
- if (JSON.stringify(this.value) !== JSON.stringify(this.initial) && isColor) {
- this.value = this.initial;
- return this.id;
- }
- return;
- }
-}
-
-export const opt = (initial: T, opts?: OptProps): Opt => new Opt(initial, opts);
-
-const getOptions = (object: Record, path = ''): Opt[] => {
- return Object.keys(object).flatMap((key) => {
- const obj = object[key];
- const id = path ? path + '.' + key : key;
-
- if (obj instanceof Variable) {
- const optValue = obj as Opt;
- optValue.id = id;
- return optValue;
- }
-
- if (typeof obj === 'object' && obj !== null) {
- return getOptions(obj as Record, id); // Recursively process nested objects
- }
-
- return [];
- });
-};
-
-export function mkOptions(
- cacheFile: string,
- object: T,
- confFile: string = 'config.json',
-): T & MkOptionsResult {
- for (const opt of getOptions(object as Record)) opt.init(cacheFile);
-
- Utils.ensureDirectory(cacheFile.split('/').slice(0, -1).join('/'));
-
- const configFile = `${TMP}/${confFile}`;
- const values = getOptions(object as Record).reduce(
- (obj, { id, value }) => ({ [id]: value, ...obj }),
- {},
- );
- Utils.writeFileSync(JSON.stringify(values, null, 2), configFile);
- Utils.monitorFile(configFile, () => {
- const cache = JSON.parse(Utils.readFile(configFile) || '{}');
- for (const opt of getOptions(object as Record)) {
- if (JSON.stringify(cache[opt.id]) !== JSON.stringify(opt.value)) opt.value = cache[opt.id];
- }
- });
-
- function sleep(ms = 0): Promise {
- return new Promise((r) => setTimeout(r, ms));
- }
-
- const reset = async (
- [opt, ...list] = getOptions(object as Record),
- id = opt?.reset(),
- ): Promise> => {
- if (!opt) return sleep().then(() => []);
-
- return id ? [id, ...(await sleep(50).then(() => reset(list)))] : await sleep().then(() => reset(list));
- };
-
- const resetTheme = async (
- [opt, ...list] = getOptions(object as Record),
- id = opt?.doResetColor(),
- ): Promise> => {
- if (!opt) return sleep().then(() => []);
-
- return id
- ? [id, ...(await sleep(50).then(() => resetTheme(list)))]
- : await sleep().then(() => resetTheme(list));
- };
-
- return Object.assign(object, {
- configFile,
- array: () => getOptions(object as Record),
- async reset() {
- return (await reset()).join('\n');
- },
- async resetTheme() {
- return (await resetTheme()).join('\n');
- },
- handler(deps: string[], callback: () => void) {
- for (const opt of getOptions(object as Record)) {
- if (deps.some((i) => opt.id.startsWith(i))) opt.connect('changed', callback);
- }
- },
- });
-}
diff --git a/ags/HyprPanel/lib/session.ts b/ags/HyprPanel/lib/session.ts
deleted file mode 100644
index 595b366..0000000
--- a/ags/HyprPanel/lib/session.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import GLib from 'gi://GLib?version=2.0';
-
-declare global {
- const OPTIONS: string;
- const TMP: string;
- const USER: string;
-}
-
-Object.assign(globalThis, {
- OPTIONS: `${GLib.get_user_cache_dir()}/ags/hyprpanel/options.json`,
- TMP: `${GLib.get_tmp_dir()}/ags/hyprpanel`,
- USER: GLib.get_user_name(),
-});
-
-Utils.ensureDirectory(TMP);
-App.addIcons(`${App.configDir}/assets`);
diff --git a/ags/HyprPanel/lib/shared/media.ts b/ags/HyprPanel/lib/shared/media.ts
deleted file mode 100644
index 23e0c6f..0000000
--- a/ags/HyprPanel/lib/shared/media.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { MprisPlayer } from 'types/service/mpris';
-const mpris = await Service.import('mpris');
-
-export const getCurrentPlayer = (activePlayer: MprisPlayer = mpris.players[0]): MprisPlayer => {
- const statusOrder = {
- Playing: 1,
- Paused: 2,
- Stopped: 3,
- };
-
- if (mpris.players.length === 0) {
- return mpris.players[0];
- }
-
- const isPlaying = mpris.players.some((p: MprisPlayer) => p.play_back_status === 'Playing');
-
- const playerStillExists = mpris.players.some((p) => activePlayer.bus_name === p.bus_name);
-
- const nextPlayerUp = mpris.players.sort(
- (a: MprisPlayer, b: MprisPlayer) => statusOrder[a.play_back_status] - statusOrder[b.play_back_status],
- )[0];
-
- if (isPlaying || !playerStillExists) {
- return nextPlayerUp;
- }
-
- return activePlayer;
-};
diff --git a/ags/HyprPanel/lib/shared/notifications.ts b/ags/HyprPanel/lib/shared/notifications.ts
deleted file mode 100644
index f772c69..0000000
--- a/ags/HyprPanel/lib/shared/notifications.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Notification } from 'types/service/notifications';
-
-export const filterNotifications = (notifications: Notification[], filter: string[]): Notification[] => {
- const notifFilter = new Set(filter.map((name: string) => name.toLowerCase().replace(/\s+/g, '_')));
-
- const filteredNotifications = notifications.filter((notif: Notification) => {
- const normalizedAppName = notif.app_name.toLowerCase().replace(/\s+/g, '_');
- return !notifFilter.has(normalizedAppName);
- });
-
- return filteredNotifications;
-};
diff --git a/ags/HyprPanel/lib/types/audio.d.ts b/ags/HyprPanel/lib/types/audio.d.ts
deleted file mode 100644
index 9332431..0000000
--- a/ags/HyprPanel/lib/types/audio.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type InputDevices = Button, Attribute>, Attribute>, Attribute>[];
-
-type DummyDevices = Button, Attribute>, Attribute>, Attribute>[];
-type RealPlaybackDevices = Button, Attribute>, Attribute>, Attribute>[];
-export type PlaybackDevices = DummyDevices | RealPlaybackDevices;
diff --git a/ags/HyprPanel/lib/types/bar.d.ts b/ags/HyprPanel/lib/types/bar.d.ts
deleted file mode 100644
index 99066d8..0000000
--- a/ags/HyprPanel/lib/types/bar.d.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Binding, Connectable } from 'types/service';
-import { Variable } from 'types/variable';
-import Box from 'types/widgets/box';
-import Button, { ButtonProps } from 'types/widgets/button';
-import Label from 'types/widgets/label';
-import { Attribute, Child } from './widget';
-
-export type BarBoxChild = {
- component: Box;
- isVisible?: boolean;
- isVis?: Variable;
- boxClass: string;
- tooltip_text?: string | Binding;
- props: ButtonProps;
-};
-
-export type SelfButton = Button;
-
-export type BoxHook = (self: Box) => void;
-export type LabelHook = (self: Label) => void;
-
-export type Module = {
- icon?: string | Binding;
- textIcon?: string | Binding;
- label?: string | Binding;
- labelHook?: LabelHook;
- boundLabel?: string;
- tooltipText?: string | Binding;
- boxClass: string;
- props?: ButtonProps;
- showLabel?: boolean;
- showLabelBinding?: Binding;
- hook?: BoxHook;
- connection?: Binding;
-};
-
-export type ResourceLabelType = 'used/total' | 'used' | 'percentage' | 'free';
-
-export type NetstatLabelType = 'full' | 'in' | 'out';
-export type RateUnit = 'GiB' | 'MiB' | 'KiB' | 'auto';
-
-
diff --git a/ags/HyprPanel/lib/types/customModules/generic.d.ts b/ags/HyprPanel/lib/types/customModules/generic.d.ts
deleted file mode 100644
index 839e04a..0000000
--- a/ags/HyprPanel/lib/types/customModules/generic.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export type GenericFunction = (...args: P) => T;
-
-export type GenericResourceMetrics = {
- total: number;
- used: number;
- percentage: number;
-};
-
-type GenericResourceData = ResourceUsage & {
- free: number;
-};
-
-export type Postfix = 'TiB' | 'GiB' | 'MiB' | 'KiB' | 'B';
diff --git a/ags/HyprPanel/lib/types/customModules/kbLayout.d.ts b/ags/HyprPanel/lib/types/customModules/kbLayout.d.ts
deleted file mode 100644
index b287e06..0000000
--- a/ags/HyprPanel/lib/types/customModules/kbLayout.d.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { layoutMap } from 'customModules/kblayout/layouts';
-
-export type KbLabelType = 'layout' | 'code';
-
-export type HyprctlKeyboard = {
- address: string;
- name: string;
- rules: string;
- model: string;
- layout: string;
- variant: string;
- options: string;
- active_keymap: string;
- main: boolean;
-};
-
-export type HyprctlMouse = {
- address: string;
- name: string;
- defaultSpeed: number;
-};
-
-export type HyprctlDeviceLayout = {
- mice: HyprctlMouse[];
- keyboards: HyprctlKeyboard[];
- tablets: unknown[];
- touch: unknown[];
- switches: unknown[];
-};
-
-export type LayoutKeys = keyof typeof layoutMap;
-export type LayoutValues = (typeof layoutMap)[LayoutKeys];
diff --git a/ags/HyprPanel/lib/types/customModules/network.d.ts b/ags/HyprPanel/lib/types/customModules/network.d.ts
deleted file mode 100644
index dbef13f..0000000
--- a/ags/HyprPanel/lib/types/customModules/network.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export type NetworkResourceData = {
- in: string;
- out: string;
-};
diff --git a/ags/HyprPanel/lib/types/customModules/utils.d.ts b/ags/HyprPanel/lib/types/customModules/utils.d.ts
deleted file mode 100644
index 14ccf90..0000000
--- a/ags/HyprPanel/lib/types/customModules/utils.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Binding } from 'lib/utils';
-
-export type InputHandlerEvents = {
- onPrimaryClick?: Binding;
- onSecondaryClick?: Binding;
- onMiddleClick?: Binding;
- onScrollUp?: Binding;
- onScrollDown?: Binding;
-};
-
-export type RunAsyncCommand = (cmd: string, args: EventArgs, fn?: (output: string) => void) => void;
diff --git a/ags/HyprPanel/lib/types/defaults/bar.ts b/ags/HyprPanel/lib/types/defaults/bar.ts
deleted file mode 100644
index 78966c4..0000000
--- a/ags/HyprPanel/lib/types/defaults/bar.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { NetstatLabelType, ResourceLabelType } from '../bar';
-
-export const LABEL_TYPES: ResourceLabelType[] = ['used/total', 'used', 'free', 'percentage'];
-
-export const NETWORK_LABEL_TYPES: NetstatLabelType[] = ['full', 'in', 'out'];
diff --git a/ags/HyprPanel/lib/types/defaults/netstat.ts b/ags/HyprPanel/lib/types/defaults/netstat.ts
deleted file mode 100644
index 083344b..0000000
--- a/ags/HyprPanel/lib/types/defaults/netstat.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { RateUnit } from '../bar';
-import { NetworkResourceData } from '../customModules/network';
-
-export const GET_DEFAULT_NETSTAT_DATA = (dataType: RateUnit): NetworkResourceData => {
- if (dataType === 'auto') {
- return { in: `0 Kib/s`, out: `0 Kib/s` };
- }
-
- return { in: `0 ${dataType}/s`, out: `0 ${dataType}/s` };
-};
diff --git a/ags/HyprPanel/lib/types/defaults/options.ts b/ags/HyprPanel/lib/types/defaults/options.ts
deleted file mode 100644
index 11b7347..0000000
--- a/ags/HyprPanel/lib/types/defaults/options.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-export const defaultColorMap = {
- rosewater: '#f5e0dc',
- flamingo: '#f2cdcd',
- pink: '#f5c2e7',
- mauve: '#cba6f7',
- red: '#f38ba8',
- maroon: '#eba0ac',
- peach: '#fab387',
- yellow: '#f9e2af',
- green: '#a6e3a1',
- teal: '#94e2d5',
- sky: '#89dceb',
- sapphire: '#74c7ec',
- blue: '#89b4fa',
- lavender: '#b4befe',
- text: '#cdd6f4',
- subtext1: '#bac2de',
- subtext2: '#a6adc8',
- overlay2: '#9399b2',
- overlay1: '#7f849c',
- overlay0: '#6c7086',
- surface2: '#585b70',
- surface1: '#45475a',
- surface0: '#313244',
- base2: '#242438',
- base: '#1e1e2e',
- mantle: '#181825',
- crust: '#11111b',
- surface1_2: '#454759',
- text2: '#cdd6f3',
- pink2: '#f5c2e6',
- red2: '#f38ba7',
- peach2: '#fab386',
- mantle2: '#181824',
- surface0_2: '#313243',
- surface2_2: '#585b69',
- overlay1_2: '#7f849b',
- lavender2: '#b4befd',
- mauve2: '#cba6f6',
- green2: '#a6e3a0',
- sky2: '#89dcea',
- teal2: '#94e2d4',
- yellow2: '#f9e2ad',
- maroon2: '#eba0ab',
- crust2: '#11111a',
- pink3: '#f5c2e8',
- red3: '#f38ba9',
- mantle3: '#181826',
- surface0_3: '#313245',
- surface2_3: '#585b71',
- overlay1_3: '#7f849d',
- lavender3: '#b4beff',
- mauve3: '#cba6f8',
- green3: '#a6e3a2',
- sky3: '#89dcec',
- teal3: '#94e2d6',
- yellow3: '#f9e2ae',
- maroon3: '#eba0ad',
- crust3: '#11111c',
-} as const;
diff --git a/ags/HyprPanel/lib/types/defaults/weather.ts b/ags/HyprPanel/lib/types/defaults/weather.ts
deleted file mode 100644
index cde95e3..0000000
--- a/ags/HyprPanel/lib/types/defaults/weather.ts
+++ /dev/null
@@ -1,1053 +0,0 @@
-export const DEFAULT_WEATHER = {
- location: {
- name: 'Tahiti',
- region: 'Somewhere',
- country: 'United States of America',
- lat: 0,
- lon: 0,
- tz_id: 'Tahiti',
- localtime_epoch: 1721981457,
- localtime: '2024-07-26 1:10',
- },
- current: {
- last_updated_epoch: 1721980800,
- last_updated: '2024-07-26 01:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'NW',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0.0,
- precip_in: 0.0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- vis_km: 0,
- vis_miles: 0,
- uv: 0,
- gust_mph: 0,
- gust_kph: 0,
- },
- forecast: {
- forecastday: [
- {
- date: '2024-07-26',
- date_epoch: 1721952000,
- day: {
- maxtemp_c: 0,
- maxtemp_f: 0,
- mintemp_c: 0,
- mintemp_f: 0,
- avgtemp_c: 0,
- avgtemp_f: 0,
- maxwind_mph: 0,
- maxwind_kph: 0,
- totalprecip_mm: 0,
- totalprecip_in: 0,
- totalsnow_cm: 0,
- avgvis_km: 0,
- avgvis_miles: 0,
- avghumidity: 0,
- daily_will_it_rain: 0,
- daily_chance_of_rain: 0,
- daily_will_it_snow: 0,
- daily_chance_of_snow: 0,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- uv: 0,
- },
- astro: {
- sunrise: '06:01 AM',
- sunset: '08:10 PM',
- moonrise: '11:32 PM',
- moonset: '12:01 PM',
- moon_phase: 'Waning Gibbous',
- moon_illumination: 0,
- is_moon_up: 0,
- is_sun_up: 0,
- },
- hour: [
- {
- time_epoch: 1721977200,
- time: '2024-07-26 00:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1721980800,
- time: '2024-07-26 01:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1721984400,
- time: '2024-07-26 02:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1721988000,
- time: '2024-07-26 03:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1721991600,
- time: '2024-07-26 04:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1721995200,
- time: '2024-07-26 05:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1721998800,
- time: '2024-07-26 06:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1722002400,
- time: '2024-07-26 07:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 7.0,
- },
- {
- time_epoch: 1722006000,
- time: '2024-07-26 08:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 7.0,
- },
- {
- time_epoch: 1722009600,
- time: '2024-07-26 09:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 8.0,
- },
- {
- time_epoch: 1722013200,
- time: '2024-07-26 10:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 8.0,
- },
- {
- time_epoch: 1722016800,
- time: '2024-07-26 11:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 9.0,
- },
- {
- time_epoch: 1722020400,
- time: '2024-07-26 12:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 9.0,
- },
- {
- time_epoch: 1722024000,
- time: '2024-07-26 13:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 9.0,
- },
- {
- time_epoch: 1722027600,
- time: '2024-07-26 14:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 10.0,
- },
- {
- time_epoch: 1722031200,
- time: '2024-07-26 15:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 10.0,
- },
- {
- time_epoch: 1722034800,
- time: '2024-07-26 16:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 10.0,
- },
- {
- time_epoch: 1722038400,
- time: '2024-07-26 17:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 10.0,
- },
- {
- time_epoch: 1722042000,
- time: '2024-07-26 18:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 9.0,
- },
- {
- time_epoch: 1722045600,
- time: '2024-07-26 19:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 9.0,
- },
- {
- time_epoch: 1722049200,
- time: '2024-07-26 20:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 1,
- condition: {
- text: 'Sunny',
- icon: '//cdn.weatherapi.com/weather/64x64/day/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 8.0,
- },
- {
- time_epoch: 1722052800,
- time: '2024-07-26 21:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1722056400,
- time: '2024-07-26 22:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- {
- time_epoch: 1722060000,
- time: '2024-07-26 23:00',
- temp_c: 0,
- temp_f: 0,
- is_day: 0,
- condition: {
- text: 'Clear ',
- icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
- code: 1000,
- },
- wind_mph: 0,
- wind_kph: 0,
- wind_degree: 0,
- wind_dir: 'N',
- pressure_mb: 0,
- pressure_in: 0,
- precip_mm: 0,
- precip_in: 0,
- snow_cm: 0,
- humidity: 0,
- cloud: 0,
- feelslike_c: 0,
- feelslike_f: 0,
- windchill_c: 0,
- windchill_f: 0,
- heatindex_c: 0,
- heatindex_f: 0,
- dewpoint_c: 0,
- dewpoint_f: 0,
- will_it_rain: 0,
- chance_of_rain: 0,
- will_it_snow: 0,
- chance_of_snow: 0,
- vis_km: 0,
- vis_miles: 0,
- gust_mph: 0,
- gust_kph: 0,
- uv: 0,
- },
- ],
- },
- ],
- },
-};
diff --git a/ags/HyprPanel/lib/types/dropdownmenu.d.ts b/ags/HyprPanel/lib/types/dropdownmenu.d.ts
deleted file mode 100644
index 8d76e5c..0000000
--- a/ags/HyprPanel/lib/types/dropdownmenu.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { WindowProps } from 'types/widgets/window';
-import { GtkWidget, Transition } from './widget';
-import { Binding } from 'types/service';
-
-export type DropdownMenuProps = {
- name: string;
- child: GtkWidget;
- layout?: string;
- transition?: Transition | Binding;
- exclusivity?: Exclusivity;
- fixed?: boolean;
-} & WindowProps;
diff --git a/ags/HyprPanel/lib/types/filechooser.d.ts b/ags/HyprPanel/lib/types/filechooser.d.ts
deleted file mode 100644
index 8bb9d8f..0000000
--- a/ags/HyprPanel/lib/types/filechooser.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export type Config = {
- [key: string]: string | number | boolean | object;
-};
diff --git a/ags/HyprPanel/lib/types/globals.d.ts b/ags/HyprPanel/lib/types/globals.d.ts
deleted file mode 100644
index ecdb39f..0000000
--- a/ags/HyprPanel/lib/types/globals.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export type MousePos = {
- source: string;
- pos: number[];
-};
diff --git a/ags/HyprPanel/lib/types/gpustat.d.ts b/ags/HyprPanel/lib/types/gpustat.d.ts
deleted file mode 100644
index 49dc75d..0000000
--- a/ags/HyprPanel/lib/types/gpustat.d.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export type GPU_Stat_Process = {
- username: string;
- command: string;
- full_command: string[];
- gpu_memory_usage: number;
- cpu_percent: number;
- cpu_memory_usage: number;
- pid: number;
-};
-
-export type GPU_Stat = {
- index: number;
- uuid: string;
- name: string;
- 'temperature.gpu': number;
- 'fan.speed': number;
- 'utilization.gpu': number;
- 'utilization.enc': number;
- 'utilization.dec': number;
- 'power.draw': number;
- 'enforced.power.limit': number;
- 'memory.used': number;
- 'memory.total': number;
- processes: Process[];
-};
diff --git a/ags/HyprPanel/lib/types/mpris.d.ts b/ags/HyprPanel/lib/types/mpris.d.ts
deleted file mode 100644
index 5450e80..0000000
--- a/ags/HyprPanel/lib/types/mpris.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export type LoopStatus = 'none' | 'track' | 'playlist';
-export type PlaybackStatus = 'playing' | 'paused' | 'stopped';
diff --git a/ags/HyprPanel/lib/types/network.d.ts b/ags/HyprPanel/lib/types/network.d.ts
deleted file mode 100644
index 58dcdec..0000000
--- a/ags/HyprPanel/lib/types/network.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { WIFI_STATUS_MAP } from 'globals/network';
-
-export type AccessPoint = {
- bssid: string | null;
- address: string | null;
- lastSeen: number;
- ssid: string | null;
- active: boolean;
- strength: number;
- frequency: number;
- iconName: string | undefined;
-};
-
-export type WifiStatus = keyof typeof WIFI_STATUS_MAP;
-
-export type WifiIcon = '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | '';
diff --git a/ags/HyprPanel/lib/types/notification.d.ts b/ags/HyprPanel/lib/types/notification.d.ts
deleted file mode 100644
index 027f195..0000000
--- a/ags/HyprPanel/lib/types/notification.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import icons from 'modules/icons/index';
-
-export interface NotificationArgs {
- appName?: string;
- body?: string;
- iconName?: string;
- id?: number;
- summary?: string;
- urgency?: Urgency;
- category?: string;
- timeout?: number;
- transient?: boolean;
-}
-
-export type NotificationIcon = keyof typeof icons.notifications;
diff --git a/ags/HyprPanel/lib/types/options.d.ts b/ags/HyprPanel/lib/types/options.d.ts
deleted file mode 100644
index 51e7f76..0000000
--- a/ags/HyprPanel/lib/types/options.d.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-import { Opt } from 'lib/option';
-import { Variable } from 'types/variable';
-import { defaultColorMap } from './defaults/options';
-
-export type MkOptionsResult = {
- configFile: string;
- array: () => Opt[];
- reset: () => Promise;
- resetTheme: () => Promise;
- handler: (deps: string[], callback: () => void) => void;
-};
-
-export type RecursiveOptionsObject = {
- [key: string]: RecursiveOptionsObject | Opt | Opt | Opt;
-};
-
-export type BarLocation = 'top' | 'bottom';
-
-export type Unit = 'imperial' | 'metric';
-export type PowerOptions = 'sleep' | 'reboot' | 'logout' | 'shutdown';
-export type NotificationAnchor =
- | 'top'
- | 'top right'
- | 'top left'
- | 'bottom'
- | 'bottom right'
- | 'bottom left'
- | 'left'
- | 'right';
-export type OSDAnchor = 'top left' | 'top' | 'top right' | 'right' | 'bottom right' | 'bottom' | 'bottom left' | 'left';
-export type BarButtonStyles = 'default' | 'split' | 'wave' | 'wave2';
-
-export type ThemeExportData = {
- filePath: string;
- themeOnly: boolean;
-};
-export type RowProps = {
- opt: Opt;
- title: string;
- note?: string;
- type?:
- | 'number'
- | 'color'
- | 'float'
- | 'object'
- | 'string'
- | 'enum'
- | 'boolean'
- | 'img'
- | 'wallpaper'
- | 'export'
- | 'import'
- | 'config_import'
- | 'font';
- enums?: T[];
- max?: number;
- min?: number;
- disabledBinding?: Variable;
- exportData?: ThemeExportData;
- subtitle?: string | VarType | Opt;
- subtitleLink?: string;
- dependencies?: string[];
- increment?: number;
-};
-
-export type OSDOrientation = 'horizontal' | 'vertical';
-
-export type HexColor = `#${string}`;
-
-export type WindowLayer = 'top' | 'bottom' | 'overlay' | 'background';
-
-export type ActiveWsIndicator = 'underline' | 'highlight' | 'color';
-
-export type MatugenColors = {
- background: HexColor;
- error: HexColor;
- error_container: HexColor;
- inverse_on_surface: HexColor;
- inverse_primary: HexColor;
- inverse_surface: HexColor;
- on_background: HexColor;
- on_error: HexColor;
- on_error_container: HexColor;
- on_primary: HexColor;
- on_primary_container: HexColor;
- on_primary_fixed: HexColor;
- on_primary_fixed_variant: HexColor;
- on_secondary: HexColor;
- on_secondary_container: HexColor;
- on_secondary_fixed: HexColor;
- on_secondary_fixed_variant: HexColor;
- on_surface: HexColor;
- on_surface_variant: HexColor;
- on_tertiary: HexColor;
- on_tertiary_container: HexColor;
- on_tertiary_fixed: HexColor;
- on_tertiary_fixed_variant: HexColor;
- outline: HexColor;
- outline_variant: HexColor;
- primary: HexColor;
- primary_container: HexColor;
- primary_fixed: HexColor;
- primary_fixed_dim: HexColor;
- scrim: HexColor;
- secondary: HexColor;
- secondary_container: HexColor;
- secondary_fixed: HexColor;
- secondary_fixed_dim: HexColor;
- shadow: HexColor;
- surface: HexColor;
- surface_bright: HexColor;
- surface_container: HexColor;
- surface_container_high: HexColor;
- surface_container_highest: HexColor;
- surface_container_low: HexColor;
- surface_container_lowest: HexColor;
- surface_dim: HexColor;
- surface_variant: HexColor;
- tertiary: HexColor;
- tertiary_container: HexColor;
- tertiary_fixed: HexColor;
- tertiary_fixed_dim: HexColor;
-};
-
-export type MatugenVariation = {
- rosewater: HexColor;
- flamingo: HexColor;
- pink: HexColor;
- mauve: HexColor;
- red: HexColor;
- maroon: HexColor;
- peach: HexColor;
- yellow: HexColor;
- green: HexColor;
- teal: HexColor;
- sky: HexColor;
- sapphire: HexColor;
- blue: HexColor;
- lavender: HexColor;
- text: HexColor;
- subtext1: HexColor;
- subtext2: HexColor;
- overlay2: HexColor;
- overlay1: HexColor;
- overlay0: HexColor;
- surface2: HexColor;
- surface1: HexColor;
- surface0: HexColor;
- base2: HexColor;
- base: HexColor;
- mantle: HexColor;
- crust: HexColor;
- notifications_closer: HexColor;
- notifications_background: HexColor;
- dashboard_btn_text: HexColor;
- red2: HexColor;
- peach2: HexColor;
- pink2: HexColor;
- mantle2: HexColor;
- surface1_2: HexColor;
- surface0_2: HexColor;
- overlay1_2: HexColor;
- text2: HexColor;
- lavender2: HexColor;
- crust2: HexColor;
- maroon2: HexColor;
- mauve2: HexColor;
- green2: HexColor;
- surface2_2: HexColor;
- sky2: HexColor;
- teal2: HexColor;
- yellow2: HexColor;
- pink3: HexColor;
- red3: HexColor;
- mantle3: HexColor;
- surface0_3: HexColor;
- surface2_3: HexColor;
- overlay1_3: HexColor;
- lavender3: HexColor;
- mauve3: HexColor;
- green3: HexColor;
- sky3: HexColor;
- teal3: HexColor;
- yellow3: HexColor;
- maroon3: HexColor;
- crust3: HexColor;
- notifications_closer?: HexColor;
- notifications_background?: HexColor;
- dashboard_btn_text?: HexColor;
-};
-export type MatugenScheme =
- | 'content'
- | 'expressive'
- | 'fidelity'
- | 'fruit-salad'
- | 'monochrome'
- | 'neutral'
- | 'rainbow'
- | 'tonal-spot';
-
-export type MatugenVariations =
- | 'standard_1'
- | 'standard_2'
- | 'standard_3'
- | 'monochrome_1'
- | 'monochrome_2'
- | 'monochrome_3'
- | 'vivid_1'
- | 'vivid_2'
- | 'vivid_3';
-
-type MatugenTheme = 'light' | 'dark';
-
-export type ColorMapKey = keyof typeof defaultColorMap;
-export type ColorMapValue = (typeof defaultColorMap)[ColorMapKey];
-
-export type ScalingPriority = 'gdk' | 'hyprland' | 'both';
diff --git a/ags/HyprPanel/lib/types/popupwindow.d.ts b/ags/HyprPanel/lib/types/popupwindow.d.ts
deleted file mode 100644
index 300baab..0000000
--- a/ags/HyprPanel/lib/types/popupwindow.d.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Widget } from 'types/widgets/widget';
-import { WindowProps } from 'types/widgets/window';
-import { Transition } from './widget';
-
-export type PopupWindowProps = {
- name: string;
- child: Widget;
- layout?: Layouts;
- transition?: Transition | Binding;
- exclusivity?: Exclusivity;
-} & WindowProps;
-
-export type LayoutFunction = (
- name: string,
- child: Widget,
- transition: Transition,
-) => {
- center: () => Widget;
- top: () => Widget;
- 'top-right': () => Widget;
- 'top-center': () => Widget;
- 'top-left': () => Widget;
- 'bottom-left': () => Widget;
- 'bottom-center': () => Widget;
- 'bottom-right': () => Widget;
-};
-export type Layouts =
- | 'center'
- | 'top'
- | 'top-right'
- | 'top-center'
- | 'top-left'
- | 'bottom-left'
- | 'bottom-center'
- | 'bottom-right';
diff --git a/ags/HyprPanel/lib/types/power.d.ts b/ags/HyprPanel/lib/types/power.d.ts
deleted file mode 100644
index ef3c536..0000000
--- a/ags/HyprPanel/lib/types/power.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type Action = 'sleep' | 'reboot' | 'logout' | 'shutdown';
diff --git a/ags/HyprPanel/lib/types/powerprofiles.d.ts b/ags/HyprPanel/lib/types/powerprofiles.d.ts
deleted file mode 100644
index 980ac3b..0000000
--- a/ags/HyprPanel/lib/types/powerprofiles.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import PowerProfiles from 'types/service/powerprofiles.js';
-
-export type PowerProfiles = InstanceType;
-export type PowerProfile = 'power-saver' | 'balanced' | 'performance';
-export type PowerProfileObject = {
- [key: string]: string;
-};
diff --git a/ags/HyprPanel/lib/types/systray.d.ts b/ags/HyprPanel/lib/types/systray.d.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/ags/HyprPanel/lib/types/utils.d.ts b/ags/HyprPanel/lib/types/utils.d.ts
deleted file mode 100644
index b35af46..0000000
--- a/ags/HyprPanel/lib/types/utils.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { substitutes } from 'lib/icons';
-import { EventArgs } from './widget';
-
-type SubstituteKeys = keyof typeof substitutes;
-
-export type ThrottleFn = (cmd: string, args: EventArgs, fn?: (output: string) => void) => void;
-export type ThrottleFnCallback = ((output: string) => void) | undefined;
diff --git a/ags/HyprPanel/lib/types/variable.d.ts b/ags/HyprPanel/lib/types/variable.d.ts
deleted file mode 100644
index af540dd..0000000
--- a/ags/HyprPanel/lib/types/variable.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type Bind = OriginalBinding, unknown>;
diff --git a/ags/HyprPanel/lib/types/volume.d.ts b/ags/HyprPanel/lib/types/volume.d.ts
deleted file mode 100644
index 5e2cf32..0000000
--- a/ags/HyprPanel/lib/types/volume.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export type VolumeIcons = {
- [index: number]: string;
-};
diff --git a/ags/HyprPanel/lib/types/weather.d.ts b/ags/HyprPanel/lib/types/weather.d.ts
deleted file mode 100644
index daf0e1a..0000000
--- a/ags/HyprPanel/lib/types/weather.d.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { weatherIcons } from 'modules/icons/weather';
-
-export type UnitType = 'imperial' | 'metric';
-
-export type Weather = {
- location: Location;
- current: Current;
- forecast: Forecast;
-};
-
-export type Current = {
- last_updated_epoch?: number;
- last_updated?: string;
- temp_c: number;
- temp_f: number;
- is_day: number;
- condition: Condition;
- wind_mph: number;
- wind_kph: number;
- wind_degree: number;
- wind_dir: string;
- pressure_mb: number;
- pressure_in: number;
- precip_mm: number;
- precip_in: number;
- humidity: number;
- cloud: number;
- feelslike_c: number;
- feelslike_f: number;
- windchill_c: number;
- windchill_f: number;
- heatindex_c: number;
- heatindex_f: number;
- dewpoint_c: number;
- dewpoint_f: number;
- vis_km: number;
- vis_miles: number;
- uv: number;
- gust_mph: number;
- gust_kph: number;
- time_epoch?: number;
- time?: string;
- snow_cm?: number;
- will_it_rain?: number;
- chance_of_rain?: number;
- will_it_snow?: number;
- chance_of_snow?: number;
-};
-
-export type Condition = {
- text: string;
- icon: string;
- code: number;
-};
-
-export type Forecast = {
- forecastday: Forecastday[];
-};
-
-export type Forecastday = {
- date: string;
- date_epoch: number;
- day: Day;
- astro: Astro;
- hour: Current[];
-};
-
-export type Astro = {
- sunrise: string;
- sunset: string;
- moonrise: string;
- moonset: string;
- moon_phase: string;
- moon_illumination: number;
- is_moon_up: number;
- is_sun_up: number;
-};
-
-export type Day = {
- maxtemp_c: number;
- maxtemp_f: number;
- mintemp_c: number;
- mintemp_f: number;
- avgtemp_c: number;
- avgtemp_f: number;
- maxwind_mph: number;
- maxwind_kph: number;
- totalprecip_mm: number;
- totalprecip_in: number;
- totalsnow_cm: number;
- avgvis_km: number;
- avgvis_miles: number;
- avghumidity: number;
- daily_will_it_rain: number;
- daily_chance_of_rain: number;
- daily_will_it_snow: number;
- daily_chance_of_snow: number;
- condition: Condition;
- uv: number;
-};
-
-export type Location = {
- name: string;
- region: string;
- country: string;
- lat: number;
- lon: number;
- tz_id: string;
- localtime_epoch: number;
- localtime: string;
-};
-
-export type TemperatureIconColorMap = {
- [key: number]: string;
-};
-
-export type WeatherIconTitle = keyof typeof weatherIcons;
-export type WeatherIcon = (typeof weatherIcons)[WeatherIconTitle];
diff --git a/ags/HyprPanel/lib/types/widget.d.ts b/ags/HyprPanel/lib/types/widget.d.ts
deleted file mode 100644
index ebb09a4..0000000
--- a/ags/HyprPanel/lib/types/widget.d.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import Gtk from 'types/@girs/gtk-3.0/gtk-3.0';
-import Box from 'types/widgets/box';
-
-export type Exclusivity = 'normal' | 'ignore' | 'exclusive';
-export type Anchor = 'left' | 'right' | 'top' | 'down';
-export type Transition = 'none' | 'crossfade' | 'slide_right' | 'slide_left' | 'slide_up' | 'slide_down';
-
-export type Layouts =
- | 'center'
- | 'top'
- | 'top-right'
- | 'top-center'
- | 'top-left'
- | 'bottom-left'
- | 'bottom-center'
- | 'bottom-right';
-
-export type Attribute = unknown;
-export type Child = Gtk.Widget;
-export type GtkWidget = Gtk.Widget;
-export type BoxWidget = Box;
-
-export type GButton = Gtk.Button;
-export type GBox = Gtk.Box;
-export type GLabel = Gtk.Label;
-export type GCenterBox = Gtk.Box;
-
-export type EventHandler = (self: Self, event: Gdk.Event) => boolean | unknown;
-export type EventArgs = { clicked: Button; event: Gdk.Event };
diff --git a/ags/HyprPanel/lib/types/workspace.d.ts b/ags/HyprPanel/lib/types/workspace.d.ts
deleted file mode 100644
index 9c46c15..0000000
--- a/ags/HyprPanel/lib/types/workspace.d.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export type WorkspaceRule = {
- workspaceString: string;
- monitor: string;
-};
-
-export type WorkspaceMap = {
- [key: string]: number[];
-};
-
-export type MonitorMap = {
- [key: number]: string;
-};
-
-export type WorkspaceIcons = {
- [key: string]: string;
-};
-
-export type WorkspaceIconsColored = {
- [key: string]: {
- color: string;
- icon: string;
- };
-};
-
-export type WorkspaceIconMap = WorkspaceIcons | WorkspaceIconsColored;
diff --git a/ags/HyprPanel/lib/utils.ts b/ags/HyprPanel/lib/utils.ts
deleted file mode 100644
index 8b8fd04..0000000
--- a/ags/HyprPanel/lib/utils.ts
+++ /dev/null
@@ -1,195 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import { type Application } from 'types/service/applications';
-import { NotificationAnchor } from './types/options';
-import { OSDAnchor } from 'lib/types/options';
-import icons, { substitutes } from './icons';
-import Gtk from 'gi://Gtk?version=3.0';
-import Gdk from 'gi://Gdk';
-import GLib from 'gi://GLib?version=2.0';
-import GdkPixbuf from 'gi://GdkPixbuf';
-import { NotificationArgs } from 'types/utils/notify';
-import { SubstituteKeys } from './types/utils';
-import { Window } from 'types/@girs/gtk-3.0/gtk-3.0.cjs';
-import { namedColors } from './constants/colors';
-
-export type Binding = import('types/service').Binding;
-
-/**
- * @returns substitute icon || name || fallback icon
- */
-export function icon(name: string | null, fallback = icons.missing): string {
- const validateSubstitute = (name: string): name is SubstituteKeys => name in substitutes;
-
- if (!name) return fallback || '';
-
- if (GLib.file_test(name, GLib.FileTest.EXISTS)) return name;
-
- let icon: string = name;
-
- if (validateSubstitute(name)) {
- icon = substitutes[name];
- }
-
- if (Utils.lookUpIcon(icon)) return icon;
-
- print(`no icon substitute "${icon}" for "${name}", fallback: "${fallback}"`);
- return fallback;
-}
-
-/**
- * @returns execAsync(["bash", "-c", cmd])
- */
-export async function bash(strings: TemplateStringsArray | string, ...values: unknown[]): Promise {
- const cmd =
- typeof strings === 'string' ? strings : strings.flatMap((str, i) => str + `${values[i] ?? ''}`).join('');
-
- return Utils.execAsync(['bash', '-c', cmd]).catch((err) => {
- console.error(cmd, err);
- return '';
- });
-}
-
-/**
- * @returns execAsync(cmd)
- */
-export async function sh(cmd: string | string[]): Promise {
- return Utils.execAsync(cmd).catch((err) => {
- console.error(typeof cmd === 'string' ? cmd : cmd.join(' '), err);
- return '';
- });
-}
-
-export function forMonitors(widget: (monitor: number) => Gtk.Window): Window[] {
- const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
- return range(n, 0).flatMap(widget);
-}
-
-/**
- * @returns [start...length]
- */
-export function range(length: number, start = 1): number[] {
- return Array.from({ length }, (_, i) => i + start);
-}
-
-/**
- * @returns true if all of the `bins` are found
- */
-export function dependencies(...bins: string[]): boolean {
- const missing = bins.filter((bin) =>
- Utils.exec({
- cmd: `which ${bin}`,
- out: () => false,
- err: () => true,
- }),
- );
-
- if (missing.length > 0) {
- console.warn(Error(`missing dependencies: ${missing.join(', ')}`));
- Notify({
- summary: 'Dependencies not found!',
- body: `The following dependencies are missing: ${missing.join(', ')}`,
- iconName: icons.ui.warning,
- timeout: 7000,
- });
- }
-
- return missing.length === 0;
-}
-
-/**
- * run app detached
- */
-export function launchApp(app: Application): void {
- const exe = app.executable
- .split(/\s+/)
- .filter((str) => !str.startsWith('%') && !str.startsWith('@'))
- .join(' ');
-
- bash(`${exe} &`);
- app.frequency += 1;
-}
-
-/**
- * to use with drag and drop
- */
-export function createSurfaceFromWidget(widget: Gtk.Widget): GdkPixbuf.Pixbuf {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const cairo = imports.gi.cairo as any;
- const alloc = widget.get_allocation();
- const surface = new cairo.ImageSurface(cairo.Format.ARGB32, alloc.width, alloc.height);
- const cr = new cairo.Context(surface);
- cr.setSourceRGBA(255, 255, 255, 0);
- cr.rectangle(0, 0, alloc.width, alloc.height);
- cr.fill();
- widget.draw(cr);
- return surface;
-}
-
-/**
- * Ensure that the provided filepath is a valid image
- */
-export const isAnImage = (imgFilePath: string): boolean => {
- try {
- GdkPixbuf.Pixbuf.new_from_file(imgFilePath);
- return true;
- } catch (error) {
- console.error(error);
- return false;
- }
-};
-
-export const Notify = (notifPayload: NotificationArgs): void => {
- let command = 'notify-send';
- command += ` "${notifPayload.summary} "`;
- if (notifPayload.body) command += ` "${notifPayload.body}" `;
- if (notifPayload.appName) command += ` -a "${notifPayload.appName}"`;
- if (notifPayload.iconName) command += ` -i "${notifPayload.iconName}"`;
- if (notifPayload.urgency) command += ` -u "${notifPayload.urgency}"`;
- if (notifPayload.timeout !== undefined) command += ` -t ${notifPayload.timeout}`;
- if (notifPayload.category) command += ` -c "${notifPayload.category}"`;
- if (notifPayload.transient) command += ` -e`;
- if (notifPayload.id !== undefined) command += ` -r ${notifPayload.id}`;
-
- Utils.execAsync(command);
-};
-
-export const getPosition = (pos: NotificationAnchor | OSDAnchor): ('top' | 'bottom' | 'left' | 'right')[] => {
- const positionMap: { [key: string]: ('top' | 'bottom' | 'left' | 'right')[] } = {
- top: ['top'],
- 'top right': ['top', 'right'],
- 'top left': ['top', 'left'],
- bottom: ['bottom'],
- 'bottom right': ['bottom', 'right'],
- 'bottom left': ['bottom', 'left'],
- right: ['right'],
- left: ['left'],
- };
-
- return positionMap[pos] || ['top'];
-};
-export const isValidGjsColor = (color: string): boolean => {
- const colorLower = color.toLowerCase().trim();
-
- if (namedColors.has(colorLower)) {
- return true;
- }
-
- const hexColorRegex = /^#(?:[a-fA-F0-9]{3,4}|[a-fA-F0-9]{6,8})$/;
-
- const rgbRegex = /^rgb\(\s*(\d{1,3}%?\s*,\s*){2}\d{1,3}%?\s*\)$/;
- const rgbaRegex = /^rgba\(\s*(\d{1,3}%?\s*,\s*){3}(0|1|0?\.\d+)\s*\)$/;
-
- if (hexColorRegex.test(color)) {
- return true;
- }
-
- if (rgbRegex.test(colorLower) || rgbaRegex.test(colorLower)) {
- return true;
- }
-
- return false;
-};
-
-export const capitalizeFirstLetter = (str: string): string => {
- return str.charAt(0).toUpperCase() + str.slice(1);
-};
diff --git a/ags/HyprPanel/lib/variables.ts b/ags/HyprPanel/lib/variables.ts
deleted file mode 100644
index 303c121..0000000
--- a/ags/HyprPanel/lib/variables.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import GLib from 'gi://GLib';
-import { DateTime } from 'types/@girs/glib-2.0/glib-2.0.cjs';
-
-export const clock = Variable(GLib.DateTime.new_now_local(), {
- poll: [1000, (): DateTime => GLib.DateTime.new_now_local()],
-});
-
-export const uptime = Variable(0, {
- poll: [60_000, 'cat /proc/uptime', (line): number => Number.parseInt(line.split('.')[0]) / 60],
-});
-
-export const distro = {
- id: GLib.get_os_info('ID'),
- logo: GLib.get_os_info('LOGO'),
-};
diff --git a/ags/HyprPanel/main.ts b/ags/HyprPanel/main.ts
deleted file mode 100644
index 399c1f9..0000000
--- a/ags/HyprPanel/main.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'lib/session';
-import 'scss/style';
-import 'globals/useTheme';
-import 'globals/dropdown.js';
-import 'globals/utilities';
-
-import { Bar } from 'modules/bar/Bar';
-import MenuWindows from './modules/menus/main.js';
-import SettingsDialog from 'widget/settings/SettingsDialog';
-import Notifications from './modules/notifications/index.js';
-import { forMonitors } from 'lib/utils';
-import OSD from 'modules/osd/index';
-
-App.config({
- onConfigParsed: () => Utils.execAsync(`python3 ${App.configDir}/services/bluetooth.py`),
- windows: [...MenuWindows, Notifications(), SettingsDialog(), ...forMonitors(Bar), OSD()],
- closeWindowDelay: {
- sideright: 350,
- launcher: 350,
- bar0: 350,
- },
-});
diff --git a/ags/HyprPanel/modules/bar/Bar.ts b/ags/HyprPanel/modules/bar/Bar.ts
deleted file mode 100644
index b5eff25..0000000
--- a/ags/HyprPanel/modules/bar/Bar.ts
+++ /dev/null
@@ -1,315 +0,0 @@
-const hyprland = await Service.import('hyprland');
-
-import {
- Menu,
- Workspaces,
- ClientTitle,
- Media,
- Notifications,
- Volume,
- Network,
- Bluetooth,
- BatteryLabel,
- Clock,
- SysTray,
-
- // Custom Modules
- Ram,
- Cpu,
- Storage,
- Netstat,
- KbInput,
- Updates,
- Submap,
- Weather,
- Power,
-} from './Exports';
-
-import { BarItemBox as WidgetContainer } from '../shared/barItemBox.js';
-import options from 'options';
-import Gdk from 'gi://Gdk?version=3.0';
-import Button from 'types/widgets/button.js';
-import Gtk from 'types/@girs/gtk-3.0/gtk-3.0.js';
-
-import './SideEffects';
-import { WindowLayer } from 'lib/types/options.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import Window from 'types/widgets/window.js';
-
-const { layouts } = options.bar;
-const { location } = options.theme.bar;
-
-export type BarWidget = keyof typeof widget;
-
-type Section =
- | 'battery'
- | 'dashboard'
- | 'workspaces'
- | 'windowtitle'
- | 'media'
- | 'notifications'
- | 'volume'
- | 'network'
- | 'bluetooth'
- | 'clock'
- | 'ram'
- | 'cpu'
- | 'storage'
- | 'netstat'
- | 'kbinput'
- | 'updates'
- | 'submap'
- | 'weather'
- | 'power'
- | 'systray';
-
-type Layout = {
- left: Section[];
- middle: Section[];
- right: Section[];
-};
-
-type BarLayout = {
- [key: string]: Layout;
-};
-
-const getLayoutForMonitor = (monitor: number, layouts: BarLayout): Layout => {
- const matchingKey = Object.keys(layouts).find((key) => key === monitor.toString());
- const wildcard = Object.keys(layouts).find((key) => key === '*');
-
- if (matchingKey) {
- return layouts[matchingKey];
- }
-
- if (wildcard) {
- return layouts[wildcard];
- }
-
- return {
- left: ['dashboard', 'workspaces', 'windowtitle'],
- middle: ['media'],
- right: ['volume', 'network', 'bluetooth', 'battery', 'systray', 'clock', 'notifications'],
- };
-};
-
-const widget = {
- battery: (): Button => WidgetContainer(BatteryLabel()),
- dashboard: (): Button => WidgetContainer(Menu()),
- workspaces: (monitor: number): Button => WidgetContainer(Workspaces(monitor)),
- windowtitle: (): Button => WidgetContainer(ClientTitle()),
- media: (): Button => WidgetContainer(Media()),
- notifications: (): Button => WidgetContainer(Notifications()),
- volume: (): Button => WidgetContainer(Volume()),
- network: (): Button => WidgetContainer(Network()),
- bluetooth: (): Button => WidgetContainer(Bluetooth()),
- clock: (): Button => WidgetContainer(Clock()),
- systray: (): Button => WidgetContainer(SysTray()),
- ram: (): Button => WidgetContainer(Ram()),
- cpu: (): Button => WidgetContainer(Cpu()),
- storage: (): Button => WidgetContainer(Storage()),
- netstat: (): Button => WidgetContainer(Netstat()),
- kbinput: (): Button => WidgetContainer(KbInput()),
- updates: (): Button => WidgetContainer(Updates()),
- submap: (): Button => WidgetContainer(Submap()),
- weather: (): Button => WidgetContainer(Weather()),
- power: (): Button => WidgetContainer(Power()),
-};
-
-type GdkMonitors = {
- [key: string]: {
- key: string;
- model: string;
- used: boolean;
- };
-};
-
-function getGdkMonitors(): GdkMonitors {
- const display = Gdk.Display.get_default();
-
- if (display === null) {
- console.error('Failed to get Gdk display.');
- return {};
- }
-
- const numGdkMonitors = display.get_n_monitors();
- const gdkMonitors: GdkMonitors = {};
-
- for (let i = 0; i < numGdkMonitors; i++) {
- const curMonitor = display.get_monitor(i);
-
- if (curMonitor === null) {
- console.warn(`Monitor at index ${i} is null.`);
- continue;
- }
-
- const model = curMonitor.get_model() || '';
- const geometry = curMonitor.get_geometry();
- const scaleFactor = curMonitor.get_scale_factor();
-
- const key = `${model}_${geometry.width}x${geometry.height}_${scaleFactor}`;
- gdkMonitors[i] = { key, model, used: false };
- }
-
- return gdkMonitors;
-}
-
-/**
- * NOTE: Some more funky stuff being done by GDK.
- * We render windows/bar based on the monitor ID. So if you have 3 monitors, then your
- * monitor IDs will be [0, 1, 2]. Hyprland will NEVER change what ID belongs to what monitor.
- *
- * So if hyprland determines id 0 = DP-1, even after you unplug, shut off or restart your monitor,
- * the id 0 will ALWAYS be DP-1.
- *
- * However, GDK (the righteous genius that it is) will change the order of ID anytime your monitor
- * setup is changed. So if you unplug your monitor and plug it back it, it now becomes the last id.
- * So if DP-1 was id 0 and you unplugged it, it will reconfigure to id 2. This sucks because now
- * there's a mismtach between what GDK determines the monitor is at id 2 and what Hyprland determines
- * is at id 2.
- *
- * So for that reason, we need to redirect the input `monitor` that the Bar module takes in, to the
- * proper Hyprland monitor. So when monitor id 0 comes in, we need to find what the id of that monitor
- * is being determined as by Hyprland so the bars show up on the right monitors.
- *
- * Since GTK3 doesn't contain connection names and only monitor models, we have to make the best guess
- * in the case that there are multiple models in the same resolution with the same scale. We find the
- * 'right' monitor by checking if the model matches along with the resolution and scale. If monitor at
- * ID 0 for GDK is being reported as 'MSI MAG271CQR' we find the same model in the Hyprland monitor list
- * and check if the resolution and scaling is the same... if it is then we determine it's a match.
- *
- * The edge-case that we just can't handle is if you have the same monitors in the same resolution at the same
- * scale. So if you've got 2 'MSI MAG271CQR' monitors at 2560x1440 at scale 1, then we just match the first
- * monitor in the list as the first match and then the second 'MSI MAG271CQR' as a match in the 2nd iteration.
- * You may have the bar showing up on the wrong one in this case because we don't know what the connector id
- * is of either of these monitors (DP-1, DP-2) which are unique values - as these are only in GTK4.
- *
- * Keep in mind though, this is ONLY an issue if you change your monitor setup by plugging in a new one, restarting
- * an existing one or shutting it off.
- *
- * If your monitors aren't changed in the current session you're in then none of this safeguarding is relevant.
- *
- * Fun stuff really... :facepalm:
- */
-
-const gdkMonitorIdToHyprlandId = (monitor: number, usedHyprlandMonitors: Set): number => {
- const gdkMonitors = getGdkMonitors();
-
- if (Object.keys(gdkMonitors).length === 0) {
- console.error('No GDK monitors were found.');
- return monitor;
- }
-
- // Get the GDK monitor for the given monitor index
- const gdkMonitor = gdkMonitors[monitor];
-
- // First pass: Strict matching including the monitor index (i.e., hypMon.id === monitor + resolution+scale criteria)
- const directMatch = hyprland.monitors.find((hypMon) => {
- const hyprlandKey = `${hypMon.model}_${hypMon.width}x${hypMon.height}_${hypMon.scale}`;
- return gdkMonitor.key.startsWith(hyprlandKey) && !usedHyprlandMonitors.has(hypMon.id) && hypMon.id === monitor;
- });
-
- if (directMatch) {
- usedHyprlandMonitors.add(directMatch.id);
- return directMatch.id;
- }
-
- // Second pass: Relaxed matching without considering the monitor index
- const hyprlandMonitor = hyprland.monitors.find((hypMon) => {
- const hyprlandKey = `${hypMon.model}_${hypMon.width}x${hypMon.height}_${hypMon.scale}`;
- return gdkMonitor.key.startsWith(hyprlandKey) && !usedHyprlandMonitors.has(hypMon.id);
- });
-
- if (hyprlandMonitor) {
- usedHyprlandMonitors.add(hyprlandMonitor.id);
- return hyprlandMonitor.id;
- }
-
- // Fallback: Find the first available monitor ID that hasn't been used
- const fallbackMonitor = hyprland.monitors.find((hypMon) => !usedHyprlandMonitors.has(hypMon.id));
-
- if (fallbackMonitor) {
- usedHyprlandMonitors.add(fallbackMonitor.id);
- return fallbackMonitor.id;
- }
-
- // Ensure we return a valid monitor ID that actually exists
- for (let i = 0; i < hyprland.monitors.length; i++) {
- if (!usedHyprlandMonitors.has(i)) {
- usedHyprlandMonitors.add(i);
- return i;
- }
- }
-
- // As a last resort, return the original monitor index if no unique monitor can be found
- console.warn(`Returning original monitor index as a last resort: ${monitor}`);
- return monitor;
-};
-
-export const Bar = (() => {
- const usedHyprlandMonitors = new Set();
-
- return (monitor: number): Window => {
- const hyprlandMonitor = gdkMonitorIdToHyprlandId(monitor, usedHyprlandMonitors);
-
- return Widget.Window({
- name: `bar-${hyprlandMonitor}`,
- class_name: 'bar',
- monitor,
- visible: true,
- anchor: location.bind('value').as((ln) => [ln, 'left', 'right']),
- exclusivity: 'exclusive',
- layer: Utils.merge(
- [options.theme.bar.layer.bind('value'), options.tear.bind('value')],
- (barLayer: WindowLayer, tear: boolean) => {
- if (tear && barLayer === 'overlay') {
- return 'top';
- }
- return barLayer;
- },
- ),
- child: Widget.Box({
- class_name: 'bar-panel-container',
- child: Widget.CenterBox({
- class_name: 'bar-panel',
- css: 'padding: 1px',
- startWidget: Widget.Box({
- class_name: 'box-left',
- hexpand: true,
- setup: (self) => {
- self.hook(layouts, (self) => {
- const foundLayout = getLayoutForMonitor(hyprlandMonitor, layouts.value as BarLayout);
- self.children = foundLayout.left
- .filter((mod) => Object.keys(widget).includes(mod))
- .map((w) => widget[w](hyprlandMonitor) as Button);
- });
- },
- }),
- centerWidget: Widget.Box({
- class_name: 'box-center',
- hpack: 'center',
- setup: (self) => {
- self.hook(layouts, (self) => {
- const foundLayout = getLayoutForMonitor(hyprlandMonitor, layouts.value as BarLayout);
- self.children = foundLayout.middle
- .filter((mod) => Object.keys(widget).includes(mod))
- .map((w) => widget[w](hyprlandMonitor) as Button);
- });
- },
- }),
- endWidget: Widget.Box({
- class_name: 'box-right',
- hpack: 'end',
- setup: (self) => {
- self.hook(layouts, (self) => {
- const foundLayout = getLayoutForMonitor(hyprlandMonitor, layouts.value as BarLayout);
- self.children = foundLayout.right
- .filter((mod) => Object.keys(widget).includes(mod))
- .map((w) => widget[w](hyprlandMonitor) as Button);
- });
- },
- }),
- }),
- }),
- });
- };
-})();
diff --git a/ags/HyprPanel/modules/bar/Exports.ts b/ags/HyprPanel/modules/bar/Exports.ts
deleted file mode 100644
index 6a17b2f..0000000
--- a/ags/HyprPanel/modules/bar/Exports.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Menu } from './menu/index';
-import { Workspaces } from './workspaces/index';
-import { ClientTitle } from './window_title/index';
-import { Media } from './media/index';
-import { Notifications } from './notifications/index';
-import { Volume } from './volume/index';
-import { Network } from './network/index';
-import { Bluetooth } from './bluetooth/index';
-import { BatteryLabel } from './battery/index';
-import { Clock } from './clock/index';
-import { SysTray } from './systray/index';
-
-// Custom Modules
-import { Ram } from '../../customModules/ram/index';
-import { Cpu } from '../../customModules/cpu/index';
-import { Storage } from 'customModules/storage/index';
-import { Netstat } from 'customModules/netstat/index';
-import { KbInput } from 'customModules/kblayout/index';
-import { Updates } from 'customModules/updates/index';
-import { Submap } from 'customModules/submap/index';
-import { Weather } from 'customModules/weather/index';
-import { Power } from 'customModules/power/index';
-
-export {
- Menu,
- Workspaces,
- ClientTitle,
- Media,
- Notifications,
- Volume,
- Network,
- Bluetooth,
- BatteryLabel,
- Clock,
- SysTray,
-
- // Custom Modules
- Ram,
- Cpu,
- Storage,
- Netstat,
- KbInput,
- Updates,
- Submap,
- Weather,
- Power,
-};
diff --git a/ags/HyprPanel/modules/bar/SideEffects.ts b/ags/HyprPanel/modules/bar/SideEffects.ts
deleted file mode 100644
index e4aabec..0000000
--- a/ags/HyprPanel/modules/bar/SideEffects.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import options from 'options';
-
-const { showIcon, showTime } = options.bar.clock;
-
-showIcon.connect('changed', () => {
- if (!showTime.value && !showIcon.value) {
- showTime.value = true;
- }
-});
-
-showTime.connect('changed', () => {
- if (!showTime.value && !showIcon.value) {
- showIcon.value = true;
- }
-});
-
-const { label, icon } = options.bar.windowtitle;
-
-label.connect('changed', () => {
- if (!label.value && !icon.value) {
- icon.value = true;
- }
-});
-
-icon.connect('changed', () => {
- if (!label.value && !icon.value) {
- label.value = true;
- }
-});
diff --git a/ags/HyprPanel/modules/bar/battery/index.ts b/ags/HyprPanel/modules/bar/battery/index.ts
deleted file mode 100644
index 8d22ef7..0000000
--- a/ags/HyprPanel/modules/bar/battery/index.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-const battery = await Service.import('battery');
-import Gdk from 'gi://Gdk?version=3.0';
-import { openMenu } from '../utils.js';
-import options from 'options';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const { label: show_label, rightClick, middleClick, scrollUp, scrollDown, hideLabelWhenFull } = options.bar.battery;
-
-const BatteryLabel = (): BarBoxChild => {
- const isVis = Variable(battery.available);
-
- const batIcon = Utils.merge(
- [battery.bind('percent'), battery.bind('charging'), battery.bind('charged')],
- (batPercent: number, batCharging, batCharged) => {
- if (batCharged) return `battery-level-100-charged-symbolic`;
- else return `battery-level-${Math.floor(batPercent / 10) * 10}${batCharging ? '-charging' : ''}-symbolic`;
- },
- );
-
- battery.connect('changed', ({ available }) => {
- isVis.value = available;
- });
-
- const formatTime = (seconds: number): Record => {
- const hours = Math.floor(seconds / 3600);
- const minutes = Math.floor((seconds % 3600) / 60);
- return { hours, minutes };
- };
-
- const generateTooltip = (timeSeconds: number, isCharging: boolean, isCharged: boolean): string => {
- if (isCharged) {
- return 'Fully Charged!!!';
- }
-
- const { hours, minutes } = formatTime(timeSeconds);
- if (isCharging) {
- return `${hours} hours ${minutes} minutes until full`;
- } else {
- return `${hours} hours ${minutes} minutes left`;
- }
- };
-
- return {
- component: Widget.Box({
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), show_label.bind('value')],
- (style, showLabel) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `battery-container ${styleMap[style]} ${!showLabel ? 'no-label' : ''}`;
- },
- ),
- visible: battery.bind('available'),
- tooltip_text: battery.bind('time_remaining').as((t) => t.toString()),
- children: Utils.merge(
- [
- battery.bind('available'),
- show_label.bind('value'),
- battery.bind('charged'),
- hideLabelWhenFull.bind('value'),
- ],
- (batAvail, showLabel, isCharged, hideWhenFull) => {
- if (batAvail && showLabel) {
- return [
- Widget.Icon({
- class_name: 'bar-button-icon battery',
- icon: batIcon,
- }),
- ...(hideWhenFull && isCharged
- ? []
- : [
- Widget.Label({
- class_name: 'bar-button-label battery',
- label: battery.bind('percent').as((p) => `${Math.floor(p)}%`),
- }),
- ]),
- ];
- } else if (batAvail && !showLabel) {
- return [
- Widget.Icon({
- class_name: 'bar-button-icon battery',
- icon: batIcon,
- }),
- ];
- } else {
- return [];
- }
- },
- ),
- setup: (self) => {
- self.hook(battery, () => {
- if (battery.available) {
- self.tooltip_text = generateTooltip(battery.time_remaining, battery.charging, battery.charged);
- }
- });
- },
- }),
- isVis,
- boxClass: 'battery',
- props: {
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- onPrimaryClick: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'energymenu');
- },
- },
- };
-};
-
-export { BatteryLabel };
diff --git a/ags/HyprPanel/modules/bar/bluetooth/index.ts b/ags/HyprPanel/modules/bar/bluetooth/index.ts
deleted file mode 100644
index 55381a3..0000000
--- a/ags/HyprPanel/modules/bar/bluetooth/index.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-const bluetooth = await Service.import('bluetooth');
-import Gdk from 'gi://Gdk?version=3.0';
-import options from 'options';
-import { openMenu } from '../utils.js';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const { label, rightClick, middleClick, scrollDown, scrollUp } = options.bar.bluetooth;
-
-const Bluetooth = (): BarBoxChild => {
- const btIcon = Widget.Label({
- label: bluetooth.bind('enabled').as((v) => (v ? '' : '')),
- class_name: 'bar-button-icon bluetooth txt-icon bar',
- });
-
- const btText = Widget.Label({
- label: Utils.merge([bluetooth.bind('enabled'), bluetooth.bind('connected_devices')], (btEnabled, btDevices) => {
- return btEnabled && btDevices.length ? ` Connected (${btDevices.length})` : btEnabled ? 'On' : 'Off';
- }),
- class_name: 'bar-button-label bluetooth',
- });
-
- return {
- component: Widget.Box({
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), label.bind('value')],
- (style, showLabel) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `bluetooth-container ${styleMap[style]} ${!showLabel ? 'no-label' : ''}`;
- },
- ),
- children: options.bar.bluetooth.label.bind('value').as((showLabel) => {
- if (showLabel) {
- return [btIcon, btText];
- }
- return [btIcon];
- }),
- }),
- isVisible: true,
- boxClass: 'bluetooth',
- props: {
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- on_primary_click: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'bluetoothmenu');
- },
- },
- };
-};
-
-export { Bluetooth };
diff --git a/ags/HyprPanel/modules/bar/clock/index.ts b/ags/HyprPanel/modules/bar/clock/index.ts
deleted file mode 100644
index 0b2fe21..0000000
--- a/ags/HyprPanel/modules/bar/clock/index.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-import GLib from 'gi://GLib';
-import { openMenu } from '../utils.js';
-import options from 'options';
-import { DateTime } from 'types/@girs/glib-2.0/glib-2.0.cjs';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const { format, icon, showIcon, showTime, rightClick, middleClick, scrollUp, scrollDown } = options.bar.clock;
-const { style } = options.theme.bar.buttons;
-
-const date = Variable(GLib.DateTime.new_now_local(), {
- poll: [1000, (): DateTime => GLib.DateTime.new_now_local()],
-});
-const time = Utils.derive([date, format], (c, f) => c.format(f) || '');
-
-const Clock = (): BarBoxChild => {
- const clockTime = Widget.Label({
- class_name: 'bar-button-label clock bar',
- label: time.bind(),
- });
-
- const clockIcon = Widget.Label({
- label: icon.bind('value'),
- class_name: 'bar-button-icon clock txt-icon bar',
- });
-
- return {
- component: Widget.Box({
- className: Utils.merge(
- [style.bind('value'), showIcon.bind('value'), showTime.bind('value')],
- (btnStyle, shwIcn, shwLbl) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
-
- return `clock-container ${styleMap[btnStyle]} ${!shwLbl ? 'no-label' : ''} ${!shwIcn ? 'no-icon' : ''}`;
- },
- ),
- children: Utils.merge([showIcon.bind('value'), showTime.bind('value')], (shIcn, shTm) => {
- if (shIcn && !shTm) {
- return [clockIcon];
- } else if (shTm && !shIcn) {
- return [clockTime];
- }
-
- return [clockIcon, clockTime];
- }),
- }),
- isVisible: true,
- boxClass: 'clock',
- props: {
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- on_primary_click: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'calendarmenu');
- },
- },
- };
-};
-
-export { Clock };
diff --git a/ags/HyprPanel/modules/bar/media/index.ts b/ags/HyprPanel/modules/bar/media/index.ts
deleted file mode 100644
index 5892d7b..0000000
--- a/ags/HyprPanel/modules/bar/media/index.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-const mpris = await Service.import('mpris');
-import { openMenu } from '../utils.js';
-import options from 'options';
-import { getCurrentPlayer } from 'lib/shared/media.js';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand } from 'customModules/utils.js';
-
-const { show_artist, truncation, truncation_size, show_label, show_active_only, rightClick, middleClick } =
- options.bar.media;
-
-const Media = (): BarBoxChild => {
- const activePlayer = Variable(mpris.players[0]);
- const isVis = Variable(!show_active_only.value);
-
- show_active_only.connect('changed', () => {
- isVis.value = !show_active_only.value || mpris.players.length > 0;
- });
-
- mpris.connect('changed', () => {
- const curPlayer = getCurrentPlayer(activePlayer.value);
- activePlayer.value = curPlayer;
- isVis.value = !show_active_only.value || mpris.players.length > 0;
- });
-
- const getIconForPlayer = (playerName: string): string => {
- const windowTitleMap = [
- ['Firefox', ''],
- ['Microsoft Edge', ''],
- ['Discord', ''],
- ['Plex', ''],
- ['Spotify', ''],
- ['(.*)', ''],
- ];
-
- const foundMatch = windowTitleMap.find((wt) => RegExp(wt[0], 'i').test(playerName));
-
- return foundMatch ? foundMatch[1] : '';
- };
-
- const songIcon = Variable('');
-
- const mediaLabel = Utils.watch('Media', [mpris, show_artist, truncation, truncation_size, show_label], () => {
- if (activePlayer.value && show_label.value) {
- const { track_title, identity, track_artists } = activePlayer.value;
- songIcon.value = getIconForPlayer(identity);
- const trackArtist = show_artist.value ? ` - ${track_artists.join(', ')}` : ``;
- const truncatedLabel = truncation.value
- ? `${track_title + trackArtist}`.substring(0, truncation_size.value)
- : `${track_title + trackArtist}`;
-
- return track_title.length === 0
- ? `No media playing...`
- : truncatedLabel.length < truncation_size.value || !truncation.value
- ? `${truncatedLabel}`
- : `${truncatedLabel.substring(0, truncatedLabel.length - 3)}...`;
- } else {
- songIcon.value = getIconForPlayer(activePlayer.value?.identity || '');
- return `Media`;
- }
- });
-
- return {
- component: Widget.Box({
- visible: false,
- child: Widget.Box({
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), show_label.bind('value')],
- (style) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `media-container ${styleMap[style]}`;
- },
- ),
- child: Widget.Box({
- children: [
- Widget.Label({
- class_name: 'bar-button-icon media txt-icon bar',
- label: songIcon.bind('value').as((v) => v || ''),
- }),
- Widget.Label({
- class_name: 'bar-button-label media',
- label: mediaLabel,
- }),
- ],
- }),
- }),
- }),
- isVis,
- boxClass: 'media',
- props: {
- on_scroll_up: () => activePlayer.value?.next(),
- on_scroll_down: () => activePlayer.value?.previous(),
- on_primary_click: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'mediamenu');
- },
- onSecondaryClick: (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- },
- onMiddleClick: (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- },
- },
- };
-};
-
-export { Media };
diff --git a/ags/HyprPanel/modules/bar/menu/index.ts b/ags/HyprPanel/modules/bar/menu/index.ts
deleted file mode 100644
index 5c55bfb..0000000
--- a/ags/HyprPanel/modules/bar/menu/index.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-import { openMenu } from '../utils.js';
-import options from 'options';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const { rightClick, middleClick, scrollUp, scrollDown } = options.bar.launcher;
-
-const Menu = (): BarBoxChild => {
- return {
- component: Widget.Box({
- className: Utils.merge([options.theme.bar.buttons.style.bind('value')], (style) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `dashboard ${styleMap[style]}`;
- }),
- child: Widget.Label({
- class_name: 'bar-menu_label bar-button_icon txt-icon bar',
- label: options.bar.launcher.icon.bind('value'),
- }),
- }),
- isVisible: true,
- boxClass: 'dashboard',
- props: {
- on_primary_click: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'dashboardmenu');
- },
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- },
- };
-};
-
-export { Menu };
diff --git a/ags/HyprPanel/modules/bar/network/index.ts b/ags/HyprPanel/modules/bar/network/index.ts
deleted file mode 100644
index 056f455..0000000
--- a/ags/HyprPanel/modules/bar/network/index.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-const network = await Service.import('network');
-import options from 'options';
-import { openMenu } from '../utils.js';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const {
- label: networkLabel,
- truncation,
- truncation_size,
- rightClick,
- middleClick,
- scrollDown,
- scrollUp,
-} = options.bar.network;
-
-const Network = (): BarBoxChild => {
- return {
- component: Widget.Box({
- vpack: 'fill',
- vexpand: true,
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), networkLabel.bind('value')],
- (style, showLabel) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `network-container ${styleMap[style]}${!showLabel ? ' no-label' : ''}`;
- },
- ),
- children: [
- Widget.Icon({
- class_name: 'bar-button-icon network-icon',
- icon: Utils.merge(
- [network.bind('primary'), network.bind('wifi'), network.bind('wired')],
- (pmry, wfi, wrd) => {
- if (pmry === 'wired') {
- return wrd.icon_name;
- }
- return wfi.icon_name;
- },
- ),
- }),
- Widget.Box({
- child: Utils.merge(
- [
- network.bind('primary'),
- network.bind('wifi'),
- networkLabel.bind('value'),
- truncation.bind('value'),
- truncation_size.bind('value'),
- ],
- (pmry, wfi, showLbl, trunc, tSize) => {
- if (!showLbl) {
- return Widget.Box();
- }
- if (pmry === 'wired') {
- return Widget.Label({
- class_name: 'bar-button-label network-label',
- label: 'Wired'.substring(0, tSize),
- });
- }
- return Widget.Label({
- class_name: 'bar-button-label network-label',
- label: wfi.ssid ? `${trunc ? wfi.ssid.substring(0, tSize) : wfi.ssid}` : '--',
- });
- },
- ),
- }),
- ],
- }),
- isVisible: true,
- boxClass: 'network',
- props: {
- on_primary_click: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'networkmenu');
- },
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- },
- };
-};
-
-export { Network };
diff --git a/ags/HyprPanel/modules/bar/notifications/index.ts b/ags/HyprPanel/modules/bar/notifications/index.ts
deleted file mode 100644
index f0e721d..0000000
--- a/ags/HyprPanel/modules/bar/notifications/index.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-import { openMenu } from '../utils.js';
-import options from 'options';
-import { filterNotifications } from 'lib/shared/notifications.js';
-import { BarBoxChild } from 'lib/types/bar.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const { show_total, rightClick, middleClick, scrollUp, scrollDown, hideCountWhenZero } = options.bar.notifications;
-const { ignore } = options.notifications;
-
-const notifs = await Service.import('notifications');
-
-export const Notifications = (): BarBoxChild => {
- return {
- component: Widget.Box({
- hpack: 'start',
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), show_total.bind('value')],
- (style, showTotal) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `notifications-container ${styleMap[style]} ${!showTotal ? 'no-label' : ''}`;
- },
- ),
- child: Widget.Box({
- hpack: 'start',
- class_name: 'bar-notifications',
- children: Utils.merge(
- [
- notifs.bind('notifications'),
- notifs.bind('dnd'),
- show_total.bind('value'),
- ignore.bind('value'),
- hideCountWhenZero.bind('value'),
- ],
- (notif, dnd, showTotal, ignoredNotifs, hideCountForZero) => {
- const filteredNotifications = filterNotifications(notif, ignoredNotifs);
-
- const notifIcon = Widget.Label({
- hpack: 'center',
- class_name: 'bar-button-icon notifications txt-icon bar',
- label: dnd ? '' : filteredNotifications.length > 0 ? '' : '',
- });
-
- const notifLabel = Widget.Label({
- hpack: 'center',
- class_name: 'bar-button-label notifications',
- label: filteredNotifications.length.toString(),
- });
-
- if (showTotal) {
- if (hideCountForZero && filteredNotifications.length === 0) {
- return [notifIcon];
- }
- return [notifIcon, notifLabel];
- }
- return [notifIcon];
- },
- ),
- }),
- }),
- isVisible: true,
- boxClass: 'notifications',
- props: {
- on_primary_click: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'notificationsmenu');
- },
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- },
- };
-};
diff --git a/ags/HyprPanel/modules/bar/systray/index.ts b/ags/HyprPanel/modules/bar/systray/index.ts
deleted file mode 100644
index b6fece3..0000000
--- a/ags/HyprPanel/modules/bar/systray/index.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-import { BarBoxChild, SelfButton } from 'lib/types/bar';
-import { Notify } from 'lib/utils';
-const systemtray = await Service.import('systemtray');
-import options from 'options';
-
-const { ignore } = options.bar.systray;
-
-const SysTray = (): BarBoxChild => {
- const isVis = Variable(false);
-
- const items = Utils.merge([systemtray.bind('items'), ignore.bind('value')], (items, ignored) => {
- const filteredTray = items.filter(({ id }) => !ignored.includes(id));
-
- isVis.value = filteredTray.length > 0;
-
- return filteredTray.map((item) => {
- return Widget.Button({
- cursor: 'pointer',
- child: Widget.Icon({
- class_name: 'systray-icon',
- icon: item.bind('icon'),
- }),
- on_primary_click: (_: SelfButton, event: Gdk.Event) => item.activate(event),
- on_secondary_click: (_, event) => item.openMenu(event),
- onMiddleClick: () => Notify({ summary: 'App Name', body: item.id }),
- tooltip_markup: item.bind('tooltip_markup'),
- });
- });
- });
-
- return {
- component: Widget.Box({
- class_name: 'systray-container',
- children: items,
- }),
- isVisible: true,
- boxClass: 'systray',
- isVis,
- props: {},
- };
-};
-
-export { SysTray };
diff --git a/ags/HyprPanel/modules/bar/utils.ts b/ags/HyprPanel/modules/bar/utils.ts
deleted file mode 100644
index f2f545a..0000000
--- a/ags/HyprPanel/modules/bar/utils.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-import { Attribute, Child } from 'lib/types/widget';
-import { calculateMenuPosition } from 'modules/menus/shared/dropdown/locationHandler/index';
-import Button from 'types/widgets/button';
-
-export const closeAllMenus = (): void => {
- const menuWindows = App.windows
- .filter((w) => {
- if (w.name) {
- return /.*menu/.test(w.name);
- }
-
- return false;
- })
- .map((w) => w.name);
-
- menuWindows.forEach((w) => {
- if (w) {
- App.closeWindow(w);
- }
- });
-};
-
-export const openMenu = async (clicked: Button, event: Gdk.Event, window: string): Promise => {
- /*
- * NOTE: We have to make some adjustments so the menu pops up relatively
- * to the center of the button clicked. We don't want the menu to spawn
- * offcenter dependending on which edge of the button you click on.
- * -------------
- * To fix this, we take the x coordinate of the click within the button's bounds.
- * If you click the left edge of a 100 width button, then the x axis will be 0
- * and if you click the right edge then the x axis will be 100.
- * -------------
- * Then we divide the width of the button by 2 to get the center of the button and then get
- * the offset by subtracting the clicked x coordinate. Then we can apply that offset
- * to the x coordinate of the click relative to the screen to get the center of the
- * icon click.
- */
-
- const middleOfButton = Math.floor(clicked.get_allocated_width() / 2);
- const xAxisOfButtonClick = clicked.get_pointer()[0];
- const middleOffset = middleOfButton - xAxisOfButtonClick;
-
- const clickPos = event.get_root_coords();
- const adjustedXCoord = clickPos[1] + middleOffset;
- const coords = [adjustedXCoord, clickPos[2]];
-
- try {
- await calculateMenuPosition(coords, window);
- } catch (error) {
- console.error(`Error calculating menu position: ${error}`);
- }
-
- closeAllMenus();
- App.toggleWindow(window);
-};
diff --git a/ags/HyprPanel/modules/bar/volume/index.ts b/ags/HyprPanel/modules/bar/volume/index.ts
deleted file mode 100644
index e85dc52..0000000
--- a/ags/HyprPanel/modules/bar/volume/index.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import Gdk from 'gi://Gdk?version=3.0';
-const audio = await Service.import('audio');
-import { openMenu } from '../utils.js';
-import options from 'options';
-import { Binding } from 'lib/utils.js';
-import { VolumeIcons } from 'lib/types/volume.js';
-import { BarBoxChild } from 'lib/types/bar.js';
-import { Bind } from 'lib/types/variable.js';
-import Button from 'types/widgets/button.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils.js';
-
-const { rightClick, middleClick, scrollUp, scrollDown } = options.bar.volume;
-
-const Volume = (): BarBoxChild => {
- const icons: VolumeIcons = {
- 101: '',
- 66: '',
- 34: '',
- 1: '',
- 0: '',
- };
-
- const getIcon = (): Bind => {
- const icon: Binding = Utils.merge(
- [audio.speaker.bind('is_muted'), audio.speaker.bind('volume')],
- (isMuted, vol) => {
- if (isMuted) return 0;
-
- const foundVol = [101, 66, 34, 1, 0].find((threshold) => threshold <= vol * 100);
-
- if (foundVol !== undefined) {
- return foundVol;
- }
-
- return 101;
- },
- );
-
- return icon.as((i: number) => (i !== undefined ? icons[i] : icons[101]));
- };
-
- const volIcn = Widget.Label({
- hexpand: true,
- label: getIcon(),
- class_name: 'bar-button-icon volume txt-icon bar',
- });
-
- const volPct = Widget.Label({
- hexpand: true,
- label: audio.speaker.bind('volume').as((v) => `${Math.round(v * 100)}%`),
- class_name: 'bar-button-label volume',
- });
-
- return {
- component: Widget.Box({
- hexpand: true,
- vexpand: true,
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), options.bar.volume.label.bind('value')],
- (style, showLabel) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `volume-container ${styleMap[style]} ${!showLabel ? 'no-label' : ''}`;
- },
- ),
- children: options.bar.volume.label.bind('value').as((showLabel) => {
- if (showLabel) {
- return [volIcn, volPct];
- }
- return [volIcn];
- }),
- }),
- isVisible: true,
- boxClass: 'volume',
- props: {
- onPrimaryClick: (clicked: Button, event: Gdk.Event): void => {
- openMenu(clicked, event, 'audiomenu');
- },
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- },
- };
-};
-
-export { Volume };
diff --git a/ags/HyprPanel/modules/bar/window_title/index.ts b/ags/HyprPanel/modules/bar/window_title/index.ts
deleted file mode 100644
index ddfd44b..0000000
--- a/ags/HyprPanel/modules/bar/window_title/index.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-const hyprland = await Service.import('hyprland');
-import { BarBoxChild } from 'lib/types/bar';
-import options from 'options';
-import { Attribute, Child } from 'lib/types/widget';
-import { ActiveClient } from 'types/service/hyprland';
-import Label from 'types/widgets/label';
-import { runAsyncCommand, throttledScrollHandler } from 'customModules/utils';
-import Button from 'types/widgets/button';
-import Gdk from 'types/@girs/gdk-3.0/gdk-3.0';
-
-const { leftClick, rightClick, middleClick, scrollDown, scrollUp } = options.bar.windowtitle;
-
-const filterTitle = (windowtitle: ActiveClient): Record => {
- const windowTitleMap = [
- // user provided values
- ...options.bar.windowtitle.title_map.value,
- // Original Entries
- ['kitty', '', 'Kitty Terminal'],
- ['firefox', '', 'Firefox'],
- ['microsoft-edge', '', 'Edge'],
- ['discord', '', 'Discord'],
- ['vesktop', '', 'Vesktop'],
- ['org.kde.dolphin', '', 'Dolphin'],
- ['plex', '', 'Plex'],
- ['steam', '', 'Steam'],
- ['spotify', '', 'Spotify'],
- ['ristretto', '', 'Ristretto'],
- ['obsidian', '', 'Obsidian'],
-
- // Browsers
- ['google-chrome', '', 'Google Chrome'],
- ['brave-browser', '', 'Brave Browser'],
- ['chromium', '', 'Chromium'],
- ['opera', '', 'Opera'],
- ['vivaldi', '', 'Vivaldi'],
- ['waterfox', '', 'Waterfox'],
- ['thorium', '', 'Waterfox'],
- ['tor-browser', '', 'Tor Browser'],
- ['floorp', '', 'Floorp'],
-
- // Terminals
- ['gnome-terminal', '', 'GNOME Terminal'],
- ['konsole', '', 'Konsole'],
- ['alacritty', '', 'Alacritty'],
- ['wezterm', '', 'Wezterm'],
- ['foot', '', 'Foot Terminal'],
- ['tilix', '', 'Tilix'],
- ['xterm', '', 'XTerm'],
- ['urxvt', '', 'URxvt'],
- ['st', '', 'st Terminal'],
-
- // Development Tools
- ['code', '', 'Visual Studio Code'],
- ['vscode', '', 'VS Code'],
- ['sublime-text', '', 'Sublime Text'],
- ['atom', '', 'Atom'],
- ['android-studio', '', 'Android Studio'],
- ['intellij-idea', '', 'IntelliJ IDEA'],
- ['pycharm', '', 'PyCharm'],
- ['webstorm', '', 'WebStorm'],
- ['phpstorm', '', 'PhpStorm'],
- ['eclipse', '', 'Eclipse'],
- ['netbeans', '', 'NetBeans'],
- ['docker', '', 'Docker'],
- ['vim', '', 'Vim'],
- ['neovim', '', 'Neovim'],
- ['neovide', '', 'Neovide'],
- ['emacs', '', 'Emacs'],
-
- // Communication Tools
- ['slack', '', 'Slack'],
- ['telegram-desktop', '', 'Telegram'],
- ['org.telegram.desktop', '', 'Telegram'],
- ['whatsapp', '', 'WhatsApp'],
- ['teams', '', 'Microsoft Teams'],
- ['skype', '', 'Skype'],
- ['thunderbird', '', 'Thunderbird'],
-
- // File Managers
- ['nautilus', '', 'Files (Nautilus)'],
- ['thunar', '', 'Thunar'],
- ['pcmanfm', '', 'PCManFM'],
- ['nemo', '', 'Nemo'],
- ['ranger', '', 'Ranger'],
- ['doublecmd', '', 'Double Commander'],
- ['krusader', '', 'Krusader'],
-
- // Media Players
- ['vlc', '', 'VLC Media Player'],
- ['mpv', '', 'MPV'],
- ['rhythmbox', '', 'Rhythmbox'],
-
- // Graphics Tools
- ['gimp', '', 'GIMP'],
- ['inkscape', '', 'Inkscape'],
- ['krita', '', 'Krita'],
- ['blender', '', 'Blender'],
-
- // Video Editing
- ['kdenlive', '', 'Kdenlive'],
-
- // Games and Gaming Platforms
- ['lutris', '', 'Lutris'],
- ['heroic', '', 'Heroic Games Launcher'],
- ['minecraft', '', 'Minecraft'],
- ['csgo', '', 'CS:GO'],
- ['dota2', '', 'Dota 2'],
-
- // Office and Productivity
- ['evernote', '', 'Evernote'],
- ['sioyek', '', 'Sioyek'],
-
- // Cloud Services and Sync
- ['dropbox', '', 'Dropbox'],
-
- // Desktop
- ['^$', '', 'Desktop'],
-
- // Fallback icon
- ['(.+)', '', `${windowtitle.class.charAt(0).toUpperCase() + windowtitle.class.slice(1)}`],
- ];
-
- const foundMatch = windowTitleMap.find((wt) => RegExp(wt[0]).test(windowtitle.class.toLowerCase()));
-
- // return the default icon if no match is found or
- // if the array element matched is not of size 3
- if (!foundMatch || foundMatch.length !== 3) {
- return {
- icon: windowTitleMap[windowTitleMap.length - 1][1],
- label: windowTitleMap[windowTitleMap.length - 1][2],
- };
- }
-
- return {
- icon: foundMatch[1],
- label: foundMatch[2],
- };
-};
-
-const getTitle = (client: ActiveClient, useCustomTitle: boolean, useClassName: boolean): string => {
- if (useCustomTitle) return filterTitle(client).label;
- if (useClassName) return client.class;
-
- const title = client.title;
- // If the title is empty or only filled with spaces, fallback to the class name
- if (title.length === 0 || title.match(/^ *$/)) {
- return client.class;
- }
- return title;
-};
-
-const truncateTitle = (title: string, max_size: number): string => {
- if (max_size > 0 && title.length > max_size) {
- return title.substring(0, max_size).trim() + '...';
- }
- return title;
-};
-
-const ClientTitle = (): BarBoxChild => {
- const { custom_title, class_name, label, icon, truncation, truncation_size } = options.bar.windowtitle;
-
- return {
- component: Widget.Box({
- className: Utils.merge(
- [options.theme.bar.buttons.style.bind('value'), label.bind('value')],
- (style, showLabel) => {
- const styleMap = {
- default: 'style1',
- split: 'style2',
- wave: 'style3',
- wave2: 'style3',
- };
- return `windowtitle-container ${styleMap[style]} ${!showLabel ? 'no-label' : ''}`;
- },
- ),
- children: Utils.merge(
- [
- hyprland.active.bind('client'),
- custom_title.bind('value'),
- class_name.bind('value'),
- label.bind('value'),
- icon.bind('value'),
- truncation.bind('value'),
- truncation_size.bind('value'),
- ],
- (client, useCustomTitle, useClassName, showLabel, showIcon, truncate, truncationSize) => {
- const children: Label[] = [];
- if (showIcon) {
- children.push(
- Widget.Label({
- class_name: 'bar-button-icon windowtitle txt-icon bar',
- label: filterTitle(client).icon,
- }),
- );
- }
-
- if (showLabel) {
- children.push(
- Widget.Label({
- class_name: `bar-button-label windowtitle ${showIcon ? '' : 'no-icon'}`,
- label: truncateTitle(
- getTitle(client, useCustomTitle, useClassName),
- truncate ? truncationSize : -1,
- ),
- }),
- );
- }
-
- return children;
- },
- ),
- }),
- isVisible: true,
- boxClass: 'windowtitle',
- props: {
- setup: (self: Button): void => {
- self.hook(options.bar.scrollSpeed, () => {
- const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.value);
-
- self.on_primary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(leftClick.value, { clicked, event });
- };
- self.on_secondary_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(rightClick.value, { clicked, event });
- };
- self.on_middle_click = (clicked: Button, event: Gdk.Event): void => {
- runAsyncCommand(middleClick.value, { clicked, event });
- };
- self.on_scroll_up = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollUp.value, { clicked, event });
- };
- self.on_scroll_down = (clicked: Button, event: Gdk.Event): void => {
- throttledHandler(scrollDown.value, { clicked, event });
- };
- });
- },
- },
- };
-};
-
-export { ClientTitle };
diff --git a/ags/HyprPanel/modules/bar/workspaces/helpers.ts b/ags/HyprPanel/modules/bar/workspaces/helpers.ts
deleted file mode 100644
index daf3cb3..0000000
--- a/ags/HyprPanel/modules/bar/workspaces/helpers.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-const hyprland = await Service.import('hyprland');
-
-import { MonitorMap, WorkspaceMap, WorkspaceRule } from 'lib/types/workspace';
-import options from 'options';
-import { Variable } from 'types/variable';
-
-const { workspaces, reverse_scroll, ignored } = options.bar.workspaces;
-
-export const getWorkspacesForMonitor = (curWs: number, wsRules: WorkspaceMap, monitor: number): boolean => {
- if (!wsRules || !Object.keys(wsRules).length) {
- return true;
- }
-
- const monitorMap: MonitorMap = {};
- const workspaceMonitorList = hyprland?.workspaces?.map((m) => ({ id: m.monitorID, name: m.monitor }));
- const monitors = [
- ...new Map([...workspaceMonitorList, ...hyprland.monitors].map((item) => [item.id, item])).values(),
- ];
-
- monitors.forEach((m) => (monitorMap[m.id] = m.name));
-
- const currentMonitorName = monitorMap[monitor];
- const monitorWSRules = wsRules[currentMonitorName];
-
- if (monitorWSRules === undefined) {
- return true;
- }
- return monitorWSRules.includes(curWs);
-};
-
-export const getWorkspaceRules = (): WorkspaceMap => {
- try {
- const rules = Utils.exec('hyprctl workspacerules -j');
-
- const workspaceRules: WorkspaceMap = {};
-
- JSON.parse(rules).forEach((rule: WorkspaceRule) => {
- const workspaceNum = parseInt(rule.workspaceString, 10);
- if (isNaN(workspaceNum)) {
- return;
- }
- if (Object.hasOwnProperty.call(workspaceRules, rule.monitor)) {
- workspaceRules[rule.monitor].push(workspaceNum);
- } else {
- workspaceRules[rule.monitor] = [workspaceNum];
- }
- });
-
- return workspaceRules;
- } catch (err) {
- console.error(err);
- return {};
- }
-};
-
-export const getCurrentMonitorWorkspaces = (monitor: number): number[] => {
- if (hyprland.monitors.length === 1) {
- return Array.from({ length: workspaces.value }, (_, i) => i + 1);
- }
-
- const monitorWorkspaces = getWorkspaceRules();
- const monitorMap: MonitorMap = {};
- hyprland.monitors.forEach((m) => (monitorMap[m.id] = m.name));
-
- const currentMonitorName = monitorMap[monitor];
-
- return monitorWorkspaces[currentMonitorName];
-};
-
-type ThrottledScrollHandlers = {
- throttledScrollUp: () => void;
- throttledScrollDown: () => void;
-};
-
-export const isWorkspaceIgnored = (ignoredWorkspaces: Variable, workspaceNumber: number): boolean => {
- if (ignoredWorkspaces.value === '') return false;
-
- const ignoredWsRegex = new RegExp(ignoredWorkspaces.value);
-
- return ignoredWsRegex.test(workspaceNumber.toString());
-};
-
-const navigateWorkspace = (
- direction: 'next' | 'prev',
- currentMonitorWorkspaces: Variable,
- activeWorkspaces: boolean,
- ignoredWorkspaces: Variable,
-): void => {
- const workspacesList = activeWorkspaces
- ? hyprland.workspaces.filter((ws) => hyprland.active.monitor.id === ws.monitorID).map((ws) => ws.id)
- : currentMonitorWorkspaces.value || Array.from({ length: workspaces.value }, (_, i) => i + 1);
-
- if (workspacesList.length === 0) return;
-
- const currentIndex = workspacesList.indexOf(hyprland.active.workspace.id);
- const step = direction === 'next' ? 1 : -1;
- let newIndex = (currentIndex + step + workspacesList.length) % workspacesList.length;
- let attempts = 0;
-
- while (attempts < workspacesList.length) {
- const targetWS = workspacesList[newIndex];
- if (!isWorkspaceIgnored(ignoredWorkspaces, targetWS)) {
- hyprland.messageAsync(`dispatch workspace ${targetWS}`);
- return;
- }
- newIndex = (newIndex + step + workspacesList.length) % workspacesList.length;
- attempts++;
- }
-};
-
-export const goToNextWS = (
- currentMonitorWorkspaces: Variable,
- activeWorkspaces: boolean,
- ignoredWorkspaces: Variable,
-): void => {
- navigateWorkspace('next', currentMonitorWorkspaces, activeWorkspaces, ignoredWorkspaces);
-};
-
-export const goToPrevWS = (
- currentMonitorWorkspaces: Variable,
- activeWorkspaces: boolean,
- ignoredWorkspaces: Variable,
-): void => {
- navigateWorkspace('prev', currentMonitorWorkspaces, activeWorkspaces, ignoredWorkspaces);
-};
-
-export function throttle void>(func: T, limit: number): T {
- let inThrottle: boolean;
- return function (this: ThisParameterType, ...args: Parameters) {
- if (!inThrottle) {
- func.apply(this, args);
- inThrottle = true;
- setTimeout(() => {
- inThrottle = false;
- }, limit);
- }
- } as T;
-}
-
-export const createThrottledScrollHandlers = (
- scrollSpeed: number,
- currentMonitorWorkspaces: Variable,
- activeWorkspaces: boolean = false,
-): ThrottledScrollHandlers => {
- const throttledScrollUp = throttle(() => {
- if (reverse_scroll.value) {
- goToPrevWS(currentMonitorWorkspaces, activeWorkspaces, ignored);
- } else {
- goToNextWS(currentMonitorWorkspaces, activeWorkspaces, ignored);
- }
- }, 200 / scrollSpeed);
-
- const throttledScrollDown = throttle(() => {
- if (reverse_scroll.value) {
- goToNextWS(currentMonitorWorkspaces, activeWorkspaces, ignored);
- } else {
- goToPrevWS(currentMonitorWorkspaces, activeWorkspaces, ignored);
- }
- }, 200 / scrollSpeed);
-
- return { throttledScrollUp, throttledScrollDown };
-};
diff --git a/ags/HyprPanel/modules/bar/workspaces/index.ts b/ags/HyprPanel/modules/bar/workspaces/index.ts
deleted file mode 100644
index c95e212..0000000
--- a/ags/HyprPanel/modules/bar/workspaces/index.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import options from 'options';
-import { createThrottledScrollHandlers, getCurrentMonitorWorkspaces } from './helpers';
-import { BarBoxChild, SelfButton } from 'lib/types/bar';
-import { occupiedWses } from './variants/occupied';
-import { defaultWses } from './variants/default';
-
-const { workspaces, scroll_speed } = options.bar.workspaces;
-
-const Workspaces = (monitor = -1): BarBoxChild => {
- const currentMonitorWorkspaces = Variable(getCurrentMonitorWorkspaces(monitor));
-
- workspaces.connect('changed', () => {
- currentMonitorWorkspaces.value = getCurrentMonitorWorkspaces(monitor);
- });
-
- return {
- component: Widget.Box({
- class_name: 'workspaces-box-container',
- child: options.bar.workspaces.hideUnoccupied.bind('value').as((hideUnoccupied) => {
- return hideUnoccupied ? occupiedWses(monitor) : defaultWses(monitor);
- }),
- }),
- isVisible: true,
- boxClass: 'workspaces',
- props: {
- setup: (self: SelfButton): void => {
- Utils.merge(
- [scroll_speed.bind('value'), options.bar.workspaces.hideUnoccupied.bind('value')],
- (scroll_speed, hideUnoccupied) => {
- const { throttledScrollUp, throttledScrollDown } = createThrottledScrollHandlers(
- scroll_speed,
- currentMonitorWorkspaces,
- hideUnoccupied,
- );
- self.on_scroll_up = throttledScrollUp;
- self.on_scroll_down = throttledScrollDown;
- },
- );
- },
- },
- };
-};
-
-export { Workspaces };
diff --git a/ags/HyprPanel/modules/bar/workspaces/utils.ts b/ags/HyprPanel/modules/bar/workspaces/utils.ts
deleted file mode 100644
index c9f2bc2..0000000
--- a/ags/HyprPanel/modules/bar/workspaces/utils.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-import { WorkspaceIconMap } from 'lib/types/workspace';
-import { isValidGjsColor } from 'lib/utils';
-import options from 'options';
-import { Monitor } from 'types/service/hyprland';
-
-const hyprland = await Service.import('hyprland');
-
-const { monochrome, background } = options.theme.bar.buttons;
-const { background: wsBackground, active } = options.theme.bar.buttons.workspaces;
-
-const { showWsIcons, showAllActive, numbered_active_indicator: activeIndicator } = options.bar.workspaces;
-
-const isWorkspaceActiveOnMonitor = (monitor: number, monitors: Monitor[], i: number): boolean => {
- return showAllActive.value && monitors[monitor]?.activeWorkspace?.id === i;
-};
-
-const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => {
- const iconEntry = wsIconMap[i];
-
- if (!iconEntry) {
- return `${i}`;
- }
-
- const hasIcon = typeof iconEntry === 'object' && 'icon' in iconEntry && iconEntry.icon !== '';
-
- if (typeof iconEntry === 'string' && iconEntry !== '') {
- return iconEntry;
- }
-
- if (hasIcon) {
- return iconEntry.icon;
- }
-
- return `${i}`;
-};
-
-export const getWsColor = (
- wsIconMap: WorkspaceIconMap,
- i: number,
- smartHighlight: boolean,
- monitor: number,
- monitors: Monitor[],
-): string => {
- const iconEntry = wsIconMap[i];
- const hasColor = typeof iconEntry === 'object' && 'color' in iconEntry && isValidGjsColor(iconEntry.color);
- if (!iconEntry) {
- return '';
- }
-
- if (
- showWsIcons.value &&
- smartHighlight &&
- activeIndicator.value === 'highlight' &&
- (hyprland.active.workspace.id === i || isWorkspaceActiveOnMonitor(monitor, monitors, i))
- ) {
- const iconColor = monochrome.value ? background : wsBackground;
- const iconBackground = hasColor && isValidGjsColor(iconEntry.color) ? iconEntry.color : active.value;
- const colorCss = `color: ${iconColor};`;
- const backgroundCss = `background: ${iconBackground};`;
-
- return colorCss + backgroundCss;
- }
-
- if (hasColor && isValidGjsColor(iconEntry.color)) {
- return `color: ${iconEntry.color}; border-bottom-color: ${iconEntry.color};`;
- }
-
- return '';
-};
-
-export const renderClassnames = (
- showIcons: boolean,
- showNumbered: boolean,
- numberedActiveIndicator: string,
- showWsIcons: boolean,
- smartHighlight: boolean,
- monitor: number,
- monitors: Monitor[],
- i: number,
-): string => {
- if (showIcons) {
- return 'workspace-icon txt-icon bar';
- }
-
- if (showNumbered || showWsIcons) {
- const numActiveInd =
- hyprland.active.workspace.id === i || isWorkspaceActiveOnMonitor(monitor, monitors, i)
- ? numberedActiveIndicator
- : '';
-
- const wsIconClass = showWsIcons ? 'txt-icon' : '';
- const smartHighlightClass = smartHighlight ? 'smart-highlight' : '';
-
- const className = `workspace-number can_${numberedActiveIndicator} ${numActiveInd} ${wsIconClass} ${smartHighlightClass}`;
-
- return className.trim();
- }
-
- return 'default';
-};
-
-export const renderLabel = (
- showIcons: boolean,
- available: string,
- active: string,
- occupied: string,
- workspaceMask: boolean,
- showWsIcons: boolean,
- wsIconMap: WorkspaceIconMap,
- i: number,
- index: number,
- monitor: number,
- monitors: Monitor[],
-): string => {
- if (showIcons) {
- if (hyprland.active.workspace.id === i || isWorkspaceActiveOnMonitor(monitor, monitors, i)) {
- return active;
- }
- if ((hyprland.getWorkspace(i)?.windows || 0) > 0) {
- return occupied;
- }
- if (monitor !== -1) {
- return available;
- }
- }
- if (showWsIcons) {
- return getWsIcon(wsIconMap, i);
- }
- return workspaceMask ? `${index + 1}` : `${i}`;
-};
diff --git a/ags/HyprPanel/modules/bar/workspaces/variants/default.ts b/ags/HyprPanel/modules/bar/workspaces/variants/default.ts
deleted file mode 100644
index dddabc9..0000000
--- a/ags/HyprPanel/modules/bar/workspaces/variants/default.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-const hyprland = await Service.import('hyprland');
-import options from 'options';
-import { getWorkspaceRules, getWorkspacesForMonitor, isWorkspaceIgnored } from '../helpers';
-import { range } from 'lib/utils';
-import { BoxWidget } from 'lib/types/widget';
-import { getWsColor, renderClassnames, renderLabel } from '../utils';
-import { WorkspaceIconMap } from 'lib/types/workspace';
-import { Monitor } from 'types/service/hyprland';
-
-const { workspaces, monitorSpecific, workspaceMask, spacing, ignored } = options.bar.workspaces;
-export const defaultWses = (monitor: number): BoxWidget => {
- return Widget.Box({
- children: Utils.merge(
- [workspaces.bind('value'), monitorSpecific.bind('value'), ignored.bind('value')],
- (workspaces: number, monitorSpecific: boolean) => {
- return range(workspaces || 8)
- .filter((workspaceNumber) => {
- if (!monitorSpecific) {
- return true;
- }
- const workspaceRules = getWorkspaceRules();
- return (
- getWorkspacesForMonitor(workspaceNumber, workspaceRules, monitor) &&
- !isWorkspaceIgnored(ignored, workspaceNumber)
- );
- })
- .sort((a, b) => {
- return a - b;
- })
- .map((i, index) => {
- return Widget.Button({
- class_name: 'workspace-button',
- on_primary_click: () => {
- hyprland.messageAsync(`dispatch workspace ${i}`);
- },
- child: Widget.Label({
- attribute: i,
- vpack: 'center',
- css: Utils.merge(
- [
- spacing.bind('value'),
- options.bar.workspaces.showWsIcons.bind('value'),
- options.bar.workspaces.workspaceIconMap.bind('value'),
- options.theme.matugen.bind('value'),
- options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
- hyprland.bind('monitors'),
- ],
- (
- sp: number,
- showWsIcons: boolean,
- workspaceIconMap: WorkspaceIconMap,
- matugen: boolean,
- smartHighlight: boolean,
- monitors: Monitor[],
- ) => {
- return (
- `margin: 0rem ${0.375 * sp}rem;` +
- `${showWsIcons && !matugen ? getWsColor(workspaceIconMap, i, smartHighlight, monitor, monitors) : ''}`
- );
- },
- ),
- class_name: Utils.merge(
- [
- options.bar.workspaces.show_icons.bind('value'),
- options.bar.workspaces.show_numbered.bind('value'),
- options.bar.workspaces.numbered_active_indicator.bind('value'),
- options.bar.workspaces.showWsIcons.bind('value'),
- options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
- hyprland.bind('monitors'),
- options.bar.workspaces.icons.available.bind('value'),
- options.bar.workspaces.icons.active.bind('value'),
- ],
- (
- showIcons: boolean,
- showNumbered: boolean,
- numberedActiveIndicator: string,
- showWsIcons: boolean,
- smartHighlight: boolean,
- monitors: Monitor[],
- ) => {
- return renderClassnames(
- showIcons,
- showNumbered,
- numberedActiveIndicator,
- showWsIcons,
- smartHighlight,
- monitor,
- monitors,
- i,
- );
- },
- ),
- label: Utils.merge(
- [
- options.bar.workspaces.show_icons.bind('value'),
- options.bar.workspaces.icons.available.bind('value'),
- options.bar.workspaces.icons.active.bind('value'),
- options.bar.workspaces.icons.occupied.bind('value'),
- options.bar.workspaces.workspaceIconMap.bind('value'),
- options.bar.workspaces.showWsIcons.bind('value'),
- workspaceMask.bind('value'),
- hyprland.bind('monitors'),
- ],
- (
- showIcons: boolean,
- available: string,
- active: string,
- occupied: string,
- wsIconMap: WorkspaceIconMap,
- showWsIcons: boolean,
- workspaceMask: boolean,
- monitors: Monitor[],
- ) => {
- return renderLabel(
- showIcons,
- available,
- active,
- occupied,
- workspaceMask,
- showWsIcons,
- wsIconMap,
- i,
- index,
- monitor,
- monitors,
- );
- },
- ),
- setup: (self) => {
- self.hook(hyprland, () => {
- self.toggleClassName('active', hyprland.active.workspace.id === i);
- self.toggleClassName('occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0);
- });
- },
- }),
- });
- });
- },
- ),
- });
-};
diff --git a/ags/HyprPanel/modules/bar/workspaces/variants/occupied.ts b/ags/HyprPanel/modules/bar/workspaces/variants/occupied.ts
deleted file mode 100644
index 31f3f14..0000000
--- a/ags/HyprPanel/modules/bar/workspaces/variants/occupied.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-const hyprland = await Service.import('hyprland');
-import options from 'options';
-import { getWorkspaceRules, getWorkspacesForMonitor, isWorkspaceIgnored } from '../helpers';
-import { Monitor, Workspace } from 'types/service/hyprland';
-import { getWsColor, renderClassnames, renderLabel } from '../utils';
-import { range } from 'lib/utils';
-import { BoxWidget } from 'lib/types/widget';
-import { WorkspaceIconMap } from 'lib/types/workspace';
-
-const { workspaces, monitorSpecific, workspaceMask, spacing, ignored, showAllActive } = options.bar.workspaces;
-
-export const occupiedWses = (monitor: number): BoxWidget => {
- return Widget.Box({
- children: Utils.merge(
- [
- monitorSpecific.bind('value'),
- hyprland.bind('workspaces'),
- workspaceMask.bind('value'),
- workspaces.bind('value'),
- options.bar.workspaces.show_icons.bind('value'),
- options.bar.workspaces.icons.available.bind('value'),
- options.bar.workspaces.icons.active.bind('value'),
- options.bar.workspaces.icons.occupied.bind('value'),
- options.bar.workspaces.show_numbered.bind('value'),
- options.bar.workspaces.numbered_active_indicator.bind('value'),
- spacing.bind('value'),
- options.bar.workspaces.workspaceIconMap.bind('value'),
- options.bar.workspaces.showWsIcons.bind('value'),
- options.theme.matugen.bind('value'),
- options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
- hyprland.bind('monitors'),
- ignored.bind('value'),
- showAllActive.bind('value'),
- ],
- (
- monitorSpecific: boolean,
- wkSpaces: Workspace[],
- workspaceMask: boolean,
- totalWkspcs: number,
- showIcons: boolean,
- available: string,
- active: string,
- occupied: string,
- showNumbered: boolean,
- numberedActiveIndicator: string,
- spacing: number,
- wsIconMap: WorkspaceIconMap,
- showWsIcons: boolean,
- matugen: boolean,
- smartHighlight: boolean,
- monitors: Monitor[],
- ) => {
- const activeId = hyprland.active.workspace.id;
- let allWkspcs = range(totalWkspcs || 8);
-
- const activeWorkspaces = wkSpaces.map((w) => w.id);
- const workspaceRules = getWorkspaceRules();
-
- // Sometimes hyprland doesn't have all the monitors in the list
- // so we complement it with monitors from the workspace list
- const workspaceMonitorList = hyprland?.workspaces?.map((m) => ({
- id: m.monitorID,
- name: m.monitor,
- }));
- const curMonitor =
- hyprland.monitors.find((m) => m.id === monitor) ||
- workspaceMonitorList.find((m) => m.id === monitor);
-
- const workspacesWithRules = Object.keys(workspaceRules).reduce((acc: number[], k: string) => {
- return [...acc, ...workspaceRules[k]];
- }, [] as number[]);
-
- const activesForMonitor = activeWorkspaces.filter((w) => {
- if (
- curMonitor &&
- Object.hasOwnProperty.call(workspaceRules, curMonitor.name) &&
- workspacesWithRules.includes(w)
- ) {
- return workspaceRules[curMonitor.name].includes(w);
- }
- return true;
- });
-
- if (monitorSpecific) {
- const wrkspcsInRange = range(totalWkspcs).filter((w) => {
- return getWorkspacesForMonitor(w, workspaceRules, monitor);
- });
- allWkspcs = [...new Set([...activesForMonitor, ...wrkspcsInRange])];
- } else {
- allWkspcs = [...new Set([...allWkspcs, ...activeWorkspaces])];
- }
-
- return allWkspcs
- .sort((a, b) => {
- return a - b;
- })
- .map((i, index) => {
- if (isWorkspaceIgnored(ignored, i)) {
- return Widget.Box();
- }
- return Widget.Button({
- class_name: 'workspace-button',
- on_primary_click: () => {
- hyprland.messageAsync(`dispatch workspace ${i}`);
- },
- child: Widget.Label({
- attribute: i,
- vpack: 'center',
- css:
- `margin: 0rem ${0.375 * spacing}rem;` +
- `${showWsIcons && !matugen ? getWsColor(wsIconMap, i, smartHighlight, monitor, monitors) : ''}`,
- class_name: renderClassnames(
- showIcons,
- showNumbered,
- numberedActiveIndicator,
- showWsIcons,
- smartHighlight,
- monitor,
- monitors,
- i,
- ),
- label: renderLabel(
- showIcons,
- available,
- active,
- occupied,
- workspaceMask,
- showWsIcons,
- wsIconMap,
- i,
- index,
- monitor,
- monitors,
- ),
- setup: (self) => {
- self.toggleClassName('active', activeId === i);
- self.toggleClassName('occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0);
- },
- }),
- });
- });
- },
- ),
- });
-};
diff --git a/ags/HyprPanel/modules/icons/index.ts b/ags/HyprPanel/modules/icons/index.ts
deleted file mode 100644
index 14d0a06..0000000
--- a/ags/HyprPanel/modules/icons/index.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-export const substitutes = {
- 'transmission-gtk': 'transmission',
- 'blueberry.py': 'blueberry',
- Caprine: 'facebook-messenger',
- 'com.raggesilver.BlackBox-symbolic': 'terminal-symbolic',
- 'org.wezfurlong.wezterm-symbolic': 'terminal-symbolic',
- 'audio-headset-bluetooth': 'audio-headphones-symbolic',
- 'audio-card-analog-usb': 'audio-speakers-symbolic',
- 'audio-card-analog-pci': 'audio-card-symbolic',
- 'preferences-system': 'emblem-system-symbolic',
- 'com.github.Aylur.ags-symbolic': 'controls-symbolic',
- 'com.github.Aylur.ags': 'controls-symbolic',
-};
-
-export default {
- missing: 'image-missing-symbolic',
- nix: {
- nix: 'nix-snowflake-symbolic',
- },
- app: {
- terminal: 'terminal-symbolic',
- },
- fallback: {
- executable: 'application-x-executable',
- notification: 'dialog-information-symbolic',
- video: 'video-x-generic-symbolic',
- audio: 'audio-x-generic-symbolic',
- },
- ui: {
- close: 'window-close-symbolic',
- colorpicker: 'color-select-symbolic',
- info: 'info-symbolic',
- link: 'external-link-symbolic',
- lock: 'system-lock-screen-symbolic',
- menu: 'open-menu-symbolic',
- refresh: 'view-refresh-symbolic',
- search: 'system-search-symbolic',
- settings: 'emblem-system-symbolic',
- themes: 'preferences-desktop-theme-symbolic',
- tick: 'object-select-symbolic',
- time: 'hourglass-symbolic',
- toolbars: 'toolbars-symbolic',
- warning: 'dialog-warning-symbolic',
- avatar: 'avatar-default-symbolic',
- arrow: {
- right: 'pan-end-symbolic',
- left: 'pan-start-symbolic',
- down: 'pan-down-symbolic',
- up: 'pan-up-symbolic',
- },
- },
- audio: {
- mic: {
- muted: 'microphone-disabled-symbolic',
- low: 'microphone-sensitivity-low-symbolic',
- medium: 'microphone-sensitivity-medium-symbolic',
- high: 'microphone-sensitivity-high-symbolic',
- },
- volume: {
- muted: 'audio-volume-muted-symbolic',
- low: 'audio-volume-low-symbolic',
- medium: 'audio-volume-medium-symbolic',
- high: 'audio-volume-high-symbolic',
- overamplified: 'audio-volume-overamplified-symbolic',
- },
- type: {
- headset: 'audio-headphones-symbolic',
- speaker: 'audio-speakers-symbolic',
- card: 'audio-card-symbolic',
- },
- mixer: 'mixer-symbolic',
- },
- powerprofile: {
- balanced: 'power-profile-balanced-symbolic',
- 'power-saver': 'power-profile-power-saver-symbolic',
- performance: 'power-profile-performance-symbolic',
- },
- asusctl: {
- profile: {
- Balanced: 'power-profile-balanced-symbolic',
- Quiet: 'power-profile-power-saver-symbolic',
- Performance: 'power-profile-performance-symbolic',
- },
- mode: {
- Integrated: 'processor-symbolic',
- Hybrid: 'controller-symbolic',
- },
- },
- battery: {
- charging: 'battery-flash-symbolic',
- warning: 'battery-empty-symbolic',
- },
- bluetooth: {
- enabled: 'bluetooth-active-symbolic',
- disabled: 'bluetooth-disabled-symbolic',
- },
- brightness: {
- indicator: 'display-brightness-symbolic',
- keyboard: 'keyboard-brightness-symbolic',
- screen: 'display-brightness-symbolic',
- },
- powermenu: {
- sleep: 'weather-clear-night-symbolic',
- reboot: 'system-reboot-symbolic',
- logout: 'system-log-out-symbolic',
- shutdown: 'system-shutdown-symbolic',
- },
- recorder: {
- recording: 'media-record-symbolic',
- },
- notifications: {
- noisy: 'org.gnome.Settings-notifications-symbolic',
- silent: 'notifications-disabled-symbolic',
- message: 'chat-bubbles-symbolic',
- },
- trash: {
- full: 'user-trash-full-symbolic',
- empty: 'user-trash-symbolic',
- },
- mpris: {
- shuffle: {
- enabled: 'media-playlist-shuffle-symbolic',
- disabled: 'media-playlist-consecutive-symbolic',
- },
- loop: {
- none: 'media-playlist-repeat-symbolic',
- track: 'media-playlist-repeat-song-symbolic',
- playlist: 'media-playlist-repeat-symbolic',
- },
- playing: 'media-playback-pause-symbolic',
- paused: 'media-playback-start-symbolic',
- stopped: 'media-playback-start-symbolic',
- prev: 'media-skip-backward-symbolic',
- next: 'media-skip-forward-symbolic',
- },
- system: {
- cpu: 'org.gnome.SystemMonitor-symbolic',
- ram: 'drive-harddisk-solidstate-symbolic',
- temp: 'temperature-symbolic',
- },
- color: {
- dark: 'dark-mode-symbolic',
- light: 'light-mode-symbolic',
- },
- weather: {
- warning: 'dialog-warning-symbolic',
- sunny: 'weather-clear-symbolic',
- clear: 'weather-clear-night-symbolic',
- partly_cloudy: 'weather-few-clouds-symbolic',
- partly_cloudy_night: 'weather-few-clouds-night-symbolic',
- cloudy: 'weather-overcast-symbolic',
- overcast: 'weather-overcast-symbolic',
- mist: 'weather-overcast-symbolic',
- patchy_rain_nearby: 'weather-showers-scattered-symbolic',
- patchy_rain_possible: 'weather-showers-scattered-symbolic',
- patchy_snow_possible: 'weather-snow-symbolic',
- patchy_sleet_possible: 'weather-snow-symbolic',
- patchy_freezing_drizzle_possible: 'weather-showers-scattered-symbolic',
- thundery_outbreaks_possible: 'weather-overcast-symbolic',
- blowing_snow: 'weather-snow-symbolic',
- blizzard: 'weather-snow-symbolic',
- fog: 'weather-fog-symbolic',
- freezing_fog: 'weather-fog-symbolic',
- patchy_light_drizzle: 'weather-showers-scattered-symbolic',
- light_drizzle: 'weather-showers-symbolic',
- freezing_drizzle: 'weather-showers-symbolic',
- heavy_freezing_drizzle: 'weather-showers-symbolic',
- patchy_light_rain: 'weather-showers-scattered-symbolic',
- light_rain: 'weather-showers-symbolic',
- moderate_rain_at_times: 'weather-showers-symbolic',
- moderate_rain: 'weather-showers-symbolic',
- heavy_rain_at_times: 'weather-showers-symbolic',
- heavy_rain: 'weather-showers-symbolic',
- light_freezing_rain: 'weather-showers-symbolic',
- moderate_or_heavy_freezing_rain: 'weather-showers-symbolic',
- light_sleet: 'weather-snow-symbolic',
- moderate_or_heavy_sleet: 'weather-snow-symbolic',
- patchy_light_snow: 'weather-snow-symbolic',
- light_snow: 'weather-snow-symbolic',
- patchy_moderate_snow: 'weather-snow-symbolic',
- moderate_snow: 'weather-snow-symbolic',
- patchy_heavy_snow: 'weather-snow-symbolic',
- heavy_snow: 'weather-snow-symbolic',
- ice_pellets: 'weather-showers-symbolic',
- light_rain_shower: 'weather-showers-symbolic',
- moderate_or_heavy_rain_shower: 'weather-showers-symbolic',
- torrential_rain_shower: 'weather-showers-symbolic',
- light_sleet_showers: 'weather-showers-symbolic',
- moderate_or_heavy_sleet_showers: 'weather-showers-symbolic',
- light_snow_showers: 'weather-snow-symbolic',
- moderate_or_heavy_snow_showers: 'weather-snow-symbolic',
- light_showers_of_ice_pellets: 'weather-showers-symbolic',
- moderate_or_heavy_showers_of_ice_pellets: 'weather-showers-symbolic',
- patchy_light_rain_with_thunder: 'weather-showers-scattered-symbolic',
- moderate_or_heavy_rain_with_thunder: 'weather-showers-symbolic',
- patchy_light_snow_with_thunder: 'weather-snow-symbolic',
- moderate_or_heavy_snow_with_thunder: 'weather-snow-symbolic',
- },
-} as const;
diff --git a/ags/HyprPanel/modules/icons/weather.ts b/ags/HyprPanel/modules/icons/weather.ts
deleted file mode 100644
index 90980a0..0000000
--- a/ags/HyprPanel/modules/icons/weather.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-export const weatherIcons = {
- warning: '',
- sunny: '',
- clear: '',
- partly_cloudy: '',
- partly_cloudy_night: '',
- cloudy: '',
- overcast: '',
- mist: '',
- patchy_rain_nearby: '',
- patchy_rain_possible: '',
- patchy_snow_possible: '',
- patchy_sleet_possible: '',
- patchy_freezing_drizzle_possible: '',
- thundery_outbreaks_possible: '',
- blowing_snow: '',
- blizzard: '',
- fog: '',
- freezing_fog: '',
- patchy_light_drizzle: '',
- light_drizzle: '',
- freezing_drizzle: '',
- heavy_freezing_drizzle: '',
- patchy_light_rain: '',
- light_rain: '',
- moderate_rain_at_times: '',
- moderate_rain: '',
- heavy_rain_at_times: '',
- heavy_rain: '',
- light_freezing_rain: '',
- moderate_or_heavy_freezing_rain: '',
- light_sleet: '',
- moderate_or_heavy_sleet: '',
- patchy_light_snow: '',
- light_snow: '',
- patchy_moderate_snow: '',
- moderate_snow: '',
- patchy_heavy_snow: '',
- heavy_snow: '',
- ice_pellets: '',
- light_rain_shower: '',
- moderate_or_heavy_rain_shower: '',
- torrential_rain_shower: '',
- light_sleet_showers: '',
- moderate_or_heavy_sleet_showers: '',
- light_snow_showers: '',
- moderate_or_heavy_snow_showers: '',
- light_showers_of_ice_pellets: '',
- moderate_or_heavy_showers_of_ice_pellets: '',
- patchy_light_rain_with_thunder: '',
- moderate_or_heavy_rain_with_thunder: '',
- patchy_light_snow_with_thunder: '',
- moderate_or_heavy_snow_with_thunder: '',
-} as const;
diff --git a/ags/HyprPanel/modules/menus/audio/active/SelectedInput.ts b/ags/HyprPanel/modules/menus/audio/active/SelectedInput.ts
deleted file mode 100644
index 4e3cff3..0000000
--- a/ags/HyprPanel/modules/menus/audio/active/SelectedInput.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-const audio = await Service.import('audio');
-import { getIcon } from '../utils.js';
-import Box from 'types/widgets/box.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-
-const renderActiveInput = (): Box[] => {
- return [
- Widget.Box({
- class_name: 'menu-slider-container input',
- children: [
- Widget.Button({
- vexpand: false,
- vpack: 'end',
- setup: (self) => {
- const updateClass = (): void => {
- const mic = audio.microphone;
- const className = `menu-active-button input ${mic.is_muted ? 'muted' : ''}`;
- self.class_name = className;
- };
-
- self.hook(audio.microphone, updateClass, 'notify::is-muted');
- },
- on_primary_click: () => (audio.microphone.is_muted = !audio.microphone.is_muted),
- child: Widget.Icon({
- class_name: 'menu-active-icon input',
- setup: (self) => {
- const updateIcon = (): void => {
- const isMicMuted =
- audio.microphone.is_muted !== null ? audio.microphone.is_muted : true;
-
- if (audio.microphone.volume > 0) {
- self.icon = getIcon(audio.microphone.volume, isMicMuted)['mic'];
- } else {
- self.icon = getIcon(100, true)['mic'];
- }
- };
- self.hook(audio.microphone, updateIcon, 'notify::volume');
- self.hook(audio.microphone, updateIcon, 'notify::is-muted');
- },
- }),
- }),
- Widget.Box({
- vertical: true,
- children: [
- Widget.Label({
- class_name: 'menu-active input',
- hpack: 'start',
- truncate: 'end',
- wrap: true,
- label: audio.bind('microphone').as((v) => {
- return v.description === null ? 'No input device found...' : v.description;
- }),
- }),
- Widget.Slider({
- value: audio.microphone.bind('volume').as((v) => v),
- class_name: 'menu-active-slider menu-slider inputs',
- draw_value: false,
- hexpand: true,
- min: 0,
- max: 1,
- onChange: ({ value }) => (audio.microphone.volume = value),
- }),
- ],
- }),
- Widget.Label({
- class_name: 'menu-active-percentage input',
- vpack: 'end',
- label: audio.microphone.bind('volume').as((v) => `${Math.round(v * 100)}%`),
- }),
- ],
- }),
- ];
-};
-
-export { renderActiveInput };
diff --git a/ags/HyprPanel/modules/menus/audio/active/SelectedPlayback.ts b/ags/HyprPanel/modules/menus/audio/active/SelectedPlayback.ts
deleted file mode 100644
index 29e5afd..0000000
--- a/ags/HyprPanel/modules/menus/audio/active/SelectedPlayback.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-const audio = await Service.import('audio');
-import { getIcon } from '../utils.js';
-import Box from 'types/widgets/box.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-
-const renderActivePlayback = (): Box[] => {
- return [
- Widget.Box({
- class_name: 'menu-slider-container playback',
- children: [
- Widget.Button({
- vexpand: false,
- vpack: 'end',
- setup: (self) => {
- const updateClass = (): void => {
- const spkr = audio.speaker;
- const className = `menu-active-button playback ${spkr.is_muted ? 'muted' : ''}`;
- self.class_name = className;
- };
-
- self.hook(audio.speaker, updateClass, 'notify::is-muted');
- },
- on_primary_click: () => (audio.speaker.is_muted = !audio.speaker.is_muted),
- child: Widget.Icon({
- class_name: 'menu-active-icon playback',
- setup: (self) => {
- const updateIcon = (): void => {
- const isSpeakerMuted = audio.speaker.is_muted !== null ? audio.speaker.is_muted : true;
- self.icon = getIcon(audio.speaker.volume, isSpeakerMuted)['spkr'];
- };
- self.hook(audio.speaker, updateIcon, 'notify::volume');
- self.hook(audio.speaker, updateIcon, 'notify::is-muted');
- },
- }),
- }),
- Widget.Box({
- vertical: true,
- children: [
- Widget.Label({
- class_name: 'menu-active playback',
- hpack: 'start',
- truncate: 'end',
- expand: true,
- wrap: true,
- label: audio.bind('speaker').as((v) => v.description || ''),
- }),
- Widget.Slider({
- value: audio['speaker'].bind('volume'),
- class_name: 'menu-active-slider menu-slider playback',
- draw_value: false,
- hexpand: true,
- min: 0,
- max: 1,
- onChange: ({ value }) => (audio.speaker.volume = value),
- }),
- ],
- }),
- Widget.Label({
- vpack: 'end',
- class_name: 'menu-active-percentage playback',
- label: audio.speaker.bind('volume').as((v) => `${Math.round(v * 100)}%`),
- }),
- ],
- }),
- ];
-};
-
-export { renderActivePlayback };
diff --git a/ags/HyprPanel/modules/menus/audio/active/index.ts b/ags/HyprPanel/modules/menus/audio/active/index.ts
deleted file mode 100644
index 9768ddb..0000000
--- a/ags/HyprPanel/modules/menus/audio/active/index.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { renderActiveInput } from './SelectedInput.js';
-import { renderActivePlayback } from './SelectedPlayback.js';
-import Box from 'types/widgets/box.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-
-const activeDevices = (): Box => {
- return Widget.Box({
- class_name: 'menu-section-container volume',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'menu-label-container volume selected',
- hpack: 'fill',
- child: Widget.Label({
- class_name: 'menu-label audio volume',
- hexpand: true,
- hpack: 'start',
- label: 'Volume',
- }),
- }),
- Widget.Box({
- class_name: 'menu-items-section selected',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'menu-active-container playback',
- vertical: true,
- children: renderActivePlayback(),
- }),
- Widget.Box({
- class_name: 'menu-active-container input',
- vertical: true,
- children: renderActiveInput(),
- }),
- ],
- }),
- ],
- });
-};
-
-export { activeDevices };
diff --git a/ags/HyprPanel/modules/menus/audio/available/InputDevices.ts b/ags/HyprPanel/modules/menus/audio/available/InputDevices.ts
deleted file mode 100644
index 8c75a5a..0000000
--- a/ags/HyprPanel/modules/menus/audio/available/InputDevices.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-const audio = await Service.import('audio');
-import { InputDevices } from 'lib/types/audio';
-import { Stream } from 'types/service/audio';
-
-const renderInputDevices = (inputDevices: Stream[]): InputDevices => {
- if (inputDevices.length === 0) {
- return [
- Widget.Button({
- class_name: `menu-unfound-button input`,
- child: Widget.Box({
- children: [
- Widget.Box({
- hpack: 'start',
- children: [
- Widget.Label({
- class_name: 'menu-button-name input',
- label: 'No input devices found...',
- }),
- ],
- }),
- ],
- }),
- }),
- ];
- }
- return inputDevices.map((device) => {
- return Widget.Button({
- on_primary_click: () => (audio.microphone = device),
- class_name: `menu-button audio input ${device}`,
- child: Widget.Box({
- children: [
- Widget.Box({
- hpack: 'start',
- children: [
- Widget.Label({
- wrap: true,
- class_name: audio.microphone
- .bind('description')
- .as((v) =>
- device.description === v
- ? 'menu-button-icon active input txt-icon'
- : 'menu-button-icon input txt-icon',
- ),
- label: '',
- }),
- Widget.Label({
- truncate: 'end',
- wrap: true,
- class_name: audio.microphone
- .bind('description')
- .as((v) =>
- device.description === v
- ? 'menu-button-name active input'
- : 'menu-button-name input',
- ),
- label: device.description,
- }),
- ],
- }),
- ],
- }),
- });
- });
-};
-
-export { renderInputDevices };
diff --git a/ags/HyprPanel/modules/menus/audio/available/PlaybackDevices.ts b/ags/HyprPanel/modules/menus/audio/available/PlaybackDevices.ts
deleted file mode 100644
index 02bc618..0000000
--- a/ags/HyprPanel/modules/menus/audio/available/PlaybackDevices.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-const audio = await Service.import('audio');
-import { PlaybackDevices } from 'lib/types/audio';
-import { Stream } from 'types/service/audio';
-
-const renderPlaybacks = (playbackDevices: Stream[]): PlaybackDevices => {
- return playbackDevices.map((device) => {
- if (device.description === 'Dummy Output') {
- return Widget.Box({
- class_name: 'menu-unfound-button playback',
- child: Widget.Box({
- children: [
- Widget.Label({
- class_name: 'menu-button-name playback',
- label: 'No playback devices found...',
- }),
- ],
- }),
- });
- }
- return Widget.Button({
- class_name: `menu-button audio playback ${device}`,
- on_primary_click: () => (audio.speaker = device),
- child: Widget.Box({
- children: [
- Widget.Box({
- hpack: 'start',
- children: [
- Widget.Label({
- truncate: 'end',
- wrap: true,
- class_name: audio.speaker
- .bind('description')
- .as((v) =>
- device.description === v
- ? 'menu-button-icon active playback txt-icon'
- : 'menu-button-icon playback txt-icon',
- ),
- label: '',
- }),
- Widget.Label({
- truncate: 'end',
- wrap: true,
- class_name: audio.speaker
- .bind('description')
- .as((v) =>
- device.description === v
- ? 'menu-button-name active playback'
- : 'menu-button-name playback',
- ),
- label: device.description,
- }),
- ],
- }),
- ],
- }),
- });
- });
-};
-
-export { renderPlaybacks };
diff --git a/ags/HyprPanel/modules/menus/audio/available/index.ts b/ags/HyprPanel/modules/menus/audio/available/index.ts
deleted file mode 100644
index e9b0d48..0000000
--- a/ags/HyprPanel/modules/menus/audio/available/index.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-const audio = await Service.import('audio');
-import { BoxWidget } from 'lib/types/widget.js';
-import { renderInputDevices } from './InputDevices.js';
-import { renderPlaybacks } from './PlaybackDevices.js';
-
-const availableDevices = (): BoxWidget => {
- return Widget.Box({
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'menu-section-container playback',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'menu-label-container playback',
- hpack: 'fill',
- child: Widget.Label({
- class_name: 'menu-label audio playback',
- hexpand: true,
- hpack: 'start',
- label: 'Playback Devices',
- }),
- }),
- Widget.Box({
- class_name: 'menu-items-section playback',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'menu-container playback',
- vertical: true,
- children: [
- Widget.Box({
- vertical: true,
- children: audio.bind('speakers').as((v) => renderPlaybacks(v)),
- }),
- ],
- }),
- ],
- }),
- Widget.Box({
- class_name: 'menu-label-container input',
- hpack: 'fill',
- child: Widget.Label({
- class_name: 'menu-label audio input',
- hexpand: true,
- hpack: 'start',
- label: 'Input Devices',
- }),
- }),
- Widget.Box({
- class_name: 'menu-items-section input',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'menu-container input',
- vertical: true,
- children: [
- Widget.Box({
- vertical: true,
- children: audio.bind('microphones').as((v) => renderInputDevices(v)),
- }),
- ],
- }),
- ],
- }),
- ],
- }),
- ],
- });
-};
-
-export { availableDevices };
diff --git a/ags/HyprPanel/modules/menus/audio/index.ts b/ags/HyprPanel/modules/menus/audio/index.ts
deleted file mode 100644
index 6801151..0000000
--- a/ags/HyprPanel/modules/menus/audio/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import Window from 'types/widgets/window.js';
-import DropdownMenu from '../shared/dropdown/index.js';
-import { activeDevices } from './active/index.js';
-import { availableDevices } from './available/index.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import options from 'options.js';
-
-export default (): Window => {
- return DropdownMenu({
- name: 'audiomenu',
- transition: options.menus.transition.bind('value'),
- child: Widget.Box({
- class_name: 'menu-items audio',
- hpack: 'fill',
- hexpand: true,
- child: Widget.Box({
- vertical: true,
- hpack: 'fill',
- hexpand: true,
- class_name: 'menu-items-container audio',
- children: [activeDevices(), availableDevices()],
- }),
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/audio/utils.ts b/ags/HyprPanel/modules/menus/audio/utils.ts
deleted file mode 100644
index aa1de5c..0000000
--- a/ags/HyprPanel/modules/menus/audio/utils.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-const speakerIcons = {
- 101: 'audio-volume-overamplified-symbolic',
- 66: 'audio-volume-high-symbolic',
- 34: 'audio-volume-medium-symbolic',
- 1: 'audio-volume-low-symbolic',
- 0: 'audio-volume-muted-symbolic',
-} as const;
-
-const inputIcons = {
- 101: 'microphone-sensitivity-high-symbolic',
- 66: 'microphone-sensitivity-high-symbolic',
- 34: 'microphone-sensitivity-medium-symbolic',
- 1: 'microphone-sensitivity-low-symbolic',
- 0: 'microphone-disabled-symbolic',
-};
-
-type IconVolumes = keyof typeof speakerIcons;
-
-const getIcon = (audioVol: number, isMuted: boolean): Record => {
- const thresholds: IconVolumes[] = [101, 66, 34, 1, 0];
- const icon = isMuted ? 0 : thresholds.find((threshold) => threshold <= audioVol * 100) || 0;
-
- return {
- spkr: speakerIcons[icon],
- mic: inputIcons[icon],
- };
-};
-
-export { getIcon };
diff --git a/ags/HyprPanel/modules/menus/bluetooth/devices/connectedControls.ts b/ags/HyprPanel/modules/menus/bluetooth/devices/connectedControls.ts
deleted file mode 100644
index 62e8345..0000000
--- a/ags/HyprPanel/modules/menus/bluetooth/devices/connectedControls.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { BoxWidget } from 'lib/types/widget';
-import { BluetoothDevice } from 'types/service/bluetooth';
-
-const connectedControls = (dev: BluetoothDevice, connectedDevices: BluetoothDevice[]): BoxWidget => {
- if (!connectedDevices.includes(dev.address)) {
- return Widget.Box({});
- }
-
- return Widget.Box({
- vpack: 'start',
- class_name: 'bluetooth-controls',
- children: [
- Widget.Button({
- class_name: 'menu-icon-button unpair bluetooth',
- child: Widget.Label({
- tooltip_text: dev.paired ? 'Unpair' : 'Pair',
- class_name: 'menu-icon-button-label unpair bluetooth txt-icon',
- label: dev.paired ? '' : '',
- }),
- on_primary_click: () =>
- Utils.execAsync([
- 'bash',
- '-c',
- `bluetoothctl ${dev.paired ? 'unpair' : 'pair'} ${dev.address}`,
- ]).catch((err) =>
- console.error(`bluetoothctl ${dev.paired ? 'unpair' : 'pair'} ${dev.address}`, err),
- ),
- }),
- Widget.Button({
- class_name: 'menu-icon-button disconnect bluetooth',
- child: Widget.Label({
- tooltip_text: dev.connected ? 'Disconnect' : 'Connect',
- class_name: 'menu-icon-button-label disconnect bluetooth txt-icon',
- label: dev.connected ? '' : '',
- }),
- on_primary_click: () => dev.setConnection(!dev.connected),
- }),
- Widget.Button({
- class_name: 'menu-icon-button untrust bluetooth',
- child: Widget.Label({
- tooltip_text: dev.trusted ? 'Untrust' : 'Trust',
- class_name: 'menu-icon-button-label untrust bluetooth txt-icon',
- label: dev.trusted ? '' : '',
- }),
- on_primary_click: () =>
- Utils.execAsync([
- 'bash',
- '-c',
- `bluetoothctl ${dev.trusted ? 'untrust' : 'trust'} ${dev.address}`,
- ]).catch((err) =>
- console.error(`bluetoothctl ${dev.trusted ? 'untrust' : 'trust'} ${dev.address}`, err),
- ),
- }),
- Widget.Button({
- class_name: 'menu-icon-button delete bluetooth',
- child: Widget.Label({
- tooltip_text: 'Forget',
- class_name: 'menu-icon-button-label delete bluetooth txt-icon',
- label: '',
- }),
- on_primary_click: () => {
- Utils.execAsync(['bash', '-c', `bluetoothctl remove ${dev.address}`]).catch((err) =>
- console.error('Bluetooth Remove', err),
- );
- },
- }),
- ],
- });
-};
-
-export { connectedControls };
diff --git a/ags/HyprPanel/modules/menus/bluetooth/devices/devicelist.ts b/ags/HyprPanel/modules/menus/bluetooth/devices/devicelist.ts
deleted file mode 100644
index e1fdcc9..0000000
--- a/ags/HyprPanel/modules/menus/bluetooth/devices/devicelist.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import { Bluetooth } from 'types/service/bluetooth.js';
-import Box from 'types/widgets/box.js';
-import { connectedControls } from './connectedControls.js';
-import { getBluetoothIcon } from '../utils.js';
-import Gtk from 'types/@girs/gtk-3.0/gtk-3.0.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-
-const devices = (bluetooth: Bluetooth, self: Box): Box => {
- return self.hook(bluetooth, () => {
- if (!bluetooth.enabled) {
- return (self.child = Widget.Box({
- class_name: 'bluetooth-items',
- vertical: true,
- expand: true,
- vpack: 'center',
- hpack: 'center',
- children: [
- Widget.Label({
- class_name: 'bluetooth-disabled dim',
- hexpand: true,
- label: 'Bluetooth is disabled',
- }),
- ],
- }));
- }
-
- const availableDevices = bluetooth.devices
- .filter((btDev) => btDev.name !== null)
- .sort((a, b) => {
- if (a.connected || a.paired) {
- return -1;
- }
-
- if (b.connected || b.paired) {
- return 1;
- }
-
- return b.name - a.name;
- });
-
- const conDevNames = availableDevices.filter((d) => d.connected || d.paired).map((d) => d.address);
-
- if (!availableDevices.length) {
- return (self.child = Widget.Box({
- class_name: 'bluetooth-items',
- vertical: true,
- expand: true,
- vpack: 'center',
- hpack: 'center',
- children: [
- Widget.Label({
- class_name: 'no-bluetooth-devices dim',
- hexpand: true,
- label: 'No devices currently found',
- }),
- Widget.Label({
- class_name: 'search-bluetooth-label dim',
- hexpand: true,
- label: "Press '' to search",
- }),
- ],
- }));
- }
-
- return (self.child = Widget.Box({
- vertical: true,
- children: availableDevices.map((device) => {
- return Widget.Box({
- children: [
- Widget.Button({
- hexpand: true,
- class_name: `bluetooth-element-item ${device}`,
- on_primary_click: () => {
- if (!conDevNames.includes(device.address)) device.setConnection(true);
- },
- child: Widget.Box({
- hexpand: true,
- children: [
- Widget.Box({
- hexpand: true,
- hpack: 'start',
- class_name: 'menu-button-container',
- children: [
- Widget.Label({
- vpack: 'start',
- class_name: `menu-button-icon bluetooth ${conDevNames.includes(device.address) ? 'active' : ''} txt-icon`,
- label: getBluetoothIcon(`${device['icon_name']}-symbolic`),
- }),
- Widget.Box({
- vertical: true,
- vpack: 'center',
- children: [
- Widget.Label({
- vpack: 'center',
- hpack: 'start',
- class_name: 'menu-button-name bluetooth',
- truncate: 'end',
- wrap: true,
- label: device.alias,
- }),
- Widget.Revealer({
- hpack: 'start',
- reveal_child: device.connected || device.paired,
- child: Widget.Label({
- hpack: 'start',
- class_name: 'connection-status dim',
- label: device.connected ? 'Connected' : 'Paired',
- }),
- }),
- ],
- }),
- ],
- }),
- Widget.Box({
- hpack: 'end',
- children: device.connecting
- ? [
- Widget.Spinner({
- vpack: 'start',
- class_name: 'spinner bluetooth',
- }),
- ]
- : [],
- }),
- ],
- }),
- }),
- connectedControls(device, conDevNames),
- ],
- });
- }),
- }));
- });
-};
-
-export { devices };
diff --git a/ags/HyprPanel/modules/menus/bluetooth/devices/index.ts b/ags/HyprPanel/modules/menus/bluetooth/devices/index.ts
deleted file mode 100644
index 31315d5..0000000
--- a/ags/HyprPanel/modules/menus/bluetooth/devices/index.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-const bluetooth = await Service.import('bluetooth');
-import { label } from './label.js';
-import { devices } from './devicelist.js';
-import { BoxWidget } from 'lib/types/widget.js';
-
-const Devices = (): BoxWidget => {
- return Widget.Box({
- class_name: 'menu-section-container',
- vertical: true,
- children: [
- label(bluetooth),
- Widget.Box({
- class_name: 'menu-items-section',
- child: Widget.Box({
- class_name: 'menu-content',
- vertical: true,
- setup: (self) => {
- devices(bluetooth, self);
- },
- }),
- }),
- ],
- });
-};
-
-export { Devices };
diff --git a/ags/HyprPanel/modules/menus/bluetooth/devices/label.ts b/ags/HyprPanel/modules/menus/bluetooth/devices/label.ts
deleted file mode 100644
index 45fabf6..0000000
--- a/ags/HyprPanel/modules/menus/bluetooth/devices/label.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { BoxWidget } from 'lib/types/widget';
-import { Bluetooth } from 'types/service/bluetooth';
-
-const label = (bluetooth: Bluetooth): BoxWidget => {
- const searchInProgress = Variable(false);
-
- const startRotation = (): void => {
- searchInProgress.value = true;
- setTimeout(() => {
- searchInProgress.value = false;
- }, 10 * 1000);
- };
-
- return Widget.Box({
- class_name: 'menu-label-container',
- hpack: 'fill',
- vpack: 'start',
- children: [
- Widget.Label({
- class_name: 'menu-label',
- vpack: 'center',
- hpack: 'start',
- label: 'Bluetooth',
- }),
- Widget.Box({
- class_name: 'controls-container',
- vpack: 'start',
- children: [
- Widget.Switch({
- class_name: 'menu-switch bluetooth',
- hexpand: true,
- hpack: 'end',
- active: bluetooth.bind('enabled'),
- on_activate: ({ active }) => {
- searchInProgress.value = false;
- Utils.execAsync(['bash', '-c', `bluetoothctl power ${active ? 'on' : 'off'}`]).catch(
- (err) => console.error(`bluetoothctl power ${active ? 'on' : 'off'}`, err),
- );
- },
- }),
- Widget.Separator({
- class_name: 'menu-separator bluetooth',
- }),
- Widget.Button({
- vpack: 'center',
- class_name: 'menu-icon-button search',
- on_primary_click: () => {
- startRotation();
- Utils.execAsync(['bash', '-c', 'bluetoothctl --timeout 120 scan on']).catch((err) => {
- searchInProgress.value = false;
- console.error('bluetoothctl --timeout 120 scan on', err);
- });
- },
- child: Widget.Icon({
- class_name: searchInProgress.bind('value').as((v) => (v ? 'spinning' : '')),
- icon: 'view-refresh-symbolic',
- }),
- }),
- ],
- }),
- ],
- });
-};
-
-export { label };
diff --git a/ags/HyprPanel/modules/menus/bluetooth/index.ts b/ags/HyprPanel/modules/menus/bluetooth/index.ts
deleted file mode 100644
index 54dfcad..0000000
--- a/ags/HyprPanel/modules/menus/bluetooth/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import Window from 'types/widgets/window.js';
-import DropdownMenu from '../shared/dropdown/index.js';
-import { Devices } from './devices/index.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import options from 'options.js';
-
-export default (): Window => {
- return DropdownMenu({
- name: 'bluetoothmenu',
- transition: options.menus.transition.bind('value'),
- child: Widget.Box({
- class_name: 'menu-items bluetooth',
- hpack: 'fill',
- hexpand: true,
- child: Widget.Box({
- vertical: true,
- hpack: 'fill',
- hexpand: true,
- class_name: 'menu-items-container bluetooth',
- child: Devices(),
- }),
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/bluetooth/utils.ts b/ags/HyprPanel/modules/menus/bluetooth/utils.ts
deleted file mode 100644
index c305538..0000000
--- a/ags/HyprPanel/modules/menus/bluetooth/utils.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-const getBluetoothIcon = (iconName: string): string => {
- const deviceIconMap = [
- ['^audio-card*', ''],
- ['^audio-headphones*', ''],
- ['^audio-headset*', ''],
- ['^audio-input*', ''],
- ['^audio-speakers*', ''],
- ['^bluetooth*', ''],
- ['^camera*', ''],
- ['^computer*', ''],
- ['^input-gaming*', ''],
- ['^input-keyboard*', ''],
- ['^input-mouse*', ''],
- ['^input-tablet*', ''],
- ['^media*', ''],
- ['^modem*', ''],
- ['^network*', ''],
- ['^phone*', ''],
- ['^printer*', ''],
- ['^scanner*', ''],
- ['^video-camera*', ''],
- ];
-
- const foundMatch = deviceIconMap.find((icon) => RegExp(icon[0]).test(iconName.toLowerCase()));
-
- return foundMatch ? foundMatch[1] : '';
-};
-
-export { getBluetoothIcon };
diff --git a/ags/HyprPanel/modules/menus/calendar/calendar.ts b/ags/HyprPanel/modules/menus/calendar/calendar.ts
deleted file mode 100644
index d2af59e..0000000
--- a/ags/HyprPanel/modules/menus/calendar/calendar.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { BoxWidget } from 'lib/types/widget';
-
-const CalendarWidget = (): BoxWidget => {
- return Widget.Box({
- class_name: 'calendar-menu-item-container calendar',
- hpack: 'fill',
- vpack: 'fill',
- expand: true,
- child: Widget.Box({
- class_name: 'calendar-container-box',
- child: Widget.Calendar({
- expand: true,
- hpack: 'fill',
- vpack: 'fill',
- class_name: 'calendar-menu-widget',
- showDayNames: true,
- showDetails: false,
- showHeading: true,
- }),
- }),
- });
-};
-
-export { CalendarWidget };
diff --git a/ags/HyprPanel/modules/menus/calendar/index.ts b/ags/HyprPanel/modules/menus/calendar/index.ts
deleted file mode 100644
index d3fecb8..0000000
--- a/ags/HyprPanel/modules/menus/calendar/index.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import DropdownMenu from 'modules/menus/shared/dropdown/index';
-import { TimeWidget } from './time/index';
-import { CalendarWidget } from './calendar';
-import { WeatherWidget } from './weather/index';
-import options from 'options';
-import Window from 'types/widgets/window';
-import { Attribute, Child } from 'lib/types/widget';
-
-const { enabled: weatherEnabled } = options.menus.clock.weather;
-
-export default (): Window => {
- return DropdownMenu({
- name: 'calendarmenu',
- transition: options.menus.transition.bind('value'),
- child: Widget.Box({
- class_name: 'calendar-menu-content',
- css: 'padding: 1px; margin: -1px;',
- vexpand: false,
- children: [
- Widget.Box({
- class_name: 'calendar-content-container',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'calendar-content-items',
- vertical: true,
- children: weatherEnabled.bind('value').as((isWeatherEnabled) => {
- return [TimeWidget(), CalendarWidget(), ...(isWeatherEnabled ? [WeatherWidget()] : [])];
- }),
- }),
- ],
- }),
- ],
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/time/index.ts b/ags/HyprPanel/modules/menus/calendar/time/index.ts
deleted file mode 100644
index 2cbb279..0000000
--- a/ags/HyprPanel/modules/menus/calendar/time/index.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { BoxWidget } from 'lib/types/widget';
-import options from 'options';
-
-const { military, hideSeconds } = options.menus.clock.time;
-
-const time = Variable('', {
- poll: [1000, 'date "+%I:%M:%S"'],
-});
-
-const period = Variable('', {
- poll: [1000, 'date "+%p"'],
-});
-
-const militaryTime = Variable('', {
- poll: [1000, 'date "+%H:%M:%S"'],
-});
-
-const TimeWidget = (): BoxWidget => {
- return Widget.Box({
- class_name: 'calendar-menu-item-container clock',
- hexpand: true,
- vpack: 'center',
- hpack: 'fill',
- child: Widget.Box({
- hexpand: true,
- vpack: 'center',
- hpack: 'center',
- class_name: 'clock-content-items',
- children: Utils.merge(
- [military.bind('value'), hideSeconds.bind('value')],
- (is24hr: boolean, hideSeconds: boolean) => {
- if (!is24hr) {
- return [
- Widget.Box({
- hpack: 'center',
- children: [
- Widget.Label({
- class_name: 'clock-content-time',
- label: hideSeconds ? time.bind().as((str) => str.slice(0, -3)) : time.bind(),
- }),
- ],
- }),
- Widget.Box({
- hpack: 'center',
- children: [
- Widget.Label({
- vpack: 'end',
- class_name: 'clock-content-period',
- label: period.bind(),
- }),
- ],
- }),
- ];
- }
-
- return [
- Widget.Box({
- hpack: 'center',
- children: [
- Widget.Label({
- class_name: 'clock-content-time',
- label: hideSeconds
- ? militaryTime.bind().as((str) => str.slice(0, -3))
- : militaryTime.bind(),
- }),
- ],
- }),
- ];
- },
- ),
- }),
- });
-};
-
-export { TimeWidget };
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/hourly/icon/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/hourly/icon/index.ts
deleted file mode 100644
index 2c636c1..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/hourly/icon/index.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Weather, WeatherIconTitle } from 'lib/types/weather.js';
-import { Variable } from 'types/variable.js';
-import { weatherIcons } from 'modules/icons/weather.js';
-import { isValidWeatherIconTitle } from 'globals/weather';
-import { BoxWidget } from 'lib/types/widget';
-import { getNextEpoch } from '../utils';
-
-export const HourlyIcon = (theWeather: Variable, hoursFromNow: number): BoxWidget => {
- const getIconQuery = (wthr: Weather): WeatherIconTitle => {
- const nextEpoch = getNextEpoch(wthr, hoursFromNow);
- const weatherAtEpoch = wthr.forecast.forecastday[0].hour.find((h) => h.time_epoch === nextEpoch);
-
- if (weatherAtEpoch === undefined) {
- return 'warning';
- }
-
- let iconQuery = weatherAtEpoch.condition.text.trim().toLowerCase().replaceAll(' ', '_');
-
- if (!weatherAtEpoch?.is_day && iconQuery === 'partly_cloudy') {
- iconQuery = 'partly_cloudy_night';
- }
-
- if (isValidWeatherIconTitle(iconQuery)) {
- return iconQuery;
- } else {
- return 'warning';
- }
- };
-
- return Widget.Box({
- hpack: 'center',
- child: theWeather.bind('value').as((w) => {
- const iconQuery = getIconQuery(w);
- const weatherIcn = weatherIcons[iconQuery] || weatherIcons['warning'];
-
- return Widget.Label({
- hpack: 'center',
- class_name: 'hourly-weather-icon txt-icon',
- label: weatherIcn,
- });
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/hourly/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/hourly/index.ts
deleted file mode 100644
index 0eb1982..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/hourly/index.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Weather } from 'lib/types/weather';
-import { Variable } from 'types/variable';
-import { HourlyIcon } from './icon/index.js';
-import { HourlyTemp } from './temperature/index.js';
-import { HourlyTime } from './time/index.js';
-import { BoxWidget } from 'lib/types/widget.js';
-
-export const Hourly = (theWeather: Variable): BoxWidget => {
- return Widget.Box({
- vertical: false,
- hexpand: true,
- hpack: 'fill',
- class_name: 'hourly-weather-container',
- children: [1, 2, 3, 4].map((hoursFromNow) => {
- return Widget.Box({
- class_name: 'hourly-weather-item',
- hexpand: true,
- vertical: true,
- children: [
- HourlyTime(theWeather, hoursFromNow),
- HourlyIcon(theWeather, hoursFromNow),
- HourlyTemp(theWeather, hoursFromNow),
- ],
- });
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/hourly/temperature/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/hourly/temperature/index.ts
deleted file mode 100644
index 440c994..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/hourly/temperature/index.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Weather } from 'lib/types/weather';
-import { Variable } from 'types/variable';
-import options from 'options';
-import Label from 'types/widgets/label';
-import { Child } from 'lib/types/widget';
-import { getNextEpoch } from '../utils';
-
-const { unit } = options.menus.clock.weather;
-
-export const HourlyTemp = (theWeather: Variable, hoursFromNow: number): Label => {
- return Widget.Label({
- class_name: 'hourly-weather-temp',
- label: Utils.merge([theWeather.bind('value'), unit.bind('value')], (wthr, unt) => {
- if (!Object.keys(wthr).length) {
- return '-';
- }
-
- const nextEpoch = getNextEpoch(wthr, hoursFromNow);
- const weatherAtEpoch = wthr.forecast.forecastday[0].hour.find((h) => h.time_epoch === nextEpoch);
-
- if (unt === 'imperial') {
- return `${weatherAtEpoch ? Math.ceil(weatherAtEpoch.temp_f) : '-'}° F`;
- }
- return `${weatherAtEpoch ? Math.ceil(weatherAtEpoch.temp_c) : '-'}° C`;
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/hourly/time/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/hourly/time/index.ts
deleted file mode 100644
index 717eac4..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/hourly/time/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Weather } from 'lib/types/weather';
-import { Child } from 'lib/types/widget';
-import { Variable } from 'types/variable';
-import Label from 'types/widgets/label';
-import { getNextEpoch } from '../utils';
-
-export const HourlyTime = (theWeather: Variable, hoursFromNow: number): Label => {
- return Widget.Label({
- class_name: 'hourly-weather-time',
- label: theWeather.bind('value').as((w) => {
- if (!Object.keys(w).length) {
- return '-';
- }
-
- const nextEpoch = getNextEpoch(w, hoursFromNow);
- const dateAtEpoch = new Date(nextEpoch * 1000);
- let hours = dateAtEpoch.getHours();
- const ampm = hours >= 12 ? 'PM' : 'AM';
- hours = hours % 12 || 12;
-
- return `${hours}${ampm}`;
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/hourly/utils.ts b/ags/HyprPanel/modules/menus/calendar/weather/hourly/utils.ts
deleted file mode 100644
index 13f1d53..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/hourly/utils.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Weather } from 'lib/types/weather';
-
-export const getNextEpoch = (wthr: Weather, hoursFromNow: number): number => {
- const currentEpoch = wthr.location.localtime_epoch;
- const epochAtHourStart = currentEpoch - (currentEpoch % 3600);
- let nextEpoch = 3600 * hoursFromNow + epochAtHourStart;
-
- const curHour = new Date(currentEpoch * 1000).getHours();
-
- /*
- * NOTE: Since the API is only capable of showing the current day; if
- * the hours left in the day are less than 4 (aka spilling into the next day),
- * then rewind to contain the prediction within the current day.
- */
- if (curHour > 19) {
- const hoursToRewind = curHour - 19;
- nextEpoch = 3600 * hoursFromNow + epochAtHourStart - hoursToRewind * 3600;
- }
- return nextEpoch;
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/icon/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/icon/index.ts
deleted file mode 100644
index dff981a..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/icon/index.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Weather } from 'lib/types/weather';
-import { Variable } from 'types/variable';
-import { getWeatherStatusTextIcon } from 'globals/weather.js';
-import { BoxWidget } from 'lib/types/widget';
-
-export const TodayIcon = (theWeather: Variable): BoxWidget => {
- return Widget.Box({
- vpack: 'center',
- hpack: 'start',
- class_name: 'calendar-menu-weather today icon container',
- child: Widget.Label({
- class_name: 'calendar-menu-weather today icon txt-icon',
- label: theWeather.bind('value').as((w) => {
- return getWeatherStatusTextIcon(w);
- }),
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/index.ts
deleted file mode 100644
index bf4a6bf..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/index.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { TodayIcon } from './icon/index.js';
-import { TodayStats } from './stats/index.js';
-import { TodayTemperature } from './temperature/index.js';
-import { Hourly } from './hourly/index.js';
-import { globalWeatherVar } from 'globals/weather.js';
-import { BoxWidget } from 'lib/types/widget.js';
-
-const WeatherWidget = (): BoxWidget => {
- return Widget.Box({
- class_name: 'calendar-menu-item-container weather',
- child: Widget.Box({
- class_name: 'weather-container-box',
- setup: (self) => {
- return (self.child = Widget.Box({
- vertical: true,
- hexpand: true,
- children: [
- Widget.Box({
- class_name: 'calendar-menu-weather today',
- hexpand: true,
- children: [
- TodayIcon(globalWeatherVar),
- TodayTemperature(globalWeatherVar),
- TodayStats(globalWeatherVar),
- ],
- }),
- Widget.Separator({
- class_name: 'menu-separator weather',
- }),
- Hourly(globalWeatherVar),
- ],
- }));
- },
- }),
- });
-};
-
-export { WeatherWidget };
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/stats/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/stats/index.ts
deleted file mode 100644
index 197032f..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/stats/index.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Weather } from 'lib/types/weather';
-import { Variable } from 'types/variable';
-import options from 'options';
-import { Unit } from 'lib/types/options';
-import { getRainChance, getWindConditions } from 'globals/weather';
-import { BoxWidget } from 'lib/types/widget';
-
-const { unit } = options.menus.clock.weather;
-
-export const TodayStats = (theWeather: Variable): BoxWidget => {
- return Widget.Box({
- class_name: 'calendar-menu-weather today stats container',
- hpack: 'end',
- vpack: 'center',
- vertical: true,
- children: [
- Widget.Box({
- class_name: 'weather wind',
- children: [
- Widget.Label({
- class_name: 'weather wind icon txt-icon',
- label: '',
- }),
- Widget.Label({
- class_name: 'weather wind label',
- label: Utils.merge(
- [theWeather.bind('value'), unit.bind('value')],
- (wthr: Weather, unt: Unit) => {
- return getWindConditions(wthr, unt);
- },
- ),
- }),
- ],
- }),
- Widget.Box({
- class_name: 'weather precip',
- children: [
- Widget.Label({
- class_name: 'weather precip icon txt-icon',
- label: '',
- }),
- Widget.Label({
- class_name: 'weather precip label',
- label: theWeather.bind('value').as((v) => getRainChance(v)),
- }),
- ],
- }),
- ],
- });
-};
diff --git a/ags/HyprPanel/modules/menus/calendar/weather/temperature/index.ts b/ags/HyprPanel/modules/menus/calendar/weather/temperature/index.ts
deleted file mode 100644
index 597a75c..0000000
--- a/ags/HyprPanel/modules/menus/calendar/weather/temperature/index.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Weather } from 'lib/types/weather';
-import { Variable } from 'types/variable';
-import options from 'options';
-import { getTemperature, getWeatherIcon } from 'globals/weather';
-import { BoxWidget } from 'lib/types/widget';
-const { unit } = options.menus.clock.weather;
-
-export const TodayTemperature = (theWeather: Variable): BoxWidget => {
- return Widget.Box({
- hpack: 'center',
- vpack: 'center',
- vertical: true,
- children: [
- Widget.Box({
- hexpand: true,
- vpack: 'center',
- class_name: 'calendar-menu-weather today temp container',
- vertical: false,
- children: [
- Widget.Box({
- hexpand: true,
- hpack: 'center',
- children: [
- Widget.Label({
- class_name: 'calendar-menu-weather today temp label',
- label: Utils.merge([theWeather.bind('value'), unit.bind('value')], (wthr, unt) => {
- return getTemperature(wthr, unt);
- }),
- }),
- Widget.Label({
- class_name: theWeather
- .bind('value')
- .as(
- (v) =>
- `calendar-menu-weather today temp label icon txt-icon ${getWeatherIcon(Math.ceil(v.current.temp_f)).color}`,
- ),
- label: theWeather
- .bind('value')
- .as((v) => getWeatherIcon(Math.ceil(v.current.temp_f)).icon),
- }),
- ],
- }),
- ],
- }),
- Widget.Box({
- hpack: 'center',
- child: Widget.Label({
- max_width_chars: 17,
- truncate: 'end',
- lines: 2,
- class_name: theWeather
- .bind('value')
- .as(
- (v) =>
- `calendar-menu-weather today condition label ${getWeatherIcon(Math.ceil(v.current.temp_f)).color}`,
- ),
- label: theWeather.bind('value').as((v) => v.current.condition.text),
- }),
- }),
- ],
- });
-};
diff --git a/ags/HyprPanel/modules/menus/dashboard/controls/index.ts b/ags/HyprPanel/modules/menus/dashboard/controls/index.ts
deleted file mode 100644
index e158f96..0000000
--- a/ags/HyprPanel/modules/menus/dashboard/controls/index.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { BoxWidget } from 'lib/types/widget';
-
-const network = await Service.import('network');
-const bluetooth = await Service.import('bluetooth');
-const notifications = await Service.import('notifications');
-const audio = await Service.import('audio');
-
-const Controls = (): BoxWidget => {
- return Widget.Box({
- class_name: 'dashboard-card controls-container',
- hpack: 'fill',
- vpack: 'fill',
- expand: true,
- children: [
- Widget.Button({
- tooltip_text: 'Toggle Wifi',
- expand: true,
- setup: (self) => {
- self.hook(network, () => {
- return (self.class_name = `dashboard-button wifi ${!network.wifi.enabled ? 'disabled' : ''}`);
- });
- },
- on_primary_click: () => network.toggleWifi(),
- child: Widget.Label({
- class_name: 'txt-icon',
- setup: (self) => {
- self.hook(network, () => {
- return (self.label = network.wifi.enabled ? '' : '');
- });
- },
- }),
- }),
- Widget.Button({
- tooltip_text: 'Toggle Bluetooth',
- expand: true,
- class_name: bluetooth
- .bind('enabled')
- .as((btOn) => `dashboard-button bluetooth ${!btOn ? 'disabled' : ''}`),
- on_primary_click: () => bluetooth.toggle(),
- child: Widget.Label({
- class_name: 'txt-icon',
- label: bluetooth.bind('enabled').as((btOn) => (btOn ? '' : '')),
- }),
- }),
- Widget.Button({
- tooltip_text: 'Toggle Notifications',
- expand: true,
- class_name: notifications
- .bind('dnd')
- .as((dnd) => `dashboard-button notifications ${dnd ? 'disabled' : ''}`),
- on_primary_click: () => (notifications.dnd = !notifications.dnd),
- child: Widget.Label({
- class_name: 'txt-icon',
- label: notifications.bind('dnd').as((dnd) => (dnd ? '' : '')),
- }),
- }),
- Widget.Button({
- tooltip_text: 'Toggle Mute (Playback)',
- expand: true,
- on_primary_click: () => (audio.speaker.is_muted = !audio.speaker.is_muted),
- setup: (self) => {
- self.hook(
- audio.speaker,
- () => {
- return (self.class_name = `dashboard-button playback ${audio.speaker.is_muted ? 'disabled' : ''}`);
- },
- 'notify::is-muted',
- );
- },
- child: Widget.Label({
- class_name: 'txt-icon',
- setup: (self) => {
- self.hook(
- audio.speaker,
- () => {
- return (self.label = audio.speaker.is_muted ? '' : '');
- },
- 'notify::is-muted',
- );
- },
- }),
- }),
- Widget.Button({
- tooltip_text: 'Toggle Mute (Microphone)',
- expand: true,
- on_primary_click: () => (audio.microphone.is_muted = !audio.microphone.is_muted),
- setup: (self) => {
- self.hook(
- audio.microphone,
- () => {
- return (self.class_name = `dashboard-button input ${audio.microphone.is_muted ? 'disabled' : ''}`);
- },
- 'notify::is-muted',
- );
- },
- child: Widget.Label({
- class_name: 'txt-icon',
- setup: (self) => {
- self.hook(
- audio.microphone,
- () => {
- return (self.label = audio.microphone.is_muted ? '' : '');
- },
- 'notify::is-muted',
- );
- },
- }),
- }),
- ],
- });
-};
-
-export { Controls };
diff --git a/ags/HyprPanel/modules/menus/dashboard/directories/index.ts b/ags/HyprPanel/modules/menus/dashboard/directories/index.ts
deleted file mode 100644
index 5b6aa11..0000000
--- a/ags/HyprPanel/modules/menus/dashboard/directories/index.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import { BoxWidget } from 'lib/types/widget';
-import options from 'options';
-
-const { left, right } = options.menus.dashboard.directories;
-
-const Directories = (): BoxWidget => {
- return Widget.Box({
- class_name: 'dashboard-card directories-container',
- vpack: 'fill',
- hpack: 'fill',
- expand: true,
- children: [
- Widget.Box({
- vertical: true,
- expand: true,
- class_name: 'section right',
- children: [
- Widget.Button({
- hpack: 'start',
- expand: true,
- class_name: 'directory-link left top',
- on_primary_click: left.directory1.command.bind('value').as((cmd) => {
- return () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(cmd);
- };
- }),
- child: Widget.Label({
- hpack: 'start',
- label: left.directory1.label.bind('value'),
- }),
- }),
- Widget.Button({
- expand: true,
- hpack: 'start',
- class_name: 'directory-link left middle',
- on_primary_click: left.directory2.command.bind('value').as((cmd) => {
- return () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(cmd);
- };
- }),
- child: Widget.Label({
- hpack: 'start',
- label: left.directory2.label.bind('value'),
- }),
- }),
- Widget.Button({
- expand: true,
- hpack: 'start',
- class_name: 'directory-link left bottom',
- on_primary_click: left.directory3.command.bind('value').as((cmd) => {
- return () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(cmd);
- };
- }),
- child: Widget.Label({
- hpack: 'start',
- label: left.directory3.label.bind('value'),
- }),
- }),
- ],
- }),
- Widget.Box({
- vertical: true,
- expand: true,
- class_name: 'section left',
- children: [
- Widget.Button({
- hpack: 'start',
- expand: true,
- class_name: 'directory-link right top',
- on_primary_click: right.directory1.command.bind('value').as((cmd) => {
- return () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(cmd);
- };
- }),
- child: Widget.Label({
- hpack: 'start',
- label: right.directory1.label.bind('value'),
- }),
- }),
- Widget.Button({
- expand: true,
- hpack: 'start',
- class_name: 'directory-link right middle',
- on_primary_click: right.directory2.command.bind('value').as((cmd) => {
- return () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(cmd);
- };
- }),
- child: Widget.Label({
- hpack: 'start',
- label: right.directory2.label.bind('value'),
- }),
- }),
- Widget.Button({
- expand: true,
- hpack: 'start',
- class_name: 'directory-link right bottom',
- on_primary_click: right.directory3.command.bind('value').as((cmd) => {
- return () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(cmd);
- };
- }),
- child: Widget.Label({
- hpack: 'start',
- label: right.directory3.label.bind('value'),
- }),
- }),
- ],
- }),
- ],
- });
-};
-
-export { Directories };
diff --git a/ags/HyprPanel/modules/menus/dashboard/index.ts b/ags/HyprPanel/modules/menus/dashboard/index.ts
deleted file mode 100644
index 9bac607..0000000
--- a/ags/HyprPanel/modules/menus/dashboard/index.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import DropdownMenu from '../shared/dropdown/index.js';
-import { Profile } from './profile/index.js';
-import { Shortcuts } from './shortcuts/index.js';
-import { Controls } from './controls/index.js';
-import { Stats } from './stats/index.js';
-import { Directories } from './directories/index.js';
-import Window from 'types/widgets/window.js';
-import { Attribute, Child } from 'lib/types/widget.js';
-import options from 'options.js';
-
-const { controls, shortcuts, stats, directories } = options.menus.dashboard;
-
-export default (): Window => {
- return DropdownMenu({
- name: 'dashboardmenu',
- transition: options.menus.transition.bind('value'),
- child: Widget.Box({
- class_name: 'dashboard-menu-content',
- css: 'padding: 1px; margin: -1px;',
- vexpand: false,
- children: [
- Widget.Box({
- class_name: 'dashboard-content-container',
- vertical: true,
- children: Utils.merge(
- [
- controls.enabled.bind('value'),
- shortcuts.enabled.bind('value'),
- stats.enabled.bind('value'),
- directories.enabled.bind('value'),
- ],
- (isControlsEnabled, isShortcutsEnabled, isStatsEnabled, isDirectoriesEnabled) => {
- return [
- Widget.Box({
- class_name: 'dashboard-content-items',
- vertical: true,
- children: [
- Profile(),
- ...(isShortcutsEnabled ? [Shortcuts()] : []),
- ...(isControlsEnabled ? [Controls()] : []),
- ...(isDirectoriesEnabled ? [Directories()] : []),
- ...(isStatsEnabled ? [Stats()] : []),
- ],
- }),
- ];
- },
- ),
- }),
- ],
- }),
- });
-};
diff --git a/ags/HyprPanel/modules/menus/dashboard/profile/index.ts b/ags/HyprPanel/modules/menus/dashboard/profile/index.ts
deleted file mode 100644
index 9d2531a..0000000
--- a/ags/HyprPanel/modules/menus/dashboard/profile/index.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import powermenu from '../../power/helpers/actions.js';
-import { PowerOptions } from 'lib/types/options.js';
-import GdkPixbuf from 'gi://GdkPixbuf';
-
-import options from 'options';
-import { BoxWidget, Child } from 'lib/types/widget.js';
-import Label from 'types/widgets/label.js';
-const { image, name } = options.menus.dashboard.powermenu.avatar;
-const { confirmation, shutdown, logout, sleep, reboot } = options.menus.dashboard.powermenu;
-
-const Profile = (): BoxWidget => {
- const handleClick = (action: PowerOptions): void => {
- const actions = {
- shutdown: shutdown.value,
- reboot: reboot.value,
- logout: logout.value,
- sleep: sleep.value,
- };
- App.closeWindow('dashboardmenu');
-
- if (!confirmation.value) {
- Utils.execAsync(actions[action]).catch((err) =>
- console.error(`Failed to execute ${action} command. Error: ${err}`),
- );
- } else {
- powermenu.action(action);
- }
- };
-
- const getIconForButton = (txtIcon: string): Label => {
- return Widget.Label({
- className: 'txt-icon',
- label: txtIcon,
- });
- };
-
- return Widget.Box({
- class_name: 'profiles-container',
- hpack: 'fill',
- hexpand: true,
- children: [
- Widget.Box({
- class_name: 'profile-picture-container dashboard-card',
- hexpand: true,
- vertical: true,
- children: [
- Widget.Box({
- hpack: 'center',
- class_name: 'profile-picture',
- css: image.bind('value').as((i) => {
- try {
- GdkPixbuf.Pixbuf.new_from_file(i);
- return `background-image: url("${i}")`;
- } catch {
- return `background-image: url("${App.configDir}/assets/hyprpanel.png")`;
- }
- }),
- }),
- Widget.Label({
- hpack: 'center',
- class_name: 'profile-name',
- label: name.bind('value').as((v) => {
- if (v === 'system') {
- return Utils.exec('bash -c whoami');
- }
- return v;
- }),
- }),
- ],
- }),
- Widget.Box({
- class_name: 'power-menu-container dashboard-card',
- vertical: true,
- vexpand: true,
- children: [
- Widget.Button({
- class_name: 'dashboard-button shutdown',
- on_clicked: () => handleClick('shutdown'),
- tooltip_text: 'Shut Down',
- vexpand: true,
- child: getIconForButton(''),
- }),
- Widget.Button({
- class_name: 'dashboard-button restart',
- on_clicked: () => handleClick('reboot'),
- tooltip_text: 'Restart',
- vexpand: true,
- child: getIconForButton(''),
- }),
- Widget.Button({
- class_name: 'dashboard-button lock',
- on_clicked: () => handleClick('logout'),
- tooltip_text: 'Log Out',
- vexpand: true,
- child: getIconForButton(''),
- }),
- Widget.Button({
- class_name: 'dashboard-button sleep',
- on_clicked: () => handleClick('sleep'),
- tooltip_text: 'Sleep',
- vexpand: true,
- child: getIconForButton(''),
- }),
- ],
- }),
- ],
- });
-};
-
-export { Profile };
diff --git a/ags/HyprPanel/modules/menus/dashboard/shortcuts/index.ts b/ags/HyprPanel/modules/menus/dashboard/shortcuts/index.ts
deleted file mode 100644
index 5b4f49c..0000000
--- a/ags/HyprPanel/modules/menus/dashboard/shortcuts/index.ts
+++ /dev/null
@@ -1,317 +0,0 @@
-const hyprland = await Service.import('hyprland');
-import { Attribute, BoxWidget, Child } from 'lib/types/widget';
-import options from 'options';
-import { Variable as VarType } from 'types/variable';
-import Box from 'types/widgets/box';
-import Button from 'types/widgets/button';
-import Label from 'types/widgets/label';
-
-const { left, right } = options.menus.dashboard.shortcuts;
-
-const Shortcuts = (): BoxWidget => {
- const isRecording = Variable(false, {
- poll: [
- 1000,
- `${App.configDir}/services/screen_record.sh status`,
- (out): boolean => {
- if (out === 'recording') {
- return true;
- }
- return false;
- },
- ],
- });
- const handleClick = (action: string, tOut: number = 250): void => {
- App.closeWindow('dashboardmenu');
-
- setTimeout(() => {
- Utils.execAsync(action)
- .then((res) => {
- return res;
- })
- .catch((err) => err);
- }, tOut);
- };
-
- const recordingDropdown = Widget.Menu({
- class_name: 'dropdown recording',
- hpack: 'fill',
- hexpand: true,
- setup: (self) => {
- const renderMonitorList = (): void => {
- const displays = hyprland.monitors.map((mon) => {
- return Widget.MenuItem({
- label: `Display ${mon.name}`,
- on_activate: () => {
- App.closeWindow('dashboardmenu');
- Utils.execAsync(`${App.configDir}/services/screen_record.sh start ${mon.name}`).catch(
- (err) => console.error(err),
- );
- },
- });
- });
-
- // NOTE: This is disabled since window recording isn't available on wayland
- // const apps = hyprland.clients.map((clt) => {
- // return Widget.MenuItem({
- // label: `${clt.class.charAt(0).toUpperCase() + clt.class.slice(1)} (Workspace ${clt.workspace.name})`,
- // on_activate: () => {
- // App.closeWindow('dashboardmenu');
- // Utils.execAsync(
- // `${App.configDir}/services/screen_record.sh start ${clt.focusHistoryID}`,
- // ).catch((err) => console.error(err));
- // },
- // });
- // });
-
- self.children = [
- ...displays,
- // Disabled since window recording isn't available on wayland
- // ...apps
- ];
- };
- self.hook(hyprland, renderMonitorList, 'monitor-added');
- self.hook(hyprland, renderMonitorList, 'monitor-removed');
- },
- });
-
- type ShortcutFixed = {
- tooltip: string;
- command: string;
- icon: string;
- configurable: false;
- };
-
- type ShortcutVariable = {
- tooltip: VarType;
- command: VarType;
- icon: VarType;
- configurable?: true;
- };
-
- type Shortcut = ShortcutFixed | ShortcutVariable;
-
- const cmdLn = (sCut: ShortcutVariable): boolean => {
- return sCut.command.value.length > 0;
- };
-
- const leftCardHidden = Variable(
- !(cmdLn(left.shortcut1) || cmdLn(left.shortcut2) || cmdLn(left.shortcut3) || cmdLn(left.shortcut4)),
- );
-
- const createButton = (shortcut: Shortcut, className: string): Button