diff --git a/.editorconfig b/.editorconfig
index 0a51807d3..4af9e4943 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,7 +1,39 @@
root = true
[*]
+charset = utf-8
end_of_line = lf
+indent_style = tab
+indent_size = 4
insert_final_newline = true
+tab_width = 4
+trim_trailing_whitespace = false
+
+[*.md]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = false
+
+[*.{nix,yml,yaml}]
indent_style = space
-indent_size = 2
\ No newline at end of file
+indent_size = 2
+tab_width = 2
+
+[*.yuck]
+indent_style = spaces
+indent_size = 4
+
+[*.{js, sh}]
+indent_style = spaces
+indent_size = 2
+
+[*.{diff,patch}]
+end_of_line = unset
+insert_final_newline = unset
+trim_trailing_whitespace = unset
+
+[secrets.yaml]
+indent_size = unset
+
+[*.lock]
+indent_size = unset
diff --git a/.envrc b/.envrc
index 3550a30f2..30fa1673f 100644
--- a/.envrc
+++ b/.envrc
@@ -1 +1,2 @@
use flake
+export DIRENV_WARN_TIMEOUT=5m
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..ff3caea67
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+flake/templates/* linguist-vendored
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 28205a28a..f14a2817b 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @isabelroses
\ No newline at end of file
+* @isabelroses
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..e69de29bb
diff --git a/.github/README.md b/.github/README.md
index 7de9aef82..cec7ad84a 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -10,40 +10,45 @@
### config layout
-- 🏠 [home](../home)
+- 🏠 [home](../home/)
- 🖥️ [hosts](../hosts/)
- - 🐉 [hydra](../hosts/hydra/) A super mid spec laptop
- ☀️ [amatarasu](../hosts/amatarasu/) My high end gameing machine
+ - 👴 [bernie](../hosts/bernie/) A server configuration for some of my infastrucior
+ - 🇧[beta](../hosts/beta/) A consept configuration for a new local server
+ - 🐉 [hydra](../hosts/hydra/) A super mid spec laptop
+ - ⚸ [lilith](../hosts/lilith/) A nixos iso image that can be qickly deployed and acessed via ssh
+- 📖 [lib](../lib/) Useful repeated functions
+- 🧩 [parts](../parts/) Nixos parts breaking down the complex confiuration into smaller more managable chuncks
- 🔌 [modules](../modules/)
- [common](../modules/common/) Common configuration settings
- [core](../modules/common/core/) Core parts of the configuration
- - [options](../modules/common/options/) Selecteable settings that can be used to toggle certain settings
- - [system](../modules/common/system/) System configurations
+ - [secrets](../modules/common/secrets/) Sops secured system secrets
+ - [types](../modules/common/types/) System type configurations (e.g. laptop, servers, desktop)
- [extra](../modules/extra/) Prebuilt configrations & spare parts
- - [desktop](../modules/extra/desktop/) Default desktop config
- - [server](../modules/extra/server/) Deafult server config
- - [virtualization](../modules/extra/virtualization/) Settings for virtualization
+ - [options](../modules/common/options/) Selecteable settings that can be used to toggle certain settings
Hyprland Shortcuts
-| Shortcut | What it does |
-|---|---|
-| SUPER+RETURN | open terminal |
-| SUPER+B | open browser |
-| SUPER+C | open editor |
-| SUPER+O | open notes |
-| SUPER+E | open file manager |
-| SUPER+Q | quit |
-| SUPER+D | launcher |
-| SUPER+F | fullscreen |
-| SUPER+[number] | open workspace [number] |
+| Shortcut | What it does |
+| ------------------------------- | -------------------------- |
+| SUPER+RETURN | open terminal |
+| SUPER+B | open browser |
+| SUPER+C | open editor |
+| SUPER+O | open notes |
+| SUPER+E | open file manager |
+| SUPER+Q | quit |
+| SUPER+D | launcher |
+| SUPER+F | fullscreen |
+| SUPER+[number] | open workspace [number] |
| SUPER+SHIFT+[number] | move to workspace [number] |
### credits
-- [numtide/srvos](https://github.com/numtide/srvos)
-- [nullishamy](https://github.com/nullishamy/derivation-station/)
-- [nekowinston](https://github.com/nekowinston/dotfiles)
+- [NotAShelf](https://github.com/notashelf/nyx) - The carry (and basicly half this repo)
+- [numtide/srvos](https://github.com/numtide/srvos) - Server stuff
+- [nullishamy](https://github.com/nullishamy/derivation-station) - Home-Manager Stuff
+- [nekowinston](https://github.com/nekowinston/dotfiles) - Basicly answers all my questions
+- [getchoo](https://github.com/getchoo) - For several things here and there
diff --git a/.github/assets/flake.svg b/.github/assets/flake.svg
index 443f9d863..f71e2ca5c 100644
--- a/.github/assets/flake.svg
+++ b/.github/assets/flake.svg
@@ -1,48 +1,48 @@
-
-
+
+
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..f5a0afc56
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: "/"
+ schedule:
+ interval: daily
+ time: "03:00"
+ open-pull-requests-limit: 10
+ reviewers:
+ - isabelroses
+ assignees:
+ - isabelroses
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..4a98566e2
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,57 @@
+name: Build and populate cache
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ paths-ignore:
+ - .github/**
+ - assets/**
+ - .gitignore
+ - docs/**
+ - README.md
+ schedule:
+ - cron: "25 1 * * *"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ package:
+ - bellado
+ - catppuccinifier-cli
+ - lutgen-rs
+ - patched-gjs
+ - ags
+ - plymouth-theme-catppuccin
+
+ steps:
+ - uses: easimon/maximize-build-space@v8
+ with:
+ overprovision-lvm: true
+ remove-android: true
+ remove-dotnet: true
+ remove-haskell: true
+
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install Nix
+ uses: DeterminateSystems/nix-installer-action@main
+ with:
+ logger: pretty
+
+ - name: Setup cachix
+ uses: cachix/cachix-action@v12
+ with:
+ name: isabelroses
+ signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}"
+ authToken: "${{ secrets.CACHIX_TOKEN }}"
+
+ - name: Set default git branch (to reduce log spam)
+ run: git config --global init.defaultBranch main
+
+ - name: Build from the matrix
+ run: nix build -L .#${{ matrix.package }}
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 64ec2a055..4ac157061 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -1,19 +1,25 @@
-name: Nix Flake Check
+name: Validate Nix Flake
-on: [push, pull_request, workflow_dispatch]
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - "**.nix"
+ - "**.lock"
+ - ".github/workflows/check.yml"
jobs:
- checks:
- name: Check expressions
+ check-flake:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: cachix/install-nix-action@v18
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install Nix
+ uses: DeterminateSystems/nix-installer-action@main
with:
- install_url: https://nixos.org/nix/install
- extra_nix_config: |
- auto-optimise-store = true
- experimental-features = nix-command flakes
- access-tokens = ${{ secrets.AUTH_TOKEN }}
- - run: nix flake check
+ logger: pretty
+
+ - name: Check Flake
+ run: nix flake check --accept-flake-config
diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml
index af72b8fc2..0950c0b41 100644
--- a/.github/workflows/fmt.yml
+++ b/.github/workflows/fmt.yml
@@ -1,18 +1,17 @@
-name: Formatting Check
+name: Validate Flake Formatting
-on: [push, pull_request, workflow_dispatch]
+on: [push, workflow_dispatch]
jobs:
- checks:
- name: Check expressions
+ check-formatting:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: cachix/install-nix-action@v18
+ - uses: actions/checkout@v4
+
+ - name: Install Nix
+ uses: DeterminateSystems/nix-installer-action@main
with:
- install_url: https://nixos.org/nix/install
- extra_nix_config: |
- auto-optimise-store = true
- experimental-features = nix-command flakes
+ logger: pretty
+ github_access_token: ${{ secrets.GITHUB_TOKEN }}
- run: nix run nixpkgs#alejandra -- -c .
diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml
new file mode 100644
index 000000000..ccb7bda4b
--- /dev/null
+++ b/.github/workflows/update.yml
@@ -0,0 +1,29 @@
+name: Bump Flake Inputs
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "0 0 * * *"
+
+jobs:
+ update-lockfile:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4.1.0
+
+ - name: Install Nix
+ uses: DeterminateSystems/nix-installer-action@main
+ with:
+ logger: pretty
+
+ - name: Update Lockfile
+ uses: DeterminateSystems/update-flake-lock@main
+ id: update
+ with:
+ pr-title: "CI: bump flake inputs"
+
+ - name: Merge Changes
+ run: |
+ gh pr merge ${{ steps.update.outputs.pull-request-number }} --squash --delete-branch
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 4812d58f9..659459369 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,6 @@
+# Ingore nixos build outputs
result
.direnv/
+
+# Ignore pre-commit config
+.pre-commit-config.yaml
diff --git a/.sops.yaml b/.sops.yaml
index 016116f86..5702ab68d 100755
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -3,5 +3,5 @@ keys:
creation_rules:
- path_regex: modules/common/secrets/[^/]+\.yaml$
- key_groups:
- - age:
- - *isabel
+ - age:
+ - *isabel
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 000000000..fcd63736d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Isabel
+
+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/flake.lock b/flake.lock
index 014322523..0bfcbb00d 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,18 +2,16 @@
"nodes": {
"ags": {
"inputs": {
- "dongsu8142-nur": "dongsu8142-nur",
"nixpkgs": [
- "bella-nur",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1692814506,
- "narHash": "sha256-hSoT3iT5uW7P/H2Z9JsOqvqcV7SezlXUELJ7yvBL+rg=",
+ "lastModified": 1698179569,
+ "narHash": "sha256-CrOXArJ4+pSUmx9NsM69ATBVkJVCEccqO2ZIEwcji04=",
"owner": "Aylur",
"repo": "ags",
- "rev": "b02412c7c39ce3d82d6825be98601b3dfe372da8",
+ "rev": "1229e8847f6331e5f7ab47a9474a8822d062134f",
"type": "github"
},
"original": {
@@ -22,23 +20,57 @@
"type": "github"
}
},
- "bella-nur": {
+ "alpha-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1689470865,
+ "narHash": "sha256-wgjYus4XlJ0GoQWTo5gf7yyKYhseOXKOqUXEiwXpEJQ=",
+ "owner": "goolord",
+ "repo": "alpha-nvim",
+ "rev": "e4fc5e29b731bdf55d204c5c6a11dc3be70f3b65",
+ "type": "github"
+ },
+ "original": {
+ "owner": "goolord",
+ "repo": "alpha-nvim",
+ "type": "github"
+ }
+ },
+ "auto-cpufreq": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1698113985,
+ "narHash": "sha256-nuSj6m50eRAB7d/tngmWUb47J+HMpLlDlzPYHNh5DD4=",
+ "owner": "AdnanHodzic",
+ "repo": "auto-cpufreq",
+ "rev": "d3760eaf37468a33d90b2e812bfcf6de06711a94",
+ "type": "github"
+ },
+ "original": {
+ "owner": "AdnanHodzic",
+ "repo": "auto-cpufreq",
+ "type": "github"
+ }
+ },
+ "bellado": {
"inputs": {
- "ags": "ags",
- "catppuccinifier": "catppuccinifier",
"nixpkgs": "nixpkgs"
},
"locked": {
- "lastModified": 1692860477,
- "narHash": "sha256-7TheFw61jYwyZeqlia//yGvXiJOp7U3SvLPuIe2JQ2w=",
+ "lastModified": 1696727195,
+ "narHash": "sha256-R+4eaviYu0SrW9xr8ZrYjemLamzWOdwoOrrkGOtXEUY=",
"owner": "isabelroses",
- "repo": "nur",
- "rev": "017a96bd2b2a5bfb878e2e09674bcc695c28aa33",
+ "repo": "bellado",
+ "rev": "4fa6b3ca680b647a912a8f6198148a3cd222a704",
"type": "github"
},
"original": {
"owner": "isabelroses",
- "repo": "nur",
+ "repo": "bellado",
"type": "github"
}
},
@@ -58,17 +90,33 @@
"type": "gitlab"
}
},
+ "bufdelete-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1688027130,
+ "narHash": "sha256-UubYRfRAXZ89WOc3QFMvAMjNjLW6bV4nDgSa1CRZkIM=",
+ "owner": "famiu",
+ "repo": "bufdelete.nvim",
+ "rev": "07d1f8ba79dec59d42b975a4df1c732b2e4e37b4",
+ "type": "github"
+ },
+ "original": {
+ "owner": "famiu",
+ "repo": "bufdelete.nvim",
+ "type": "github"
+ }
+ },
"catppuccin": {
"inputs": {
- "flake-compat": "flake-compat_2",
+ "flake-compat": "flake-compat",
"nixpkgs": "nixpkgs_2"
},
"locked": {
- "lastModified": 1692027154,
- "narHash": "sha256-41Eug3MJHYRM4kDx00qvoXZ5kr+Dlvr6c7GpCRFIdVo=",
+ "lastModified": 1697225301,
+ "narHash": "sha256-EKKclzHBNgRmnZPMuzVbX5KAqkBdxMutDDauqLWOhf4=",
"owner": "isabelroses",
"repo": "ctp-nix",
- "rev": "0b448d3e12a9429ee95d6c9c44f5f5035fdbc2b4",
+ "rev": "8c39bd3d2adeb68b541fa174bf0163d4365ecbd5",
"type": "github"
},
"original": {
@@ -77,21 +125,56 @@
"type": "github"
}
},
+ "catppuccin-toolbox": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs_3",
+ "rust-overlay": "rust-overlay"
+ },
+ "locked": {
+ "lastModified": 1697961149,
+ "narHash": "sha256-0UeE/xr23CpkkP9lig0O6YnN/AsdM28VGSQTHTBaLSk=",
+ "owner": "catppuccin",
+ "repo": "toolbox",
+ "rev": "5b5b4a50dd9183b4182818528202f990de5bd422",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "toolbox",
+ "type": "github"
+ }
+ },
+ "catppuccin_2": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690630440,
+ "narHash": "sha256-MSZcIrV3vvgb5mlMpO5uRlAYoENm2pZyuZbV5Q9Vg58=",
+ "owner": "catppuccin",
+ "repo": "nvim",
+ "rev": "057c34f849cf21059487d849e2f3b3efcd4ee0eb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "nvim",
+ "type": "github"
+ }
+ },
"catppuccinifier": {
"inputs": {
"crane": "crane",
- "flake-utils": "flake-utils_2",
+ "flake-utils": "flake-utils_3",
"nixpkgs": [
- "bella-nur",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1692223331,
- "narHash": "sha256-CEjdCr7QgyQw+1VmeEyt95R0HKE0lAKZHrwahaxgJoU=",
+ "lastModified": 1696928114,
+ "narHash": "sha256-h445Aox0jck7MOCsKxXLKiE4QvptL/54eXUuhQZGF7o=",
"owner": "lighttigerXIV",
"repo": "catppuccinifier",
- "rev": "965f48a28d57eb979a5d932b873fa6e4d1b2497b",
+ "rev": "ef9c180bb7bbf1486671a1c6df41adaab60a9b41",
"type": "github"
},
"original": {
@@ -100,1208 +183,2704 @@
"type": "github"
}
},
- "crane": {
- "inputs": {
- "flake-compat": "flake-compat",
- "flake-utils": "flake-utils",
- "nixpkgs": [
- "bella-nur",
- "catppuccinifier",
- "nixpkgs"
- ],
- "rust-overlay": "rust-overlay"
- },
+ "ccc": {
+ "flake": false,
"locked": {
- "lastModified": 1687310026,
- "narHash": "sha256-20RHFbrnC+hsG4Hyeg/58LvQAK7JWfFItTPFAFamu8E=",
- "owner": "ipetkov",
- "repo": "crane",
- "rev": "116b32c30b5ff28e49f4fcbeeb1bbe3544593204",
+ "lastModified": 1686587775,
+ "narHash": "sha256-T1ryyTdbU/335MpD184PSnBLgj4S2Kzf9hZnwc9to+I=",
+ "owner": "uga-rosa",
+ "repo": "ccc.nvim",
+ "rev": "4a0ddaf787cc82796e84ab8a7f70d086f250aeb6",
"type": "github"
},
"original": {
- "owner": "ipetkov",
- "repo": "crane",
+ "owner": "uga-rosa",
+ "repo": "ccc.nvim",
"type": "github"
}
},
- "crane_2": {
- "inputs": {
- "flake-compat": [
- "lanzaboote",
- "flake-compat"
- ],
- "flake-utils": [
- "lanzaboote",
- "flake-utils"
- ],
- "nixpkgs": [
- "lanzaboote",
- "nixpkgs"
- ],
- "rust-overlay": [
- "lanzaboote",
- "rust-overlay"
- ]
- },
+ "cellular-automaton": {
+ "flake": false,
"locked": {
- "lastModified": 1688772518,
- "narHash": "sha256-ol7gZxwvgLnxNSZwFTDJJ49xVY5teaSvF7lzlo3YQfM=",
- "owner": "ipetkov",
- "repo": "crane",
- "rev": "8b08e96c9af8c6e3a2b69af5a7fa168750fcf88e",
+ "lastModified": 1674679594,
+ "narHash": "sha256-h4KQCf8+GbxWSyZzDny07YFZm7j+aSSfm51lsaK0Ers=",
+ "owner": "Eandrju",
+ "repo": "cellular-automaton.nvim",
+ "rev": "679943b8e1e5ef79aaeeaf4b00782c52eb4e928f",
"type": "github"
},
"original": {
- "owner": "ipetkov",
- "repo": "crane",
+ "owner": "Eandrju",
+ "repo": "cellular-automaton.nvim",
"type": "github"
}
},
- "crane_3": {
- "inputs": {
- "flake-compat": [
- "nekowinston-nur"
- ],
- "flake-utils": [
- "nekowinston-nur",
- "flake-utils"
- ],
- "nixpkgs": [
- "nekowinston-nur",
- "nixpkgs"
- ],
- "rust-overlay": [
- "nekowinston-nur",
- "rust-overlay"
- ]
+ "cheatsheet-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1640255456,
+ "narHash": "sha256-TYkGB7cON2t4GwMaR9H1MDG2j3btBv2AR37ade8kqTY=",
+ "owner": "sudormrfbin",
+ "repo": "cheatsheet.nvim",
+ "rev": "9716f9aaa94dd1fd6ce59b5aae0e5f25e2a463ef",
+ "type": "github"
},
+ "original": {
+ "owner": "sudormrfbin",
+ "repo": "cheatsheet.nvim",
+ "type": "github"
+ }
+ },
+ "cinnamon-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1686108916,
- "narHash": "sha256-looLH5MdY4erLiJw0XwQohGdr0fJL9y6TJY3898RA2U=",
- "owner": "ipetkov",
- "repo": "crane",
- "rev": "8ab1a49432695bd80ff4b7f6c6515da0e926d922",
+ "lastModified": 1670143364,
+ "narHash": "sha256-JglXQhoPgN9sQ3yuv0+VQxmKMvoQTu5lbGLSRaQkytI=",
+ "owner": "declancm",
+ "repo": "cinnamon.nvim",
+ "rev": "c406ffda3a0302f32c23b24ab756ea20467d6578",
"type": "github"
},
"original": {
- "owner": "ipetkov",
- "ref": "v0.12.2",
- "repo": "crane",
+ "owner": "declancm",
+ "repo": "cinnamon.nvim",
"type": "github"
}
},
- "devshell": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ],
- "systems": "systems_3"
+ "cmp-buffer": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1660101488,
+ "narHash": "sha256-dG4U7MtnXThoa/PD+qFtCt76MQ14V1wX8GMYcvxEnbM=",
+ "owner": "hrsh7th",
+ "repo": "cmp-buffer",
+ "rev": "3022dbc9166796b644a841a02de8dd1cc1d311fa",
+ "type": "github"
},
+ "original": {
+ "owner": "hrsh7th",
+ "repo": "cmp-buffer",
+ "type": "github"
+ }
+ },
+ "cmp-nvim-lsp": {
+ "flake": false,
"locked": {
- "lastModified": 1692793255,
- "narHash": "sha256-yVyj0AE280JkccDHuG1XO9oGxN6bW8ksr/xttXcXzK0=",
- "owner": "numtide",
- "repo": "devshell",
- "rev": "2aa26972b951bc05c3632d4e5ae683cb6771a7c6",
+ "lastModified": 1687494203,
+ "narHash": "sha256-mU0soCz79erJXMMqD/FyrJZ0mu2n6fE0deymPzQlxts=",
+ "owner": "hrsh7th",
+ "repo": "cmp-nvim-lsp",
+ "rev": "44b16d11215dce86f253ce0c30949813c0a90765",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "devshell",
+ "owner": "hrsh7th",
+ "repo": "cmp-nvim-lsp",
"type": "github"
}
},
- "dongsu8142-nur": {
- "inputs": {
- "nixpkgs": [
- "bella-nur",
- "ags",
- "nixpkgs"
- ]
+ "cmp-path": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1664784283,
+ "narHash": "sha256-thppiiV3wjIaZnAXmsh7j3DUc6ceSCvGzviwFUnoPaI=",
+ "owner": "hrsh7th",
+ "repo": "cmp-path",
+ "rev": "91ff86cd9c29299a64f968ebb45846c485725f23",
+ "type": "github"
},
+ "original": {
+ "owner": "hrsh7th",
+ "repo": "cmp-path",
+ "type": "github"
+ }
+ },
+ "cmp-treesitter": {
+ "flake": false,
"locked": {
- "lastModified": 1690083492,
- "narHash": "sha256-UoIG+sl44U38FTmM2+m4X2Qi5aivjITcUxAkVHouZl4=",
- "owner": "dongsu8142",
- "repo": "nur",
- "rev": "7f5c7067a482e96fe3787e07a54e21041a4d15c0",
+ "lastModified": 1680745848,
+ "narHash": "sha256-WOcg6w4M20gpMCZjZ3DpPIA55SGLjV75fhckefiVfU0=",
+ "owner": "ray-x",
+ "repo": "cmp-treesitter",
+ "rev": "389eadd48c27aa6dc0e6b992644704f026802a2e",
"type": "github"
},
"original": {
- "owner": "dongsu8142",
- "repo": "nur",
+ "owner": "ray-x",
+ "repo": "cmp-treesitter",
"type": "github"
}
},
- "flake-compat": {
+ "cmp-vsnip": {
"flake": false,
"locked": {
- "lastModified": 1673956053,
- "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
- "owner": "edolstra",
- "repo": "flake-compat",
- "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "lastModified": 1669100283,
+ "narHash": "sha256-2mkN03noOr5vBvRbSb35xZKorSH+8savQNZtgM9+QcM=",
+ "owner": "hrsh7th",
+ "repo": "cmp-vsnip",
+ "rev": "989a8a73c44e926199bfd05fa7a516d51f2d2752",
"type": "github"
},
"original": {
- "owner": "edolstra",
- "repo": "flake-compat",
+ "owner": "hrsh7th",
+ "repo": "cmp-vsnip",
"type": "github"
}
},
- "flake-compat_2": {
+ "codewindow-nvim": {
"flake": false,
"locked": {
- "lastModified": 1673956053,
- "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
- "owner": "edolstra",
- "repo": "flake-compat",
- "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "lastModified": 1690128662,
+ "narHash": "sha256-7ntC06PhxfuKnGyXpiW4juP3fWR97DH3Gygwvscv3OY=",
+ "owner": "gorbit99",
+ "repo": "codewindow.nvim",
+ "rev": "11fb5520898d22a563fe6a124a61c0d2887f3d3f",
"type": "github"
},
"original": {
- "owner": "edolstra",
- "repo": "flake-compat",
+ "owner": "gorbit99",
+ "repo": "codewindow.nvim",
"type": "github"
}
},
- "flake-compat_3": {
+ "comment-nvim": {
"flake": false,
"locked": {
- "lastModified": 1673956053,
- "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
- "owner": "edolstra",
- "repo": "flake-compat",
- "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "lastModified": 1686546603,
+ "narHash": "sha256-XM9yhp+SGxfAOdN/eDunzM0TMoCJhVth3wpFKNCGf3g=",
+ "owner": "numToStr",
+ "repo": "Comment.nvim",
+ "rev": "176e85eeb63f1a5970d6b88f1725039d85ca0055",
"type": "github"
},
"original": {
- "owner": "edolstra",
- "repo": "flake-compat",
+ "owner": "numToStr",
+ "repo": "Comment.nvim",
"type": "github"
}
},
- "flake-compat_4": {
+ "copilot-cmp": {
+ "flake": false,
"locked": {
- "lastModified": 1688025799,
- "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=",
- "owner": "nix-community",
- "repo": "flake-compat",
- "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c",
+ "lastModified": 1683831407,
+ "narHash": "sha256-+MzEGnhlrYRvAfskOwmw69OC1CsPXt7s3z+xPe9XPqs=",
+ "owner": "zbirenbaum",
+ "repo": "copilot-cmp",
+ "rev": "c2cdb3c0f5078b0619055af192295830a7987790",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "flake-compat",
+ "owner": "zbirenbaum",
+ "repo": "copilot-cmp",
"type": "github"
}
},
- "flake-compat_5": {
+ "copilot-lua": {
"flake": false,
"locked": {
- "lastModified": 1668681692,
- "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
- "owner": "edolstra",
- "repo": "flake-compat",
- "rev": "009399224d5e398d03b22badca40a37ac85412a1",
+ "lastModified": 1688190439,
+ "narHash": "sha256-lD9FdbKKZ6d/BjIfqp0Ust2hqSYNLpCFWxuaKUO9qLs=",
+ "owner": "zbirenbaum",
+ "repo": "copilot.lua",
+ "rev": "e48bd7020a98be217d85c006a298656294fd6210",
"type": "github"
},
"original": {
- "owner": "edolstra",
- "repo": "flake-compat",
+ "owner": "zbirenbaum",
+ "repo": "copilot.lua",
"type": "github"
}
},
- "flake-parts": {
+ "crane": {
"inputs": {
- "nixpkgs-lib": [
+ "flake-compat": "flake-compat_2",
+ "flake-utils": "flake-utils_2",
+ "nixpkgs": [
+ "catppuccinifier",
"nixpkgs"
- ]
+ ],
+ "rust-overlay": "rust-overlay_2"
},
"locked": {
- "lastModified": 1690933134,
- "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb",
+ "lastModified": 1687310026,
+ "narHash": "sha256-20RHFbrnC+hsG4Hyeg/58LvQAK7JWfFItTPFAFamu8E=",
+ "owner": "ipetkov",
+ "repo": "crane",
+ "rev": "116b32c30b5ff28e49f4fcbeeb1bbe3544593204",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
+ "owner": "ipetkov",
+ "repo": "crane",
"type": "github"
}
},
- "flake-parts_2": {
+ "crane_2": {
"inputs": {
- "nixpkgs-lib": [
+ "nixpkgs": [
"lanzaboote",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1688466019,
- "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
+ "lastModified": 1697840921,
+ "narHash": "sha256-zXHwu104SQOxogkMgg+w22c3+zI/FvK83TAkfLmeKw0=",
+ "owner": "ipetkov",
+ "repo": "crane",
+ "rev": "758ae442227103fa501276e8225609a11c99718e",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
+ "owner": "ipetkov",
+ "repo": "crane",
"type": "github"
}
},
- "flake-parts_3": {
- "inputs": {
- "nixpkgs-lib": "nixpkgs-lib"
- },
+ "crates-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1688466019,
- "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
+ "lastModified": 1688295570,
+ "narHash": "sha256-ah+fTmzkZn+xuL3sG2RxlCtDiFsRv3SY1iJzYKMIaMg=",
+ "owner": "Saecki",
+ "repo": "crates.nvim",
+ "rev": "4ce7c51b881e58f1e2f8f437f30e4e583cbac319",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
+ "owner": "Saecki",
+ "repo": "crates.nvim",
"type": "github"
}
},
- "flake-parts_4": {
- "inputs": {
- "nixpkgs-lib": "nixpkgs-lib_2"
- },
+ "dashboard-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1690933134,
- "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb",
+ "lastModified": 1690351087,
+ "narHash": "sha256-aVMugjgA9lnORUVDBpa8G800Ev86htP4hDGrBq6Sw6s=",
+ "owner": "glepnir",
+ "repo": "dashboard-nvim",
+ "rev": "c17d3210b3dec8798b4fc82a11c542989251f85d",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
+ "owner": "glepnir",
+ "repo": "dashboard-nvim",
"type": "github"
}
},
- "flake-parts_5": {
+ "devshell": {
"inputs": {
- "nixpkgs-lib": [
- "nixpkgs-wayland",
- "nix-eval-jobs",
+ "nixpkgs": [
"nixpkgs"
- ]
+ ],
+ "systems": "systems_4"
},
"locked": {
- "lastModified": 1690933134,
- "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb",
+ "lastModified": 1695973661,
+ "narHash": "sha256-BP2H4c42GThPIhERtTpV1yCtwQHYHEKdRu7pjrmQAwo=",
+ "owner": "numtide",
+ "repo": "devshell",
+ "rev": "cd4e2fda3150dd2f689caeac07b7f47df5197c31",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
+ "owner": "numtide",
+ "repo": "devshell",
"type": "github"
}
},
- "flake-parts_6": {
- "inputs": {
- "nixpkgs-lib": [
- "schizofox",
- "nixpak",
- "hercules-ci-effects",
- "hercules-ci-agent",
- "nixpkgs"
- ]
+ "diffview-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1689788060,
+ "narHash": "sha256-0tsgwI/qZm8Gj3NyN9CA+YHf3qim7vGXI+vbEcFBKbQ=",
+ "owner": "sindrets",
+ "repo": "diffview.nvim",
+ "rev": "e91110d2a7f8e2f667666aba6ea089ff823f8748",
+ "type": "github"
},
+ "original": {
+ "owner": "sindrets",
+ "repo": "diffview.nvim",
+ "type": "github"
+ }
+ },
+ "dirt-samples-src": {
+ "flake": false,
"locked": {
- "lastModified": 1688466019,
- "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
+ "lastModified": 1588278411,
+ "narHash": "sha256-h8vQxRym6QzNLOTZU7A43VCHuG0H77l+BFwXnC0L1CE=",
+ "owner": "tidalcycles",
+ "repo": "dirt-samples",
+ "rev": "66d432418c9a7d82cf049d9246adfa62f46df2a6",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
+ "owner": "tidalcycles",
+ "ref": "master",
+ "repo": "dirt-samples",
"type": "github"
}
},
- "flake-utils": {
- "inputs": {
- "systems": "systems"
+ "dracula": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690594744,
+ "narHash": "sha256-gblqxRTphGBpEOx57/4oU/B50O0OguIm1bFtd4LXuQ4=",
+ "owner": "Mofiqul",
+ "repo": "dracula.nvim",
+ "rev": "9fe831e685a76e1a1898a694623b33247c4d036c",
+ "type": "github"
},
+ "original": {
+ "owner": "Mofiqul",
+ "repo": "dracula.nvim",
+ "type": "github"
+ }
+ },
+ "dressing-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1685518550,
- "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
+ "lastModified": 1690648598,
+ "narHash": "sha256-hndRErSXhX1BHM90nuhiZkgHwkclLEMv5vtF+GDzUP4=",
+ "owner": "stevearc",
+ "repo": "dressing.nvim",
+ "rev": "829bc80400651aea31b03d8fc9a99135512fe67a",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "stevearc",
+ "repo": "dressing.nvim",
"type": "github"
}
},
- "flake-utils_2": {
- "inputs": {
- "systems": "systems_2"
+ "elixir-ls": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690526097,
+ "narHash": "sha256-lR1xsOJhz0W/Z3E2EUWujpUvpgUkLLDr0E6Ao31zi8s=",
+ "owner": "elixir-lsp",
+ "repo": "elixir-ls",
+ "rev": "216ff0e2969c2bbe45d324c4d6a5f08e6b681f5e",
+ "type": "github"
},
+ "original": {
+ "owner": "elixir-lsp",
+ "repo": "elixir-ls",
+ "type": "github"
+ }
+ },
+ "elixir-tools": {
+ "flake": false,
"locked": {
- "lastModified": 1687171271,
- "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c",
+ "lastModified": 1690555653,
+ "narHash": "sha256-7wDEChXTUGp8ONT6jufIJp05vawzo4AXg35ELNLvysA=",
+ "owner": "elixir-tools",
+ "repo": "elixir-tools.nvim",
+ "rev": "883933b57c9150c71ad2b99a4080685d83e095b8",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "elixir-tools",
+ "repo": "elixir-tools.nvim",
"type": "github"
}
},
- "flake-utils_3": {
- "inputs": {
- "systems": "systems_5"
+ "fidget-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1686378433,
+ "narHash": "sha256-N3O/AvsD6Ckd62kDEN4z/K5A3SZNR15DnQeZhH6/Rr0=",
+ "owner": "j-hui",
+ "repo": "fidget.nvim",
+ "rev": "90c22e47be057562ee9566bad313ad42d622c1d3",
+ "type": "github"
},
+ "original": {
+ "owner": "j-hui",
+ "ref": "legacy",
+ "repo": "fidget.nvim",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
"locked": {
- "lastModified": 1689068808,
- "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "edolstra",
+ "repo": "flake-compat",
"type": "github"
}
},
- "flake-utils_4": {
- "inputs": {
- "systems": "systems_6"
+ "flake-compat_2": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
},
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-compat_3": {
+ "flake": false,
"locked": {
- "lastModified": 1689068808,
- "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
+ "lastModified": 1696426674,
+ "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "edolstra",
+ "repo": "flake-compat",
"type": "github"
}
},
- "flake-utils_5": {
- "inputs": {
- "systems": "systems_7"
+ "flake-compat_4": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
},
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-compat_5": {
+ "flake": false,
"locked": {
- "lastModified": 1687709756,
- "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7",
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "edolstra",
+ "repo": "flake-compat",
"type": "github"
}
},
- "flake-utils_6": {
- "inputs": {
- "systems": "systems_8"
+ "flake-compat_6": {
+ "locked": {
+ "lastModified": 1688025799,
+ "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=",
+ "owner": "nix-community",
+ "repo": "flake-compat",
+ "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c",
+ "type": "github"
},
+ "original": {
+ "owner": "nix-community",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-compat_7": {
+ "flake": false,
"locked": {
- "lastModified": 1692799911,
- "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "edolstra",
+ "repo": "flake-compat",
"type": "github"
}
},
- "flake-utils_7": {
- "inputs": {
- "systems": "systems_9"
+ "flake-compat_8": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1696426674,
+ "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+ "type": "github"
},
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-compat_9": {
+ "flake": false,
"locked": {
- "lastModified": 1681202837,
- "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+ "lastModified": 1668681692,
+ "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "009399224d5e398d03b22badca40a37ac85412a1",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "edolstra",
+ "repo": "flake-compat",
"type": "github"
}
},
- "flake-utils_8": {
+ "flake-parts": {
"inputs": {
- "systems": "systems_10"
+ "nixpkgs-lib": [
+ "nixpkgs"
+ ]
},
"locked": {
- "lastModified": 1681202837,
- "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+ "lastModified": 1696343447,
+ "narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
"type": "github"
}
},
- "gitignore": {
+ "flake-parts_2": {
"inputs": {
- "nixpkgs": [
+ "nixpkgs-lib": [
"lanzaboote",
- "pre-commit-hooks-nix",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1660459072,
- "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "lastModified": 1696343447,
+ "narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
"owner": "hercules-ci",
- "repo": "gitignore.nix",
- "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "repo": "flake-parts",
+ "rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
"type": "github"
},
"original": {
"owner": "hercules-ci",
- "repo": "gitignore.nix",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-parts_3": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1693611461,
+ "narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-parts_4": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib_2"
+ },
+ "locked": {
+ "lastModified": 1696343447,
+ "narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-parts_5": {
+ "inputs": {
+ "nixpkgs-lib": [
+ "nixpkgs-wayland",
+ "nix-eval-jobs",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1696343447,
+ "narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-parts_6": {
+ "inputs": {
+ "nixpkgs-lib": [
+ "schizofox",
+ "nixpak",
+ "hercules-ci-effects",
+ "hercules-ci-agent",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1688466019,
+ "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-schemas": {
+ "locked": {
+ "lastModified": 1697467827,
+ "narHash": "sha256-j8SR19V1SRysyJwpOBF4TLuAvAjF5t+gMiboN4gYQDU=",
+ "owner": "DeterminateSystems",
+ "repo": "flake-schemas",
+ "rev": "764932025c817d4e500a8d2a4d8c565563923d29",
+ "type": "github"
+ },
+ "original": {
+ "owner": "DeterminateSystems",
+ "repo": "flake-schemas",
+ "type": "github"
+ }
+ },
+ "flake-schemas_2": {
+ "locked": {
+ "lastModified": 1693392497,
+ "narHash": "sha256-/fuUqkWIfRHaZb9cFTWWVHqSxpq/n6NlAvXqBuFTJqs=",
+ "owner": "DeterminateSystems",
+ "repo": "flake-schemas",
+ "rev": "9af39734fcd4813be17cadef98fc47285eaf7888",
+ "type": "github"
+ },
+ "original": {
+ "owner": "DeterminateSystems",
+ "repo": "flake-schemas",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1694529238,
+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_10": {
+ "inputs": {
+ "systems": "systems_12"
+ },
+ "locked": {
+ "lastModified": 1681202837,
+ "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_2": {
+ "inputs": {
+ "systems": "systems_2"
+ },
+ "locked": {
+ "lastModified": 1685518550,
+ "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_3": {
+ "inputs": {
+ "systems": "systems_3"
+ },
+ "locked": {
+ "lastModified": 1687171271,
+ "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_4": {
+ "inputs": {
+ "systems": "systems_5"
+ },
+ "locked": {
+ "lastModified": 1694529238,
+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_5": {
+ "inputs": {
+ "systems": "systems_7"
+ },
+ "locked": {
+ "lastModified": 1694529238,
+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_6": {
+ "locked": {
+ "lastModified": 1659877975,
+ "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_7": {
+ "inputs": {
+ "systems": "systems_9"
+ },
+ "locked": {
+ "lastModified": 1694529238,
+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_8": {
+ "inputs": {
+ "systems": "systems_10"
+ },
+ "locked": {
+ "lastModified": 1694529238,
+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_9": {
+ "inputs": {
+ "systems": "systems_11"
+ },
+ "locked": {
+ "lastModified": 1681202837,
+ "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flutter-tools": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690188839,
+ "narHash": "sha256-h8s5g6KU7dMesDqiwzv2MmUGk6jlU5lBnuVA3LaoI1g=",
+ "owner": "akinsho",
+ "repo": "flutter-tools.nvim",
+ "rev": "561d85b16d8ca2938820a9c26b2fe74096d89c81",
+ "type": "github"
+ },
+ "original": {
+ "owner": "akinsho",
+ "repo": "flutter-tools.nvim",
+ "type": "github"
+ }
+ },
+ "gesture-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1687655077,
+ "narHash": "sha256-ps/dAKIga2ZVunwj+KU/Iej4PGZbBvm5ZzcK30EiKMc=",
+ "owner": "notomo",
+ "repo": "gesture.nvim",
+ "rev": "aa273e7982943ac6ccf6b864f3fd40ad287a9fe2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "notomo",
+ "repo": "gesture.nvim",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "lanzaboote",
+ "pre-commit-hooks-nix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "gitignore_2": {
+ "inputs": {
+ "nixpkgs": [
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "gitsigns-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690463120,
+ "narHash": "sha256-kraK0GP5aLGbh1eVZCm41D6BztjFxthSXGnE5CxhrZs=",
+ "owner": "lewis6991",
+ "repo": "gitsigns.nvim",
+ "rev": "5d73da785a3c05fd63ac31769079db05169a6ec7",
+ "type": "github"
+ },
+ "original": {
+ "owner": "lewis6991",
+ "repo": "gitsigns.nvim",
+ "type": "github"
+ }
+ },
+ "glow-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690579937,
+ "narHash": "sha256-ZDlQfSJHq9CbOpTDgmIoMq4gDzHxoUslFfN5XKtrDtM=",
+ "owner": "ellisonleao",
+ "repo": "glow.nvim",
+ "rev": "8942dfb05794f436af4fbc90a34393f1fd36f361",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ellisonleao",
+ "repo": "glow.nvim",
+ "type": "github"
+ }
+ },
+ "haskell-flake": {
+ "locked": {
+ "lastModified": 1684780604,
+ "narHash": "sha256-2uMZsewmRn7rRtAnnQNw1lj0uZBMh4m6Cs/7dV5YF08=",
+ "owner": "srid",
+ "repo": "haskell-flake",
+ "rev": "74210fa80a49f1b6f67223debdbf1494596ff9f2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "srid",
+ "ref": "0.3.0",
+ "repo": "haskell-flake",
+ "type": "github"
+ }
+ },
+ "hercules-ci-agent": {
+ "inputs": {
+ "flake-parts": "flake-parts_6",
+ "haskell-flake": "haskell-flake",
+ "nixpkgs": "nixpkgs_11"
+ },
+ "locked": {
+ "lastModified": 1688568579,
+ "narHash": "sha256-ON0M56wtY/TIIGPkXDlJboAmuYwc73Hi8X9iJGtxOhM=",
+ "owner": "hercules-ci",
+ "repo": "hercules-ci-agent",
+ "rev": "367dd8cd649b57009a6502e878005a1e54ad78c5",
+ "type": "github"
+ },
+ "original": {
+ "id": "hercules-ci-agent",
+ "type": "indirect"
+ }
+ },
+ "hercules-ci-effects": {
+ "inputs": {
+ "flake-parts": [
+ "schizofox",
+ "nixpak",
+ "flake-parts"
+ ],
+ "hercules-ci-agent": "hercules-ci-agent",
+ "nixpkgs": [
+ "schizofox",
+ "nixpak",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1697031886,
+ "narHash": "sha256-oTMPX8dGC7yxSwrbF4NuPNQsUEcHB1dusW2yEbFD5zg=",
+ "owner": "hercules-ci",
+ "repo": "hercules-ci-effects",
+ "rev": "178b36dc3a75c96efc25477d45eafc37ba1fafc3",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "hercules-ci-effects",
+ "type": "github"
+ }
+ },
+ "highlight-undo": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1695227852,
+ "narHash": "sha256-I1AwVYqpJNA3K1AwGy/VgPnbrYvX19qfI9bQFZNu1SU=",
+ "owner": "tzachar",
+ "repo": "highlight-undo.nvim",
+ "rev": "50a6884a8476be04ecce8f1c4ed692c5000ef0a1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tzachar",
+ "repo": "highlight-undo.nvim",
+ "type": "github"
+ }
+ },
+ "home-manager": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1698162493,
+ "narHash": "sha256-Zehw3cWiTXGGlDDjzTgIX1BhWG+049D/RcSMAiypAcM=",
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "rev": "14b54157201fd574b0fa1b3ce7394c9d3a87fbc1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "type": "github"
+ }
+ },
+ "home-manager_2": {
+ "inputs": {
+ "nixpkgs": [
+ "schizofox",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1697662575,
+ "narHash": "sha256-fVtd4Le9edB831xyGWu0aqSfg6YVbkCNMX/IE3SUIdk=",
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "rev": "3433206e51766b4164dad368a81325efbf343fbe",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "type": "github"
+ }
+ },
+ "hop-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1684332066,
+ "narHash": "sha256-xdjFbdp0+S3pVdwcOFmad8PMUU033WeDzswOSdxSQjg=",
+ "owner": "phaazon",
+ "repo": "hop.nvim",
+ "rev": "03f0434869f1f38868618198b5f4f2ab6d39aef2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "phaazon",
+ "repo": "hop.nvim",
+ "type": "github"
+ }
+ },
+ "hyprland": {
+ "inputs": {
+ "hyprland-protocols": "hyprland-protocols",
+ "nixpkgs": "nixpkgs_4",
+ "systems": "systems_6",
+ "wlroots": "wlroots",
+ "xdph": "xdph"
+ },
+ "locked": {
+ "lastModified": 1698190104,
+ "narHash": "sha256-40TEEIjlIb0hJE/yRsjLBwjkRYkj/4QRTkN1Op86umw=",
+ "owner": "hyprwm",
+ "repo": "Hyprland",
+ "rev": "a1b138a6258b00787cea43bddc48b7caa8cca3a0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "Hyprland",
+ "type": "github"
+ }
+ },
+ "hyprland-protocols": {
+ "inputs": {
+ "nixpkgs": [
+ "hyprland",
+ "nixpkgs"
+ ],
+ "systems": [
+ "hyprland",
+ "systems"
+ ]
+ },
+ "locked": {
+ "lastModified": 1691753796,
+ "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
+ "owner": "hyprwm",
+ "repo": "hyprland-protocols",
+ "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprland-protocols",
+ "type": "github"
+ }
+ },
+ "hyprland-protocols_2": {
+ "inputs": {
+ "nixpkgs": [
+ "xdg-portal-hyprland",
+ "nixpkgs"
+ ],
+ "systems": [
+ "xdg-portal-hyprland",
+ "systems"
+ ]
+ },
+ "locked": {
+ "lastModified": 1691753796,
+ "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
+ "owner": "hyprwm",
+ "repo": "hyprland-protocols",
+ "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprland-protocols",
+ "type": "github"
+ }
+ },
+ "hyprpicker": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1697019850,
+ "narHash": "sha256-o5YxKQjs2SGMCt7I7U+CFleAVzXjoXAWRicMNATQQ94=",
+ "owner": "hyprwm",
+ "repo": "hyprpicker",
+ "rev": "94010d6b9afae7d9dfde910cf18b81d148374426",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprpicker",
+ "type": "github"
+ }
+ },
+ "icon-picker-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1683205244,
+ "narHash": "sha256-/oi2Kj7GDXzN3ccPoxyxXtQTYSxtZndgELZa2XgZ3U8=",
+ "owner": "ziontee113",
+ "repo": "icon-picker.nvim",
+ "rev": "e6dca182518eeb7a51470c13605a5bce08a816e4",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ziontee113",
+ "repo": "icon-picker.nvim",
+ "type": "github"
+ }
+ },
+ "indent-blankline": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1688727830,
+ "narHash": "sha256-efMRkxjbr6o7kSKAEn0Kaw8lsDubRmc1N0Kd1BZ3A7k=",
+ "owner": "lukas-reineke",
+ "repo": "indent-blankline.nvim",
+ "rev": "4541d690816cb99a7fc248f1486aa87f3abce91c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "lukas-reineke",
+ "repo": "indent-blankline.nvim",
+ "type": "github"
+ }
+ },
+ "kommentary": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1672983049,
+ "narHash": "sha256-N4n5tjNB1yX/QxH+t5aG0VxNwZhUJejv0b5V62WEKDU=",
+ "owner": "b3nj5m1n",
+ "repo": "kommentary",
+ "rev": "3a80117148c6798972bb69414423311ab151d368",
+ "type": "github"
+ },
+ "original": {
+ "owner": "b3nj5m1n",
+ "repo": "kommentary",
+ "type": "github"
+ }
+ },
+ "lanzaboote": {
+ "inputs": {
+ "crane": "crane_2",
+ "flake-compat": "flake-compat_3",
+ "flake-parts": "flake-parts_2",
+ "flake-utils": "flake-utils_5",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "pre-commit-hooks-nix": "pre-commit-hooks-nix",
+ "rust-overlay": "rust-overlay_3"
+ },
+ "locked": {
+ "lastModified": 1698100456,
+ "narHash": "sha256-Hx9ZVZYARVbzJB0fFNe/lPE9a4oP1dDGJnl3siRtBJ0=",
+ "owner": "nix-community",
+ "repo": "lanzaboote",
+ "rev": "bb380e19488ec6105d07b57c23ac518be51bf901",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "lanzaboote",
+ "type": "github"
+ }
+ },
+ "leap-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690120911,
+ "narHash": "sha256-9GFZ5CuR92kFGwh/ouqSSp14eOLZLpzpoFTEuYL7biQ=",
+ "owner": "ggandor",
+ "repo": "leap.nvim",
+ "rev": "5efe985cf68fac3b6a6dfe7a75fbfaca8db2af9c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ggandor",
+ "repo": "leap.nvim",
+ "type": "github"
+ }
+ },
+ "lib-aggregate": {
+ "inputs": {
+ "flake-utils": "flake-utils_8",
+ "nixpkgs-lib": "nixpkgs-lib_3"
+ },
+ "locked": {
+ "lastModified": 1697976504,
+ "narHash": "sha256-sU8q83TEaafIe5d7L6Dc2alRhWT898aB0+6EXcfao1I=",
+ "owner": "nix-community",
+ "repo": "lib-aggregate",
+ "rev": "2e96d2f9d80f80bd22cd7c603985f2b03cf186fc",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "lib-aggregate",
+ "type": "github"
+ }
+ },
+ "lowdown-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1633514407,
+ "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "type": "github"
+ }
+ },
+ "lsp-lines": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1684163755,
+ "narHash": "sha256-Zhf2xitLWtE+dWqhvWtLM1K1WdtBvkqqoRLSYIO42oY=",
+ "owner": "~whynothugo",
+ "repo": "lsp_lines.nvim",
+ "rev": "f53af96d4789eef39a082dbcce078d2bfc384ece",
+ "type": "sourcehut"
+ },
+ "original": {
+ "owner": "~whynothugo",
+ "repo": "lsp_lines.nvim",
+ "type": "sourcehut"
+ }
+ },
+ "lsp-signature": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690267930,
+ "narHash": "sha256-qvcs0KuO2/NdtiTZIxJ2vrwV0I5PjzjMvoAePPasaJM=",
+ "owner": "ray-x",
+ "repo": "lsp_signature.nvim",
+ "rev": "58d4e810801da74c29313da86075d6aea537501f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ray-x",
+ "repo": "lsp_signature.nvim",
+ "type": "github"
+ }
+ },
+ "lspkind": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1683275543,
+ "narHash": "sha256-S+qZm51hw/cRujIfHV/1x1fYyCKI4XQ0utSL8uy4l6I=",
+ "owner": "onsails",
+ "repo": "lspkind-nvim",
+ "rev": "57610d5ab560c073c465d6faf0c19f200cb67e6e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "onsails",
+ "repo": "lspkind-nvim",
+ "type": "github"
+ }
+ },
+ "lspsaga": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1670360222,
+ "narHash": "sha256-7ENInq3LAPPTdm0Fb7klOc630j8m4LRj1kLZZFYLh68=",
+ "owner": "tami5",
+ "repo": "lspsaga.nvim",
+ "rev": "5faeec9f2508d2d49a66c0ac0d191096b4e3fa81",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tami5",
+ "repo": "lspsaga.nvim",
+ "type": "github"
+ }
+ },
+ "lualine": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1683213422,
+ "narHash": "sha256-ltHE8UIquGo07BSlFGM1l3wmTNN43i8kx6QY7Fj2CNo=",
+ "owner": "hoob3rt",
+ "repo": "lualine.nvim",
+ "rev": "05d78e9fd0cdfb4545974a5aa14b1be95a86e9c9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hoob3rt",
+ "repo": "lualine.nvim",
+ "type": "github"
+ }
+ },
+ "mind-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1679526071,
+ "narHash": "sha256-JIhAhQYGLLRucwlhzfckQYU5qjqbHtNH52JlGS5a79w=",
+ "owner": "phaazon",
+ "repo": "mind.nvim",
+ "rev": "002137dd7cf97865ebd01b6a260209d2daf2da66",
+ "type": "github"
+ },
+ "original": {
+ "owner": "phaazon",
+ "repo": "mind.nvim",
+ "type": "github"
+ }
+ },
+ "minimap-vim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690301768,
+ "narHash": "sha256-yRWZH9caSxrWjUXlM84fU90tZjNfX97m0m491ZsIHxA=",
+ "owner": "wfxr",
+ "repo": "minimap.vim",
+ "rev": "74573b63b9ef0583262b6bf6ef209eb7f3b06b94",
+ "type": "github"
+ },
+ "original": {
+ "owner": "wfxr",
+ "repo": "minimap.vim",
+ "type": "github"
+ }
+ },
+ "modes-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1682778003,
+ "narHash": "sha256-qrGgraBdAvIc6AXqMMWESlOV29lM5zC1du1r5L2kpQQ=",
+ "owner": "mvllow",
+ "repo": "modes.nvim",
+ "rev": "4d97a51ebbdb649b85f6d79da0009fddd7081a6b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "mvllow",
+ "repo": "modes.nvim",
+ "type": "github"
+ }
+ },
+ "naersk": {
+ "inputs": {
+ "nixpkgs": [
+ "neovim-flake",
+ "rnix-lsp",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1655042882,
+ "narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=",
+ "owner": "nix-community",
+ "repo": "naersk",
+ "rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "naersk",
+ "type": "github"
+ }
+ },
+ "neodev-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1695449121,
+ "narHash": "sha256-WisbNLKEz0IgO7gLDA2quNzK69hJaHzmvWkZSUPQb6k=",
+ "owner": "folke",
+ "repo": "neodev.nvim",
+ "rev": "c8e126393a34939fb448d48eeddb510971739e3a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "folke",
+ "repo": "neodev.nvim",
+ "type": "github"
+ }
+ },
+ "neovim-flake": {
+ "inputs": {
+ "alpha-nvim": "alpha-nvim",
+ "bufdelete-nvim": "bufdelete-nvim",
+ "catppuccin": "catppuccin_2",
+ "ccc": "ccc",
+ "cellular-automaton": "cellular-automaton",
+ "cheatsheet-nvim": "cheatsheet-nvim",
+ "cinnamon-nvim": "cinnamon-nvim",
+ "cmp-buffer": "cmp-buffer",
+ "cmp-nvim-lsp": "cmp-nvim-lsp",
+ "cmp-path": "cmp-path",
+ "cmp-treesitter": "cmp-treesitter",
+ "cmp-vsnip": "cmp-vsnip",
+ "codewindow-nvim": "codewindow-nvim",
+ "comment-nvim": "comment-nvim",
+ "copilot-cmp": "copilot-cmp",
+ "copilot-lua": "copilot-lua",
+ "crates-nvim": "crates-nvim",
+ "dashboard-nvim": "dashboard-nvim",
+ "diffview-nvim": "diffview-nvim",
+ "dracula": "dracula",
+ "dressing-nvim": "dressing-nvim",
+ "elixir-ls": "elixir-ls",
+ "elixir-tools": "elixir-tools",
+ "fidget-nvim": "fidget-nvim",
+ "flake-parts": [
+ "flake-parts"
+ ],
+ "flake-utils": [
+ "flake-utils"
+ ],
+ "flutter-tools": "flutter-tools",
+ "gesture-nvim": "gesture-nvim",
+ "gitsigns-nvim": "gitsigns-nvim",
+ "glow-nvim": "glow-nvim",
+ "highlight-undo": "highlight-undo",
+ "hop-nvim": "hop-nvim",
+ "icon-picker-nvim": "icon-picker-nvim",
+ "indent-blankline": "indent-blankline",
+ "kommentary": "kommentary",
+ "leap-nvim": "leap-nvim",
+ "lsp-lines": "lsp-lines",
+ "lsp-signature": "lsp-signature",
+ "lspkind": "lspkind",
+ "lspsaga": "lspsaga",
+ "lualine": "lualine",
+ "mind-nvim": "mind-nvim",
+ "minimap-vim": "minimap-vim",
+ "modes-nvim": "modes-nvim",
+ "neodev-nvim": "neodev-nvim",
+ "nil": [
+ "nil"
+ ],
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "nmd": "nmd",
+ "noice-nvim": "noice-nvim",
+ "none-ls": "none-ls",
+ "nui-nvim": "nui-nvim",
+ "nvim-autopairs": "nvim-autopairs",
+ "nvim-bufferline-lua": "nvim-bufferline-lua",
+ "nvim-cmp": "nvim-cmp",
+ "nvim-code-action-menu": "nvim-code-action-menu",
+ "nvim-colorizer-lua": "nvim-colorizer-lua",
+ "nvim-compe": "nvim-compe",
+ "nvim-cursorline": "nvim-cursorline",
+ "nvim-dap": "nvim-dap",
+ "nvim-dap-ui": "nvim-dap-ui",
+ "nvim-lightbulb": "nvim-lightbulb",
+ "nvim-lspconfig": "nvim-lspconfig",
+ "nvim-navbuddy": "nvim-navbuddy",
+ "nvim-navic": "nvim-navic",
+ "nvim-neoclip": "nvim-neoclip",
+ "nvim-notify": "nvim-notify",
+ "nvim-session-manager": "nvim-session-manager",
+ "nvim-surround": "nvim-surround",
+ "nvim-tree-lua": "nvim-tree-lua",
+ "nvim-treesitter-context": "nvim-treesitter-context",
+ "nvim-ts-autotag": "nvim-ts-autotag",
+ "nvim-web-devicons": "nvim-web-devicons",
+ "obsidian-nvim": "obsidian-nvim",
+ "onedark": "onedark",
+ "orgmode-nvim": "orgmode-nvim",
+ "oxocarbon": "oxocarbon",
+ "plenary-nvim": "plenary-nvim",
+ "presence-nvim": "presence-nvim",
+ "project-nvim": "project-nvim",
+ "registers": "registers",
+ "rnix-lsp": "rnix-lsp",
+ "rust-tools": "rust-tools",
+ "scrollbar-nvim": "scrollbar-nvim",
+ "smartcolumn": "smartcolumn",
+ "sqls-nvim": "sqls-nvim",
+ "systems": "systems_8",
+ "tabular": "tabular",
+ "telescope": "telescope",
+ "tidalcycles": "tidalcycles",
+ "todo-comments": "todo-comments",
+ "toggleterm-nvim": "toggleterm-nvim",
+ "tokyonight": "tokyonight",
+ "trouble": "trouble",
+ "vim-dirtytalk": "vim-dirtytalk",
+ "vim-illuminate": "vim-illuminate",
+ "vim-markdown": "vim-markdown",
+ "vim-repeat": "vim-repeat",
+ "vim-startify": "vim-startify",
+ "vim-vsnip": "vim-vsnip",
+ "which-key": "which-key",
+ "zig": "zig"
+ },
+ "locked": {
+ "lastModified": 1698081721,
+ "narHash": "sha256-V5WhcZbPIod8jE493Cnvzciy7ChShb6LCESw1eMUWlQ=",
+ "owner": "NotAShelf",
+ "repo": "neovim-flake",
+ "rev": "2b48b6d8443e3780636e8a71eb075f00aedcfd94",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NotAShelf",
+ "repo": "neovim-flake",
+ "type": "github"
+ }
+ },
+ "nh": {
+ "inputs": {
+ "flake-parts": "flake-parts_3",
+ "nix-filter": "nix-filter",
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1698045010,
+ "narHash": "sha256-jqGzR+REGYKYrpgTlVZeKqcpBSmQxrapkcWxCBh/Ebs=",
+ "owner": "viperML",
+ "repo": "nh",
+ "rev": "385e537de3c833dc4cc2ee7522b1852b030cbe06",
+ "type": "github"
+ },
+ "original": {
+ "owner": "viperML",
+ "repo": "nh",
+ "type": "github"
+ }
+ },
+ "nil": {
+ "inputs": {
+ "flake-utils": "flake-utils_7",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "rust-overlay": [
+ "rust-overlay"
+ ]
+ },
+ "locked": {
+ "lastModified": 1697710615,
+ "narHash": "sha256-YL63eoy3C/WeDxwctbv9dJBjqBabx8cO7lVTlVn3FVI=",
+ "owner": "oxalica",
+ "repo": "nil",
+ "rev": "bd93024db616a528473a7210d2756c7118155de9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "nil",
+ "type": "github"
+ }
+ },
+ "nix-eval-jobs": {
+ "inputs": {
+ "flake-parts": "flake-parts_5",
+ "nixpkgs": "nixpkgs_10",
+ "treefmt-nix": "treefmt-nix"
+ },
+ "locked": {
+ "lastModified": 1697679370,
+ "narHash": "sha256-E4iEs004owoShYK0MBDD6uRXCgZdxl//hYijvSakg0k=",
+ "owner": "nix-community",
+ "repo": "nix-eval-jobs",
+ "rev": "01a606e119963957eefaf1b22ef92b69b90f5b85",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nix-eval-jobs",
+ "type": "github"
+ }
+ },
+ "nix-filter": {
+ "locked": {
+ "lastModified": 1694857738,
+ "narHash": "sha256-bxxNyLHjhu0N8T3REINXQ2ZkJco0ABFPn6PIe2QUfqo=",
+ "owner": "numtide",
+ "repo": "nix-filter",
+ "rev": "41fd48e00c22b4ced525af521ead8792402de0ea",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "nix-filter",
+ "type": "github"
+ }
+ },
+ "nix-gaming": {
+ "inputs": {
+ "flake-parts": "flake-parts_4",
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1698109854,
+ "narHash": "sha256-Vg+LytTlOpgO0dWZoS/CsYCNQllG0p0I+XLWrkRrU8E=",
+ "owner": "fufexan",
+ "repo": "nix-gaming",
+ "rev": "5e8f1c9ae134b459475705a2eb9b81e6dc667e43",
+ "type": "github"
+ },
+ "original": {
+ "owner": "fufexan",
+ "repo": "nix-gaming",
+ "type": "github"
+ }
+ },
+ "nix-index-db": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1697946153,
+ "narHash": "sha256-7k7qIwWLaYPgQ4fxmEdew3yCffhK6rM4I4Jo3X/79DA=",
+ "owner": "nix-community",
+ "repo": "nix-index-database",
+ "rev": "5a2006282caaf32663cdcd582c5b18809c7d7d8d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nix-index-database",
+ "type": "github"
+ }
+ },
+ "nix-ld": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1686849676,
+ "narHash": "sha256-+z9t7BLugZO1WhyYEq6FI38TMh2EwfgfAv3RDFSjwtc=",
+ "owner": "Mic92",
+ "repo": "nix-ld",
+ "rev": "3abd605e56b5b34ec630bb10ba85f98c93cc05b2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "Mic92",
+ "repo": "nix-ld",
+ "type": "github"
+ }
+ },
+ "nixSchemas": {
+ "inputs": {
+ "flake-compat": "flake-compat_5",
+ "flake-schemas": "flake-schemas_2",
+ "lowdown-src": "lowdown-src",
+ "nixpkgs": "nixpkgs_8",
+ "nixpkgs-regression": "nixpkgs-regression"
+ },
+ "locked": {
+ "lastModified": 1697822067,
+ "narHash": "sha256-7HCcrF6GqIAreKvzt74do1/Urvp+b901Hckf5+WgR9M=",
+ "owner": "DeterminateSystems",
+ "repo": "nix",
+ "rev": "84867fa212fe08feeb27b668c4c78bc9eaf74e17",
+ "type": "github"
+ },
+ "original": {
+ "owner": "DeterminateSystems",
+ "ref": "flake-schemas",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "nixpak": {
+ "inputs": {
+ "flake-parts": [
+ "schizofox",
+ "flake-parts"
+ ],
+ "hercules-ci-effects": "hercules-ci-effects",
+ "nixpkgs": [
+ "schizofox",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1697667112,
+ "narHash": "sha256-/Mo2rCALFjplsA+e/H+V3QfpZ4BFUwoWFVXQqBLnClM=",
+ "owner": "nixpak",
+ "repo": "nixpak",
+ "rev": "a7640d51f24a462dee71f5dfe22f24c000dc5bdf",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixpak",
+ "repo": "nixpak",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1687379288,
+ "narHash": "sha256-cSuwfiqYfeVyqzCRkU9AvLTysmEuSal8nh6CYr+xWog=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "ef0bc3976340dab9a4e087a0bcff661a8b2e87f3",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-22_11": {
+ "locked": {
+ "lastModified": 1669558522,
+ "narHash": "sha256-yqxn+wOiPqe6cxzOo4leeJOp1bXE/fjPEi/3F/bBHv8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "ce5fe99df1f15a09a91a86be9738d68fadfbad82",
+ "type": "github"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "ref": "nixos-22.11",
+ "type": "indirect"
+ }
+ },
+ "nixpkgs-23_05": {
+ "locked": {
+ "lastModified": 1684782344,
+ "narHash": "sha256-SHN8hPYYSX0thDrMLMWPWYulK3YFgASOrCsIL3AJ78g=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "8966c43feba2c701ed624302b6a935f97bcbdf88",
+ "type": "github"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "ref": "nixos-23.05",
+ "type": "indirect"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1693471703,
+ "narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib_2": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1696019113,
+ "narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib_3": {
+ "locked": {
+ "lastModified": 1697935651,
+ "narHash": "sha256-qOfWjQ2JQSQL15KLh6D7xQhx0qgZlYZTYlcEiRuAMMw=",
+ "owner": "nix-community",
+ "repo": "nixpkgs.lib",
+ "rev": "e1e11fdbb01113d85c7f41cada9d2847660e3902",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nixpkgs.lib",
+ "type": "github"
+ }
+ },
+ "nixpkgs-regression": {
+ "locked": {
+ "lastModified": 1643052045,
+ "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1685801374,
+ "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable_2": {
+ "locked": {
+ "lastModified": 1685801374,
+ "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-wayland": {
+ "inputs": {
+ "flake-compat": "flake-compat_6",
+ "lib-aggregate": "lib-aggregate",
+ "nix-eval-jobs": "nix-eval-jobs",
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1698156831,
+ "narHash": "sha256-1NnPsQO2d0glJyA2dOsCvf7R7H/IEr5B6xRRUTblDI0=",
+ "owner": "nix-community",
+ "repo": "nixpkgs-wayland",
+ "rev": "ec64882e7238818dd914734ba7fe18945950ec71",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nixpkgs-wayland",
+ "type": "github"
+ }
+ },
+ "nixpkgs_10": {
+ "locked": {
+ "lastModified": 1697677194,
+ "narHash": "sha256-lN2eJCsOzjhxrvTQsNcW7r0E9hMJ7ABrKDQWpmYFRkM=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "18e505d654892d057f308c817d220faf962dbf23",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "master",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_11": {
+ "locked": {
+ "lastModified": 1688322751,
+ "narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_12": {
+ "locked": {
+ "lastModified": 1670751203,
+ "narHash": "sha256-XdoH1v3shKDGlrwjgrNX/EN8s3c+kQV7xY6cLCE8vcI=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "64e0bf055f9d25928c31fb12924e59ff8ce71e60",
+ "type": "github"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "ref": "nixos-unstable",
+ "type": "indirect"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1685655444,
+ "narHash": "sha256-6EujQNAeaUkWvpEZZcVF8qSfQrNVWFNNGbUJxv/A5a8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "e635192892f5abbc2289eaac3a73cdb249abaefd",
+ "type": "github"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "ref": "nixos-unstable",
+ "type": "indirect"
+ }
+ },
+ "nixpkgs_3": {
+ "locked": {
+ "lastModified": 1697723726,
+ "narHash": "sha256-SaTWPkI8a5xSHX/rrKzUe+/uVNy6zCGMXgoeMb7T9rg=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "7c9cc5a6e5d38010801741ac830a3f8fd667a7a0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
"type": "github"
}
},
- "haskell-flake": {
+ "nixpkgs_4": {
"locked": {
- "lastModified": 1684780604,
- "narHash": "sha256-2uMZsewmRn7rRtAnnQNw1lj0uZBMh4m6Cs/7dV5YF08=",
- "owner": "srid",
- "repo": "haskell-flake",
- "rev": "74210fa80a49f1b6f67223debdbf1494596ff9f2",
+ "lastModified": 1697723726,
+ "narHash": "sha256-SaTWPkI8a5xSHX/rrKzUe+/uVNy6zCGMXgoeMb7T9rg=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "7c9cc5a6e5d38010801741ac830a3f8fd667a7a0",
"type": "github"
},
"original": {
- "owner": "srid",
- "ref": "0.3.0",
- "repo": "haskell-flake",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
"type": "github"
}
},
- "hercules-ci-agent": {
- "inputs": {
- "flake-parts": "flake-parts_6",
- "haskell-flake": "haskell-flake",
- "nixpkgs": "nixpkgs_7"
- },
+ "nixpkgs_5": {
"locked": {
- "lastModified": 1688568579,
- "narHash": "sha256-ON0M56wtY/TIIGPkXDlJboAmuYwc73Hi8X9iJGtxOhM=",
- "owner": "hercules-ci",
- "repo": "hercules-ci-agent",
- "rev": "367dd8cd649b57009a6502e878005a1e54ad78c5",
+ "lastModified": 1656753965,
+ "narHash": "sha256-BCrB3l0qpJokOnIVc3g2lHiGhnjUi0MoXiw6t1o8H1E=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "0ea7a8f1b939d74e5df8af9a8f7342097cdf69eb",
"type": "github"
},
"original": {
- "id": "hercules-ci-agent",
- "type": "indirect"
+ "owner": "nixos",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
}
},
- "hercules-ci-effects": {
- "inputs": {
- "flake-parts": [
- "schizofox",
- "nixpak",
- "flake-parts"
- ],
- "hercules-ci-agent": "hercules-ci-agent",
- "nixpkgs": [
- "schizofox",
- "nixpak",
- "nixpkgs"
- ]
- },
+ "nixpkgs_6": {
"locked": {
- "lastModified": 1689397210,
- "narHash": "sha256-fVxZnqxMbsDkB4GzGAs/B41K0wt/e+B/fLxmTFF/S20=",
- "owner": "hercules-ci",
- "repo": "hercules-ci-effects",
- "rev": "0a63bfa3f00a3775ea3a6722b247880f1ffe91ce",
+ "lastModified": 1655400192,
+ "narHash": "sha256-49OBVVRgb9H/PSmNT9W61+NRdDbuSJVuDDflwXlaUKU=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "3d7435c638baffaa826b85459df0fff47f12317d",
"type": "github"
},
"original": {
- "owner": "hercules-ci",
- "repo": "hercules-ci-effects",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
"type": "github"
}
},
- "home-manager": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
- },
+ "nixpkgs_7": {
"locked": {
- "lastModified": 1692763155,
- "narHash": "sha256-qMrGKZ8c/q/mHO3ZdrcBPwiVVXPLLgXjY98Ejqb5kAA=",
- "owner": "nix-community",
- "repo": "home-manager",
- "rev": "6a20e40acaebf067da682661aa67da8b36812606",
+ "lastModified": 1689088367,
+ "narHash": "sha256-Y2tl2TlKCWEHrOeM9ivjCLlRAKH3qoPUE/emhZECU14=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "5c9ddb86679c400d6b7360797b8a22167c2053f8",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "home-manager",
+ "owner": "NixOS",
+ "ref": "release-23.05",
+ "repo": "nixpkgs",
"type": "github"
}
},
- "hyprland": {
- "inputs": {
- "hyprland-protocols": "hyprland-protocols",
- "nixpkgs": "nixpkgs_3",
- "systems": "systems_4",
- "wlroots": "wlroots",
- "xdph": "xdph"
- },
+ "nixpkgs_8": {
"locked": {
- "lastModified": 1692988931,
- "narHash": "sha256-biA+vhcRS2lT3zTnV8QyT0FoxEIdQ6N+JnaWsr7F+8M=",
- "owner": "hyprwm",
- "repo": "Hyprland",
- "rev": "ae69b9a2fa559d869f4e9c61ddf24e152d97df2f",
+ "lastModified": 1670461440,
+ "narHash": "sha256-jy1LB8HOMKGJEGXgzFRLDU1CBGL0/LlkolgnqIsF0D8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "04a75b2eecc0acf6239acf9dd04485ff8d14f425",
"type": "github"
},
"original": {
- "owner": "hyprwm",
- "repo": "Hyprland",
+ "owner": "NixOS",
+ "ref": "nixos-22.11-small",
+ "repo": "nixpkgs",
"type": "github"
}
},
- "hyprland-protocols": {
- "inputs": {
- "nixpkgs": [
- "hyprland",
- "nixpkgs"
- ],
- "systems": [
- "hyprland",
- "systems"
- ]
- },
+ "nixpkgs_9": {
"locked": {
- "lastModified": 1691753796,
- "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
- "owner": "hyprwm",
- "repo": "hyprland-protocols",
- "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
+ "lastModified": 1697723726,
+ "narHash": "sha256-SaTWPkI8a5xSHX/rrKzUe+/uVNy6zCGMXgoeMb7T9rg=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "7c9cc5a6e5d38010801741ac830a3f8fd667a7a0",
"type": "github"
},
"original": {
- "owner": "hyprwm",
- "repo": "hyprland-protocols",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
"type": "github"
}
},
- "hyprland-protocols_2": {
- "inputs": {
- "nixpkgs": [
- "xdg-portal-hyprland",
- "nixpkgs"
- ],
- "systems": [
- "xdg-portal-hyprland",
- "systems"
- ]
- },
+ "nmd": {
+ "flake": false,
"locked": {
- "lastModified": 1691753796,
- "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
- "owner": "hyprwm",
- "repo": "hyprland-protocols",
- "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
+ "lastModified": 1696846470,
+ "narHash": "sha256-S/6s3nRcg+xZfsO7aLe01W+EMAKFVyieHa4eFvOKOLk=",
+ "owner": "horriblename",
+ "repo": "nmd",
+ "rev": "bcf805ce85b9e938f7e027b3311137ffbd995794",
"type": "github"
},
"original": {
- "owner": "hyprwm",
- "repo": "hyprland-protocols",
+ "owner": "horriblename",
+ "repo": "nmd",
"type": "github"
}
},
- "hyprpicker": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
+ "nmd_2": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1687627428,
+ "narHash": "sha256-7zGfXuNS5RHqhpEdz2fwrtqvF86JRo5U1hrxZSYgcm8=",
+ "owner": "~rycee",
+ "repo": "nmd",
+ "rev": "824a380546b5d0d0eb701ff8cd5dbafb360750ff",
+ "type": "sourcehut"
},
+ "original": {
+ "owner": "~rycee",
+ "repo": "nmd",
+ "type": "sourcehut"
+ }
+ },
+ "noice-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1691427524,
- "narHash": "sha256-3n0HJgo+3YCuo56a+efzcrh5UsfXi5jPU4tjqzJVm7g=",
- "owner": "hyprwm",
- "repo": "hyprpicker",
- "rev": "5ba32686943f839d072426d9ffd172decaee0e3e",
+ "lastModified": 1690306450,
+ "narHash": "sha256-Zca6meJkfF4fl17Y+6s77GYrqnhkkzIYW73vAhKg7e4=",
+ "owner": "folke",
+ "repo": "noice.nvim",
+ "rev": "894db25ec726d32047799d4d0a982b701bec453b",
"type": "github"
},
"original": {
- "owner": "hyprwm",
- "repo": "hyprpicker",
+ "owner": "folke",
+ "repo": "noice.nvim",
"type": "github"
}
},
- "isabel-nvim": {
+ "none-ls": {
"flake": false,
"locked": {
- "lastModified": 1691575884,
- "narHash": "sha256-42VQOHkvdqlqqs4Of0wXbrVyvvaIZIgQZx1pj3QMKY8=",
- "ref": "refs/heads/main",
- "rev": "1489357a98c4226122fff4c9574d85fdc9c84d49",
- "revCount": 11,
- "submodules": false,
- "type": "git",
- "url": "https://github.com/isabelroses/nvim"
+ "lastModified": 1697600654,
+ "narHash": "sha256-dDMZEgT5uG31bEsLiX9r6MJlOJUdQyeTPJAeRcY2z7s=",
+ "owner": "nvimtools",
+ "repo": "none-ls.nvim",
+ "rev": "dc9b7e28f5573a1a2225ffb33893d23d3e052ed6",
+ "type": "github"
},
"original": {
- "submodules": false,
- "type": "git",
- "url": "https://github.com/isabelroses/nvim"
+ "owner": "nvimtools",
+ "repo": "none-ls.nvim",
+ "type": "github"
}
},
- "lanzaboote": {
- "inputs": {
- "crane": "crane_2",
- "flake-compat": "flake-compat_3",
- "flake-parts": "flake-parts_2",
- "flake-utils": "flake-utils_3",
- "nixpkgs": [
- "nixpkgs"
- ],
- "pre-commit-hooks-nix": "pre-commit-hooks-nix",
- "rust-overlay": "rust-overlay_2"
- },
+ "nui-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1692972892,
- "narHash": "sha256-ifDTnczs4c/v73LKQdmoGYO81JmysKTlR5ZUH5cr+cE=",
- "owner": "nix-community",
- "repo": "lanzaboote",
- "rev": "6d6cdf59b9d1ca6a2732c57e40f7cbd0f1eb1755",
+ "lastModified": 1689828309,
+ "narHash": "sha256-nSUs9zAX7hQ3PuFrH4zQblMfTY6ALDNggmqaQnkbR5E=",
+ "owner": "MunifTanjim",
+ "repo": "nui.nvim",
+ "rev": "9e3916e784660f55f47daa6f26053ad044db5d6a",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "lanzaboote",
+ "owner": "MunifTanjim",
+ "repo": "nui.nvim",
"type": "github"
}
},
- "lib-aggregate": {
- "inputs": {
- "flake-utils": "flake-utils_6",
- "nixpkgs-lib": "nixpkgs-lib_3"
- },
+ "nvim-autopairs": {
+ "flake": false,
"locked": {
- "lastModified": 1692878963,
- "narHash": "sha256-/pv2E36Su112vPMk5dgUED0j2v7n/Mh0p99sXdJ9cH4=",
- "owner": "nix-community",
- "repo": "lib-aggregate",
- "rev": "e74fab6aff10cd2f4241c4bf646e53f5b3203349",
+ "lastModified": 1689332359,
+ "narHash": "sha256-bu+WpW5Wfk3pS74mzVvehl7dVMHgrttmV4ZSlfwbai4=",
+ "owner": "windwp",
+ "repo": "nvim-autopairs",
+ "rev": "ae5b41ce880a6d850055e262d6dfebd362bb276e",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "lib-aggregate",
+ "owner": "windwp",
+ "repo": "nvim-autopairs",
"type": "github"
}
},
- "nekowinston-nur": {
- "inputs": {
- "crane": "crane_3",
- "flake-utils": "flake-utils_4",
- "nixpkgs": "nixpkgs_4",
- "rust-overlay": "rust-overlay_3"
- },
+ "nvim-bufferline-lua": {
+ "flake": false,
"locked": {
- "lastModified": 1692342174,
- "narHash": "sha256-AaIfb/Ecu5tai6rJLfXxQL0MGUbLYxpiIewXP4zgFC0=",
- "owner": "nekowinston",
- "repo": "nur",
- "rev": "c994b2a594cab20bedf7697351ae7353ef74a54e",
+ "lastModified": 1690184232,
+ "narHash": "sha256-MiQsYeLgADCaUf1x88q/7gO17F992HMlt1pu9dYEmp0=",
+ "owner": "akinsho",
+ "repo": "nvim-bufferline.lua",
+ "rev": "99f0932365b34e22549ff58e1bea388465d15e99",
"type": "github"
},
"original": {
- "owner": "nekowinston",
- "repo": "nur",
+ "owner": "akinsho",
+ "repo": "nvim-bufferline.lua",
"type": "github"
}
},
- "nh": {
- "inputs": {
- "flake-parts": "flake-parts_3",
- "nix-filter": "nix-filter",
- "nixpkgs": [
- "nixpkgs"
- ]
- },
+ "nvim-cmp": {
+ "flake": false,
"locked": {
- "lastModified": 1691768450,
- "narHash": "sha256-NbHI+0WrHxGj34AAzS6V3bj5EJK/YBKlmvbrkwkCxhs=",
- "owner": "viperML",
- "repo": "nh",
- "rev": "6dcca8fc2a8873161ad60300d8ecad13326176d8",
+ "lastModified": 1688965049,
+ "narHash": "sha256-Hq6YUfMQo1rHoay3/NieGCne7U/f06GwUPhN2HO0PdQ=",
+ "owner": "hrsh7th",
+ "repo": "nvim-cmp",
+ "rev": "c4e491a87eeacf0408902c32f031d802c7eafce8",
"type": "github"
},
"original": {
- "owner": "viperML",
- "repo": "nh",
+ "owner": "hrsh7th",
+ "repo": "nvim-cmp",
"type": "github"
}
},
- "nil": {
- "inputs": {
- "flake-utils": "flake-utils_5",
- "nixpkgs": [
- "nixpkgs"
- ],
- "rust-overlay": [
- "rust-overlay"
- ]
- },
+ "nvim-code-action-menu": {
+ "flake": false,
"locked": {
- "lastModified": 1691372739,
- "narHash": "sha256-fZ8KfBMcIFO/R7xaWtB85SFeuUjb9SCH8fxYBnY8068=",
- "owner": "oxalica",
- "repo": "nil",
- "rev": "97abe7d3d48721d4e0fcc1876eea83bb4247825b",
+ "lastModified": 1671523188,
+ "narHash": "sha256-7szx+Me6WhrANbmfQ6C6gfSVB2owd02b3iZYhz7K6wY=",
+ "owner": "weilbith",
+ "repo": "nvim-code-action-menu",
+ "rev": "e4399dbaf6eabff998d3d5f1cbcd8d9933710027",
"type": "github"
},
"original": {
- "owner": "oxalica",
- "repo": "nil",
+ "owner": "weilbith",
+ "repo": "nvim-code-action-menu",
"type": "github"
}
},
- "nix-eval-jobs": {
- "inputs": {
- "flake-parts": "flake-parts_5",
- "nixpkgs": "nixpkgs_6",
- "treefmt-nix": "treefmt-nix"
- },
+ "nvim-colorizer-lua": {
+ "flake": false,
"locked": {
- "lastModified": 1692841356,
- "narHash": "sha256-ppV8EdbH6s4+E9YeHhF1+MrEO/R36PeFE/6zjHS4Pn8=",
- "owner": "nix-community",
- "repo": "nix-eval-jobs",
- "rev": "3681d5930d1479898758b752f2d77be0c8e0f90f",
+ "lastModified": 1591879145,
+ "narHash": "sha256-6YrnItxExL2C8pNIdLd+hXCjsB2MbZANwWkah6dreD8=",
+ "owner": "norcalli",
+ "repo": "nvim-colorizer.lua",
+ "rev": "36c610a9717cc9ec426a07c8e6bf3b3abcb139d6",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "nix-eval-jobs",
+ "owner": "norcalli",
+ "repo": "nvim-colorizer.lua",
"type": "github"
}
},
- "nix-filter": {
+ "nvim-compe": {
+ "flake": false,
"locked": {
- "lastModified": 1687178632,
- "narHash": "sha256-HS7YR5erss0JCaUijPeyg2XrisEb959FIct3n2TMGbE=",
- "owner": "numtide",
- "repo": "nix-filter",
- "rev": "d90c75e8319d0dd9be67d933d8eb9d0894ec9174",
+ "lastModified": 1633188506,
+ "narHash": "sha256-Y2oqvsuAKM3qjmmtJVD9z34682eCRF25kPL+rxhhg7I=",
+ "owner": "hrsh7th",
+ "repo": "nvim-compe",
+ "rev": "d186d739c54823e0b010feb205c6f97792322c08",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "nix-filter",
+ "owner": "hrsh7th",
+ "repo": "nvim-compe",
"type": "github"
}
},
- "nix-gaming": {
- "inputs": {
- "flake-parts": "flake-parts_4",
- "nixpkgs": [
- "nixpkgs"
- ]
- },
+ "nvim-cursorline": {
+ "flake": false,
"locked": {
- "lastModified": 1692977085,
- "narHash": "sha256-eFq6bcDirufyYO1qsh4KlxLSRWlNDZG/ZFeVcikoJ4E=",
- "owner": "fufexan",
- "repo": "nix-gaming",
- "rev": "bc33c7297e8299e074f3a238bac52dc9e84b13e4",
+ "lastModified": 1650034925,
+ "narHash": "sha256-Uhw65p1KBjs8KsVOmTzuiu3XKclxBob8AVdWEt30C/8=",
+ "owner": "yamatsum",
+ "repo": "nvim-cursorline",
+ "rev": "804f0023692653b2b2368462d67d2a87056947f9",
"type": "github"
},
"original": {
- "owner": "fufexan",
- "repo": "nix-gaming",
+ "owner": "yamatsum",
+ "repo": "nvim-cursorline",
"type": "github"
}
},
- "nix-ld": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
- },
+ "nvim-dap": {
+ "flake": false,
"locked": {
- "lastModified": 1686849676,
- "narHash": "sha256-+z9t7BLugZO1WhyYEq6FI38TMh2EwfgfAv3RDFSjwtc=",
- "owner": "Mic92",
- "repo": "nix-ld",
- "rev": "3abd605e56b5b34ec630bb10ba85f98c93cc05b2",
+ "lastModified": 1690444190,
+ "narHash": "sha256-OSJA+K8eGj87RWo2tE0kT6bAItGkMMtuR0HB8WEXZ4k=",
+ "owner": "mfussenegger",
+ "repo": "nvim-dap",
+ "rev": "2f28ea843bcdb378b171a66ddcd568516e431d55",
"type": "github"
},
"original": {
- "owner": "Mic92",
- "repo": "nix-ld",
+ "owner": "mfussenegger",
+ "repo": "nvim-dap",
"type": "github"
}
},
- "nixpak": {
- "inputs": {
- "flake-parts": [
- "schizofox",
- "flake-parts"
- ],
- "hercules-ci-effects": "hercules-ci-effects",
- "nixpkgs": [
- "schizofox",
- "nixpkgs"
- ]
- },
+ "nvim-dap-ui": {
+ "flake": false,
"locked": {
- "lastModified": 1692831528,
- "narHash": "sha256-EG/hn6KpDCfQSVHoKoxU+4MgMs8gJzrrHtpo2atTvWo=",
- "owner": "nixpak",
- "repo": "nixpak",
- "rev": "8b331d0e2f46c72731303311f65f3690b1917816",
+ "lastModified": 1689371609,
+ "narHash": "sha256-z6TFe7+r/g2tfgdXr6PCPri5lSboi66zZmsdyWTI1BM=",
+ "owner": "rcarriga",
+ "repo": "nvim-dap-ui",
+ "rev": "85b16ac2309d85c88577cd8ee1733ce52be8227e",
"type": "github"
},
"original": {
- "owner": "nixpak",
- "repo": "nixpak",
+ "owner": "rcarriga",
+ "repo": "nvim-dap-ui",
"type": "github"
}
},
- "nixpkgs": {
+ "nvim-lightbulb": {
+ "flake": false,
"locked": {
- "lastModified": 1692808169,
- "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "9201b5ff357e781bf014d0330d18555695df7ba8",
+ "lastModified": 1689887436,
+ "narHash": "sha256-Meoop66jINllnxN6aohuPmU7DEjn64FMq/b8zuy9FEQ=",
+ "owner": "kosayoda",
+ "repo": "nvim-lightbulb",
+ "rev": "8f00b89dd1b1dbde16872bee5fbcee2e58c9b8e9",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
+ "owner": "kosayoda",
+ "repo": "nvim-lightbulb",
"type": "github"
}
},
- "nixpkgs-22_11": {
+ "nvim-lspconfig": {
+ "flake": false,
"locked": {
- "lastModified": 1669558522,
- "narHash": "sha256-yqxn+wOiPqe6cxzOo4leeJOp1bXE/fjPEi/3F/bBHv8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "ce5fe99df1f15a09a91a86be9738d68fadfbad82",
+ "lastModified": 1690356683,
+ "narHash": "sha256-Ama9nLC/T1wJWal6bKvgY0ywUUiJ5VLuIxoY1xbJKtY=",
+ "owner": "neovim",
+ "repo": "nvim-lspconfig",
+ "rev": "b6091272422bb0fbd729f7f5d17a56d37499c54f",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "ref": "nixos-22.11",
- "type": "indirect"
+ "owner": "neovim",
+ "repo": "nvim-lspconfig",
+ "type": "github"
}
},
- "nixpkgs-23_05": {
+ "nvim-navbuddy": {
+ "flake": false,
"locked": {
- "lastModified": 1684782344,
- "narHash": "sha256-SHN8hPYYSX0thDrMLMWPWYulK3YFgASOrCsIL3AJ78g=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "8966c43feba2c701ed624302b6a935f97bcbdf88",
+ "lastModified": 1688569844,
+ "narHash": "sha256-011RT/wnQdBR1vMrXFwxbicBAgdcd4eQYPbok/o3CIE=",
+ "owner": "SmiteshP",
+ "repo": "nvim-navbuddy",
+ "rev": "244a4cded6f2b568403684131d148048efe4e8af",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "ref": "nixos-23.05",
- "type": "indirect"
+ "owner": "SmiteshP",
+ "repo": "nvim-navbuddy",
+ "type": "github"
}
},
- "nixpkgs-lib": {
+ "nvim-navic": {
+ "flake": false,
"locked": {
- "dir": "lib",
- "lastModified": 1688049487,
- "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9",
+ "lastModified": 1689944100,
+ "narHash": "sha256-M7BT1C9xHyLgr22JI3b+wyD+bYs6FgKc6PIqMrXnNr4=",
+ "owner": "SmiteshP",
+ "repo": "nvim-navic",
+ "rev": "9c89730da6a05acfeb6a197e212dfadf5aa60ca0",
"type": "github"
},
"original": {
- "dir": "lib",
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "SmiteshP",
+ "repo": "nvim-navic",
"type": "github"
}
},
- "nixpkgs-lib_2": {
+ "nvim-neoclip": {
+ "flake": false,
"locked": {
- "dir": "lib",
- "lastModified": 1690881714,
- "narHash": "sha256-h/nXluEqdiQHs1oSgkOOWF+j8gcJMWhwnZ9PFabN6q0=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "9e1960bc196baf6881340d53dccb203a951745a2",
+ "lastModified": 1684196333,
+ "narHash": "sha256-96AwMgyC7PTDEPS5tXwDT3WfK8jJJuIYGE+q+j6U5Uc=",
+ "owner": "AckslD",
+ "repo": "nvim-neoclip.lua",
+ "rev": "4e406ae0f759262518731538f2585abb9d269bac",
"type": "github"
},
"original": {
- "dir": "lib",
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "AckslD",
+ "repo": "nvim-neoclip.lua",
"type": "github"
}
},
- "nixpkgs-lib_3": {
+ "nvim-notify": {
+ "flake": false,
"locked": {
- "lastModified": 1692492218,
- "narHash": "sha256-sBj4dllTXEuBzVUaXGvWrQt3iwr64wlnVP26ZcaND0E=",
- "owner": "nix-community",
- "repo": "nixpkgs.lib",
- "rev": "2a3f8763738dca95b14705619c5e489912b7f36a",
+ "lastModified": 1685978736,
+ "narHash": "sha256-Rr2tzuEr06M9ZbvQbC07qcxkyjFJFYdABwRpYelKBFI=",
+ "owner": "rcarriga",
+ "repo": "nvim-notify",
+ "rev": "ea9c8ce7a37f2238f934e087c255758659948e0f",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "nixpkgs.lib",
+ "owner": "rcarriga",
+ "repo": "nvim-notify",
"type": "github"
}
},
- "nixpkgs-stable": {
+ "nvim-session-manager": {
+ "flake": false,
"locked": {
- "lastModified": 1685801374,
- "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
+ "lastModified": 1689976511,
+ "narHash": "sha256-04GL+0JdtD2hEOSrRJUh3Wdpoy2igjHt95Nf3WioFU4=",
+ "owner": "Shatur",
+ "repo": "neovim-session-manager",
+ "rev": "4883372b1ef2bdcf4cbdac44c98d68c216914462",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-23.05",
- "repo": "nixpkgs",
+ "owner": "Shatur",
+ "repo": "neovim-session-manager",
"type": "github"
}
},
- "nixpkgs-wayland": {
- "inputs": {
- "flake-compat": "flake-compat_4",
- "lib-aggregate": "lib-aggregate",
- "nix-eval-jobs": "nix-eval-jobs",
- "nixpkgs": [
- "nixpkgs"
- ],
- "nixpkgs_sirula": "nixpkgs_sirula"
- },
+ "nvim-surround": {
+ "flake": false,
"locked": {
- "lastModified": 1692995783,
- "narHash": "sha256-0/QfEw4sDMNxBxJiHsyP+2xgf0P9/J5y1OiKsdU4yoA=",
- "owner": "nix-community",
- "repo": "nixpkgs-wayland",
- "rev": "98d723cc5ab8a10f584f39fcf7505d3f7193247a",
+ "lastModified": 1685464327,
+ "narHash": "sha256-r3D5WTqEnIL1T3p7cmkRmBY8qgwFFJptM7BKNNsCT8k=",
+ "owner": "kylechui",
+ "repo": "nvim-surround",
+ "rev": "10b20ca7d9da1ac8df8339e140ffef94f9ab3b18",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "nixpkgs-wayland",
+ "owner": "kylechui",
+ "repo": "nvim-surround",
"type": "github"
}
},
- "nixpkgs_2": {
+ "nvim-tree-lua": {
+ "flake": false,
"locked": {
- "lastModified": 1685655444,
- "narHash": "sha256-6EujQNAeaUkWvpEZZcVF8qSfQrNVWFNNGbUJxv/A5a8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "e635192892f5abbc2289eaac3a73cdb249abaefd",
+ "lastModified": 1690616703,
+ "narHash": "sha256-kTbYvT21wLfiwEpQAgGZtep2GP4F9e7e6XGVpr4D1hY=",
+ "owner": "nvim-tree",
+ "repo": "nvim-tree.lua",
+ "rev": "4bd30f0137e44dcf3e74cc1164efb568f78f2b02",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "ref": "nixos-unstable",
- "type": "indirect"
+ "owner": "nvim-tree",
+ "repo": "nvim-tree.lua",
+ "type": "github"
}
},
- "nixpkgs_3": {
+ "nvim-treesitter-context": {
+ "flake": false,
"locked": {
- "lastModified": 1692638711,
- "narHash": "sha256-J0LgSFgJVGCC1+j5R2QndadWI1oumusg6hCtYAzLID4=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "91a22f76cd1716f9d0149e8a5c68424bb691de15",
+ "lastModified": 1689239188,
+ "narHash": "sha256-AJamiDezFK7l0bqb/VFm+pzBKugQNCmQ6JAWKmjH76g=",
+ "owner": "nvim-treesitter",
+ "repo": "nvim-treesitter-context",
+ "rev": "6f8f788738b968f24a108ee599c5be0031f94f06",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "nvim-treesitter",
+ "repo": "nvim-treesitter-context",
"type": "github"
}
},
- "nixpkgs_4": {
+ "nvim-ts-autotag": {
+ "flake": false,
"locked": {
- "lastModified": 1691654369,
- "narHash": "sha256-gSILTEx1jRaJjwZxRlnu3ZwMn1FVNk80qlwiCX8kmpo=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "ce5e4a6ef2e59d89a971bc434ca8ca222b9c7f5e",
+ "lastModified": 1686883732,
+ "narHash": "sha256-4qTtXYA5HyG1sADV0wsiccO/G89qEoYPmlg8tTx7h8g=",
+ "owner": "windwp",
+ "repo": "nvim-ts-autotag",
+ "rev": "6be1192965df35f94b8ea6d323354f7dc7a557e4",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "windwp",
+ "repo": "nvim-ts-autotag",
"type": "github"
}
},
- "nixpkgs_5": {
+ "nvim-web-devicons": {
+ "flake": false,
"locked": {
- "lastModified": 1692913444,
- "narHash": "sha256-1SvMQm2DwofNxXVtNWWtIcTh7GctEVrS/Xel/mdc6iY=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "18324978d632ffc55ef1d928e81630c620f4f447",
+ "lastModified": 1689474464,
+ "narHash": "sha256-FtEJBhqvs+c/Rvy4qXf3iyoMTTKrDBvQw5g63n4KEYo=",
+ "owner": "nvim-tree",
+ "repo": "nvim-web-devicons",
+ "rev": "efbfed0567ef4bfac3ce630524a0f6c8451c5534",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "nvim-tree",
+ "repo": "nvim-web-devicons",
"type": "github"
}
},
- "nixpkgs_6": {
+ "obsidian-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1692838642,
- "narHash": "sha256-Y47k7ckDN2nlH+A2hdfgNulXqKkTX8WdWCfd6l0ys0Y=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "6408fedbfacd0d323edc2512f6033dbce818672a",
+ "lastModified": 1690662423,
+ "narHash": "sha256-qemlp11QSp4BnWadN3+3ndv47e+1yS+w91GumbzQric=",
+ "owner": "epwalsh",
+ "repo": "obsidian.nvim",
+ "rev": "f81ddfa56b87fda158d3a56625a8040a7cf23fef",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "master",
- "repo": "nixpkgs",
+ "owner": "epwalsh",
+ "repo": "obsidian.nvim",
"type": "github"
}
},
- "nixpkgs_7": {
+ "onedark": {
+ "flake": false,
"locked": {
- "lastModified": 1688322751,
- "narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f",
+ "lastModified": 1689269544,
+ "narHash": "sha256-HfyYEppo9NFswYlPKnHNOZO5eiTQSORQhWAkzCmM2m4=",
+ "owner": "navarasu",
+ "repo": "onedark.nvim",
+ "rev": "cae5fdf035ee92c407a29ee2ccfcff503d2be7f1",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "navarasu",
+ "repo": "onedark.nvim",
"type": "github"
}
},
- "nixpkgs_8": {
+ "orgmode-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1670751203,
- "narHash": "sha256-XdoH1v3shKDGlrwjgrNX/EN8s3c+kQV7xY6cLCE8vcI=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "64e0bf055f9d25928c31fb12924e59ff8ce71e60",
+ "lastModified": 1690291768,
+ "narHash": "sha256-jc89zEAtHBh8785gNW/UZ9jkgTee/XYMm4+jyW7G2Oo=",
+ "owner": "nvim-orgmode",
+ "repo": "orgmode",
+ "rev": "6b6eb8eabbed4d95568fd1f5374a3dff7ed51a3b",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "ref": "nixos-unstable",
- "type": "indirect"
+ "owner": "nvim-orgmode",
+ "repo": "orgmode",
+ "type": "github"
}
},
- "nixpkgs_sirula": {
+ "oxocarbon": {
+ "flake": false,
"locked": {
- "lastModified": 1682879489,
- "narHash": "sha256-sASwo8gBt7JDnOOstnps90K1wxmVfyhsTPPNTGBPjjg=",
- "owner": "nixos",
- "repo": "nixpkgs",
- "rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0",
+ "lastModified": 1687168305,
+ "narHash": "sha256-2o++5aRDULfI35d+7psa6bk0eSXH2HwfuGjGtYGjR4w=",
+ "owner": "glyh",
+ "repo": "oxocarbon.nvim",
+ "rev": "7591d2e18df05374d612acba2b2573c7ff44dce4",
"type": "github"
},
"original": {
- "owner": "nixos",
- "repo": "nixpkgs",
- "rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0",
+ "owner": "glyh",
+ "ref": "lualine-support",
+ "repo": "oxocarbon.nvim",
"type": "github"
}
},
- "nu_scripts": {
+ "plenary-nvim": {
"flake": false,
"locked": {
- "lastModified": 1692875499,
- "narHash": "sha256-kpE+vgobYsQuh8sS3gK/yg68nQykquwteeuecjLtIrE=",
- "ref": "refs/heads/main",
- "rev": "45c051dad0e243a63608c8274b7fddd5f0b74941",
- "revCount": 729,
- "submodules": true,
- "type": "git",
- "url": "https://github.com/nushell/nu_scripts"
+ "lastModified": 1689589150,
+ "narHash": "sha256-oRtNcURQzrIRS3D88tWAl3HuFHxVJr8m/zzL7xoa/II=",
+ "owner": "nvim-lua",
+ "repo": "plenary.nvim",
+ "rev": "267282a9ce242bbb0c5dc31445b6d353bed978bb",
+ "type": "github"
},
"original": {
- "submodules": true,
- "type": "git",
- "url": "https://github.com/nushell/nu_scripts"
+ "owner": "nvim-lua",
+ "repo": "plenary.nvim",
+ "type": "github"
}
},
- "nur": {
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": "flake-compat_7",
+ "flake-utils": [
+ "flake-utils"
+ ],
+ "gitignore": "gitignore_2",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable_2"
+ },
"locked": {
- "lastModified": 1692996347,
- "narHash": "sha256-0gMI45VgTgQBonFr/utWkUyDJ7Tt+TA0pbqJXMIFU0g=",
- "owner": "nix-community",
- "repo": "nur",
- "rev": "f050fc284b58af8989b996f2e17950e55bae1332",
+ "lastModified": 1697746376,
+ "narHash": "sha256-gu77VkgdfaHgNCVufeb6WP9oqFLjwK4jHcoPZmBVF3E=",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "rev": "8cc349bfd082da8782b989cad2158c9ad5bd70fd",
"type": "github"
},
"original": {
- "owner": "nix-community",
- "repo": "nur",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
"type": "github"
}
},
@@ -1323,11 +2902,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
- "lastModified": 1689668210,
- "narHash": "sha256-XAATwDkaUxH958yXLs1lcEOmU6pSEIkatY3qjqk8X0E=",
+ "lastModified": 1697746376,
+ "narHash": "sha256-gu77VkgdfaHgNCVufeb6WP9oqFLjwK4jHcoPZmBVF3E=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
- "rev": "eb433bff05b285258be76513add6f6c57b441775",
+ "rev": "8cc349bfd082da8782b989cad2158c9ad5bd70fd",
"type": "github"
},
"original": {
@@ -1336,26 +2915,100 @@
"type": "github"
}
},
+ "presence-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1674984077,
+ "narHash": "sha256-ZpsunLsn//zYgUtmAm5FqKVueVd/Pa1r55ZDqxCimBk=",
+ "owner": "andweeb",
+ "repo": "presence.nvim",
+ "rev": "87c857a56b7703f976d3a5ef15967d80508df6e6",
+ "type": "github"
+ },
+ "original": {
+ "owner": "andweeb",
+ "repo": "presence.nvim",
+ "type": "github"
+ }
+ },
+ "project-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1680567592,
+ "narHash": "sha256-avV3wMiDbraxW4mqlEsKy0oeewaRj9Q33K8NzWoaptU=",
+ "owner": "ahmedkhalf",
+ "repo": "project.nvim",
+ "rev": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ahmedkhalf",
+ "repo": "project.nvim",
+ "type": "github"
+ }
+ },
+ "registers": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1680595111,
+ "narHash": "sha256-MeBlcF5LLk6bhIofYuG+0Z2xwc0BVqP85yNCvjH66fw=",
+ "owner": "tversteeg",
+ "repo": "registers.nvim",
+ "rev": "2ab8372bb837f05fae6b43091f10a0b725d113ca",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tversteeg",
+ "repo": "registers.nvim",
+ "type": "github"
+ }
+ },
+ "rnix-lsp": {
+ "inputs": {
+ "naersk": "naersk",
+ "nixpkgs": "nixpkgs_5",
+ "utils": "utils"
+ },
+ "locked": {
+ "lastModified": 1669555118,
+ "narHash": "sha256-F0s0m62S5bHNVWNHLZD6SeHiLrsDx98VQbRjDyIu+qQ=",
+ "owner": "nix-community",
+ "repo": "rnix-lsp",
+ "rev": "95d40673fe43642e2e1144341e86d0036abd95d9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "rnix-lsp",
+ "type": "github"
+ }
+ },
"root": {
"inputs": {
- "bella-nur": "bella-nur",
+ "ags": "ags",
+ "auto-cpufreq": "auto-cpufreq",
+ "bellado": "bellado",
"catppuccin": "catppuccin",
+ "catppuccin-toolbox": "catppuccin-toolbox",
+ "catppuccinifier": "catppuccinifier",
"devshell": "devshell",
"flake-parts": "flake-parts",
+ "flake-schemas": "flake-schemas",
+ "flake-utils": "flake-utils_4",
"home-manager": "home-manager",
"hyprland": "hyprland",
"hyprpicker": "hyprpicker",
- "isabel-nvim": "isabel-nvim",
"lanzaboote": "lanzaboote",
- "nekowinston-nur": "nekowinston-nur",
+ "neovim-flake": "neovim-flake",
"nh": "nh",
"nil": "nil",
"nix-gaming": "nix-gaming",
+ "nix-index-db": "nix-index-db",
"nix-ld": "nix-ld",
- "nixpkgs": "nixpkgs_5",
+ "nixSchemas": "nixSchemas",
+ "nixpkgs": "nixpkgs_9",
"nixpkgs-wayland": "nixpkgs-wayland",
- "nu_scripts": "nu_scripts",
- "nur": "nur",
+ "pre-commit-hooks": "pre-commit-hooks",
"rust-overlay": "rust-overlay_4",
"schizofox": "schizofox",
"simple-nixos-mailserver": "simple-nixos-mailserver",
@@ -1368,24 +3021,20 @@
"rust-overlay": {
"inputs": {
"flake-utils": [
- "bella-nur",
- "catppuccinifier",
- "crane",
+ "catppuccin-toolbox",
"flake-utils"
],
"nixpkgs": [
- "bella-nur",
- "catppuccinifier",
- "crane",
+ "catppuccin-toolbox",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1685759304,
- "narHash": "sha256-I3YBH6MS3G5kGzNuc1G0f9uYfTcNY9NYoRc3QsykLk4=",
+ "lastModified": 1697940838,
+ "narHash": "sha256-eyk92QqAoRNC0V99KOcKcBZjLPixxNBS0PRc4KlSQVs=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "c535b4f3327910c96dcf21851bbdd074d0760290",
+ "rev": "a3e829c06eadf848f13d109c7648570ce37ebccd",
"type": "github"
},
"original": {
@@ -1397,20 +3046,22 @@
"rust-overlay_2": {
"inputs": {
"flake-utils": [
- "lanzaboote",
+ "catppuccinifier",
+ "crane",
"flake-utils"
],
"nixpkgs": [
- "lanzaboote",
+ "catppuccinifier",
+ "crane",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1689906077,
- "narHash": "sha256-2tjLXKoSK7O0LYHlA6GCWL0gy2kZZno4krg+KZpDh6U=",
+ "lastModified": 1685759304,
+ "narHash": "sha256-I3YBH6MS3G5kGzNuc1G0f9uYfTcNY9NYoRc3QsykLk4=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "c88b28944129eeff5e819bdc21248dc07eb0625d",
+ "rev": "c535b4f3327910c96dcf21851bbdd074d0760290",
"type": "github"
},
"original": {
@@ -1422,20 +3073,20 @@
"rust-overlay_3": {
"inputs": {
"flake-utils": [
- "nekowinston-nur",
+ "lanzaboote",
"flake-utils"
],
"nixpkgs": [
- "nekowinston-nur",
+ "lanzaboote",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1691892594,
- "narHash": "sha256-Lt9/WUnI/ZqBYnHOC3n6Lg5jTfd/ZI+39jZx5HmolSQ=",
+ "lastModified": 1697940838,
+ "narHash": "sha256-eyk92QqAoRNC0V99KOcKcBZjLPixxNBS0PRc4KlSQVs=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "c638e10caf94caaa97fb1df74e3bb467dc9b92db",
+ "rev": "a3e829c06eadf848f13d109c7648570ce37ebccd",
"type": "github"
},
"original": {
@@ -1446,17 +3097,17 @@
},
"rust-overlay_4": {
"inputs": {
- "flake-utils": "flake-utils_7",
+ "flake-utils": "flake-utils_9",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
- "lastModified": 1692929460,
- "narHash": "sha256-zdN6UVtEml7t0WQHVy0avsE+TWJLklXnqJyiPaOa8u0=",
+ "lastModified": 1697940838,
+ "narHash": "sha256-eyk92QqAoRNC0V99KOcKcBZjLPixxNBS0PRc4KlSQVs=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "673e2d3d2a3951adc6f5e3351c9fce6ad130baed",
+ "rev": "a3e829c06eadf848f13d109c7648570ce37ebccd",
"type": "github"
},
"original": {
@@ -1465,45 +3116,80 @@
"type": "github"
}
},
+ "rust-tools": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1689033186,
+ "narHash": "sha256-jtfyDxifchznUupLSao6nmpVqaX1yO0xN+NhqS9fgxg=",
+ "owner": "simrat39",
+ "repo": "rust-tools.nvim",
+ "rev": "0cc8adab23117783a0292a0c8a2fbed1005dc645",
+ "type": "github"
+ },
+ "original": {
+ "owner": "simrat39",
+ "repo": "rust-tools.nvim",
+ "type": "github"
+ }
+ },
"schizofox": {
"inputs": {
+ "flake-compat": "flake-compat_8",
"flake-parts": [
"flake-parts"
],
+ "home-manager": "home-manager_2",
"nixpak": "nixpak",
"nixpkgs": [
"nixpkgs"
- ]
+ ],
+ "nmd": "nmd_2"
+ },
+ "locked": {
+ "lastModified": 1697945806,
+ "narHash": "sha256-2lTAyh/0J6r7og8gW8PRbJapFKD+2JuR7q84+hcHahE=",
+ "owner": "schizofox",
+ "repo": "schizofox",
+ "rev": "a4c72ef30acbd9dfbf3c14e65a385540053229c5",
+ "type": "github"
},
+ "original": {
+ "owner": "schizofox",
+ "repo": "schizofox",
+ "type": "github"
+ }
+ },
+ "scrollbar-nvim": {
+ "flake": false,
"locked": {
- "lastModified": 1692915203,
- "narHash": "sha256-NmLV78gGKTuZcUryWH6Ohp1In3epKqhy0zs9w/t48fQ=",
- "owner": "schizofox",
- "repo": "schizofox",
- "rev": "95ae463dc4360d5c8e88b4fff1a413528ea4d2f2",
+ "lastModified": 1684886154,
+ "narHash": "sha256-zLBexSxQCn9HPY04a9w/UCJP1F5ShI2X12I9xE9H0cM=",
+ "owner": "petertriho",
+ "repo": "nvim-scrollbar",
+ "rev": "35f99d559041c7c0eff3a41f9093581ceea534e8",
"type": "github"
},
"original": {
- "owner": "schizofox",
- "repo": "schizofox",
+ "owner": "petertriho",
+ "repo": "nvim-scrollbar",
"type": "github"
}
},
"simple-nixos-mailserver": {
"inputs": {
"blobs": "blobs",
- "flake-compat": "flake-compat_5",
- "nixpkgs": "nixpkgs_8",
+ "flake-compat": "flake-compat_9",
+ "nixpkgs": "nixpkgs_12",
"nixpkgs-22_11": "nixpkgs-22_11",
"nixpkgs-23_05": "nixpkgs-23_05",
- "utils": "utils"
+ "utils": "utils_3"
},
"locked": {
- "lastModified": 1689976554,
- "narHash": "sha256-uWJq3sIhkqfzPmfB2RWd5XFVooGFfSuJH9ER/r302xQ=",
+ "lastModified": 1695910380,
+ "narHash": "sha256-CyzeiXQGm8ceEOSK1dffBCfO7JNp8XhQeNkUiJ5HxgY=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
- "rev": "c63f6e7b053c18325194ff0e274dba44e8d2271e",
+ "rev": "84783b661ecf33927c534b6476beb74ea3308968",
"type": "gitlab"
},
"original": {
@@ -1513,6 +3199,22 @@
"type": "gitlab"
}
},
+ "smartcolumn": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1679417638,
+ "narHash": "sha256-DjPWBOLbzdfOQAx+6xgV1CD5NKuP1N6An2lmHNHd39Q=",
+ "owner": "m4xshen",
+ "repo": "smartcolumn.nvim",
+ "rev": "0c572e3eae48874f25b74394a486f38cadb5c958",
+ "type": "github"
+ },
+ "original": {
+ "owner": "m4xshen",
+ "repo": "smartcolumn.nvim",
+ "type": "github"
+ }
+ },
"sops": {
"inputs": {
"nixpkgs": [
@@ -1523,11 +3225,11 @@
]
},
"locked": {
- "lastModified": 1692728678,
- "narHash": "sha256-02MjG7Sb9k7eOi86CcC4GNWVOjT6gjmXFSqkRjZ8Xyk=",
+ "lastModified": 1697943852,
+ "narHash": "sha256-DaBxUPaZhQ3yLCmAATshYB7qo7NwcMvSFWz9T3bjYYY=",
"owner": "Mic92",
"repo": "sops-nix",
- "rev": "1b7b3a32d65dbcd69c217d7735fdf0a6b2184f45",
+ "rev": "30a0ba4a20703b4bfe047fe5def1fc24978e322c",
"type": "github"
},
"original": {
@@ -1536,6 +3238,39 @@
"type": "github"
}
},
+ "sqls-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1684697500,
+ "narHash": "sha256-jKFut6NZAf/eIeIkY7/2EsjsIhvZQKCKAJzeQ6XSr0s=",
+ "owner": "nanotee",
+ "repo": "sqls.nvim",
+ "rev": "4b1274b5b44c48ce784aac23747192f5d9d26207",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nanotee",
+ "repo": "sqls.nvim",
+ "type": "github"
+ }
+ },
+ "superdirt-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1611740180,
+ "narHash": "sha256-GtnqZeMFqFkVhgx2Exu0wY687cHa7mNnVCgjQd6fiIA=",
+ "owner": "musikinformatik",
+ "repo": "superdirt",
+ "rev": "7abb62e89649daa1232b9cbd6427241868abd30e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "musikinformatik",
+ "ref": "master",
+ "repo": "superdirt",
+ "type": "github"
+ }
+ },
"systems": {
"locked": {
"lastModified": 1681028828,
@@ -1567,6 +3302,36 @@
}
},
"systems_11": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_12": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_13": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
@@ -1613,16 +3378,16 @@
},
"systems_4": {
"locked": {
- "lastModified": 1689347949,
- "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
- "repo": "default-linux",
- "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
- "repo": "default-linux",
+ "repo": "default",
"type": "github"
}
},
@@ -1643,16 +3408,16 @@
},
"systems_6": {
"locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "lastModified": 1689347949,
+ "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "repo": "default-linux",
+ "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
- "repo": "default",
+ "repo": "default-linux",
"type": "github"
}
},
@@ -1701,6 +3466,127 @@
"type": "github"
}
},
+ "tabular": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1550598128,
+ "narHash": "sha256-irolBA/m3YIaezl+90h5G+xUOpad+3u44uJqDs4JCUs=",
+ "owner": "godlygeek",
+ "repo": "tabular",
+ "rev": "339091ac4dd1f17e225fe7d57b48aff55f99b23a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "godlygeek",
+ "repo": "tabular",
+ "type": "github"
+ }
+ },
+ "telescope": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690663693,
+ "narHash": "sha256-okyOr5t0e+oV3mY7Yq1ad/7f6qEEDS/ZQrqJcjktYRI=",
+ "owner": "nvim-telescope",
+ "repo": "telescope.nvim",
+ "rev": "b6fccfb0f7589a87587875206786daccba62acc3",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nvim-telescope",
+ "repo": "telescope.nvim",
+ "type": "github"
+ }
+ },
+ "tidal-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1654350756,
+ "narHash": "sha256-tONM5SYYBca0orTLH1EUOilSC1FCluWrFt8AetUx+YQ=",
+ "owner": "tidalcycles",
+ "repo": "tidal",
+ "rev": "fda9c1ecb3722698935245e5409ef8ccdfca16c8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tidalcycles",
+ "ref": "main",
+ "repo": "tidal",
+ "type": "github"
+ }
+ },
+ "tidalcycles": {
+ "inputs": {
+ "dirt-samples-src": "dirt-samples-src",
+ "nixpkgs": "nixpkgs_6",
+ "superdirt-src": "superdirt-src",
+ "tidal-src": "tidal-src",
+ "utils": "utils_2",
+ "vim-tidal-src": "vim-tidal-src",
+ "vowel-src": "vowel-src"
+ },
+ "locked": {
+ "lastModified": 1664760044,
+ "narHash": "sha256-e5LGk/tDnphory1mYhADgPnVtShofY2w/3xY09jEE2A=",
+ "owner": "mitchmindtree",
+ "repo": "tidalcycles.nix",
+ "rev": "3f3a820cd43709077d15a24fa6062de7d623a6bf",
+ "type": "github"
+ },
+ "original": {
+ "owner": "mitchmindtree",
+ "repo": "tidalcycles.nix",
+ "type": "github"
+ }
+ },
+ "todo-comments": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690569591,
+ "narHash": "sha256-Qm8AJ8omU5eCfjLt91DVxLS0R3QHbfW55ZTegB1JvWI=",
+ "owner": "folke",
+ "repo": "todo-comments.nvim",
+ "rev": "3094ead8edfa9040de2421deddec55d3762f64d1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "folke",
+ "repo": "todo-comments.nvim",
+ "type": "github"
+ }
+ },
+ "toggleterm-nvim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1689602083,
+ "narHash": "sha256-/sUulN93nRHa3Je+tXr8/i1cgCrd/wtrvMPkjG5Ofzs=",
+ "owner": "akinsho",
+ "repo": "toggleterm.nvim",
+ "rev": "00c13dccc78c09fa5da4c5edda990a363e75035e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "akinsho",
+ "repo": "toggleterm.nvim",
+ "type": "github"
+ }
+ },
+ "tokyonight": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1689285710,
+ "narHash": "sha256-x26qLaZzg7sJIc1d/5Q/DJ/YvRSc3s87PwPHTPTl+Xk=",
+ "owner": "folke",
+ "repo": "tokyonight.nvim",
+ "rev": "1ee11019f8a81dac989ae1db1a013e3d582e2033",
+ "type": "github"
+ },
+ "original": {
+ "owner": "folke",
+ "repo": "tokyonight.nvim",
+ "type": "github"
+ }
+ },
"treefmt-nix": {
"inputs": {
"nixpkgs": [
@@ -1710,11 +3596,11 @@
]
},
"locked": {
- "lastModified": 1692792358,
- "narHash": "sha256-yqKPLUvl9lFTy43+GvVRwT39k1qu7Yd0HNktZjRbUP4=",
+ "lastModified": 1697388351,
+ "narHash": "sha256-63N2eBpKaziIy4R44vjpUu8Nz5fCJY7okKrkixvDQmY=",
"owner": "numtide",
"repo": "treefmt-nix",
- "rev": "b070c28bf9d7d3ef93084aa47c01b4b6c16cdce4",
+ "rev": "aae39f64f5ecbe89792d05eacea5cb241891292a",
"type": "github"
},
"original": {
@@ -1730,11 +3616,11 @@
]
},
"locked": {
- "lastModified": 1692972530,
- "narHash": "sha256-LG+M7TjlLJ1lx2qbD1yaexvue1VAatpVandtHVEN5Lc=",
+ "lastModified": 1697388351,
+ "narHash": "sha256-63N2eBpKaziIy4R44vjpUu8Nz5fCJY7okKrkixvDQmY=",
"owner": "numtide",
"repo": "treefmt-nix",
- "rev": "843e1e1b01ac7c9e858368fffd1692cbbdbe4a0e",
+ "rev": "aae39f64f5ecbe89792d05eacea5cb241891292a",
"type": "github"
},
"original": {
@@ -1743,7 +3629,53 @@
"type": "github"
}
},
+ "trouble": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690614197,
+ "narHash": "sha256-Ee0AM8S/A8DU0hyOnZoKC1hkW0fvk0A+c3WGvPqmKcU=",
+ "owner": "folke",
+ "repo": "trouble.nvim",
+ "rev": "40aad004f53ae1d1ba91bcc5c29d59f07c5f01d3",
+ "type": "github"
+ },
+ "original": {
+ "owner": "folke",
+ "repo": "trouble.nvim",
+ "type": "github"
+ }
+ },
"utils": {
+ "locked": {
+ "lastModified": 1656928814,
+ "narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "utils_2": {
+ "locked": {
+ "lastModified": 1653893745,
+ "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "utils_3": {
"locked": {
"lastModified": 1605370193,
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
@@ -1758,9 +3690,139 @@
"type": "github"
}
},
+ "vim-dirtytalk": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690722430,
+ "narHash": "sha256-kjyLwkAk6mqK7u4+zAr+Yh+zbSiukNKtXwb7t39LUco=",
+ "owner": "psliwka",
+ "repo": "vim-dirtytalk",
+ "rev": "a49251dce1852875951d95f7013979ece5caebf0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "psliwka",
+ "repo": "vim-dirtytalk",
+ "type": "github"
+ }
+ },
+ "vim-illuminate": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1679187974,
+ "narHash": "sha256-8dL3cBjQ2iY4D4gTxKVVmOGhxcSSRuDBvmEwwFIbWsQ=",
+ "owner": "RRethy",
+ "repo": "vim-illuminate",
+ "rev": "a2907275a6899c570d16e95b9db5fd921c167502",
+ "type": "github"
+ },
+ "original": {
+ "owner": "RRethy",
+ "repo": "vim-illuminate",
+ "type": "github"
+ }
+ },
+ "vim-markdown": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1680951012,
+ "narHash": "sha256-B00rad/Bbp+kJBN/fYliOaGiUe0AfBng6gs/fVBve9A=",
+ "owner": "preservim",
+ "repo": "vim-markdown",
+ "rev": "cc82d88e2a791f54d2b6e2b26e41f743351ac947",
+ "type": "github"
+ },
+ "original": {
+ "owner": "preservim",
+ "repo": "vim-markdown",
+ "type": "github"
+ }
+ },
+ "vim-repeat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1611544268,
+ "narHash": "sha256-8rfZa3uKXB3TRCqaDHZ6DfzNbm7WaYnLvmTNzYtnKHg=",
+ "owner": "tpope",
+ "repo": "vim-repeat",
+ "rev": "24afe922e6a05891756ecf331f39a1f6743d3d5a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tpope",
+ "repo": "vim-repeat",
+ "type": "github"
+ }
+ },
+ "vim-startify": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1620487920,
+ "narHash": "sha256-//3bzFTe1WKqvQ3uYrDbk5Zu5BKq2hXQGeBhmhKIHvk=",
+ "owner": "mhinz",
+ "repo": "vim-startify",
+ "rev": "81e36c352a8deea54df5ec1e2f4348685569bed2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "mhinz",
+ "repo": "vim-startify",
+ "type": "github"
+ }
+ },
+ "vim-tidal-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1685703852,
+ "narHash": "sha256-8gyk17YLeKpLpz3LRtxiwbpsIbZka9bb63nK5/9IUoA=",
+ "owner": "tidalcycles",
+ "repo": "vim-tidal",
+ "rev": "e440fe5bdfe07f805e21e6872099685d38e8b761",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tidalcycles",
+ "ref": "master",
+ "repo": "vim-tidal",
+ "type": "github"
+ }
+ },
+ "vim-vsnip": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1678609126,
+ "narHash": "sha256-ehPnvGle7YrECn76YlSY/2V7Zeq56JGlmZPlwgz2FdE=",
+ "owner": "hrsh7th",
+ "repo": "vim-vsnip",
+ "rev": "7753ba9c10429c29d25abfd11b4c60b76718c438",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hrsh7th",
+ "repo": "vim-vsnip",
+ "type": "github"
+ }
+ },
+ "vowel-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1641306144,
+ "narHash": "sha256-zfF6cvAGDNYWYsE8dOIo38b+dIymd17Pexg0HiPFbxM=",
+ "owner": "supercollider-quarks",
+ "repo": "vowel",
+ "rev": "ab59caa870201ecf2604b3efdd2196e21a8b5446",
+ "type": "github"
+ },
+ "original": {
+ "owner": "supercollider-quarks",
+ "ref": "master",
+ "repo": "vowel",
+ "type": "github"
+ }
+ },
"vscode-server": {
"inputs": {
- "flake-utils": "flake-utils_8",
+ "flake-utils": "flake-utils_10",
"nixpkgs": [
"nixpkgs"
]
@@ -1779,22 +3841,38 @@
"type": "github"
}
},
+ "which-key": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1690570286,
+ "narHash": "sha256-B1+EHd2eH/EbD5Kip9PfhdPyyGfIkD6rsx0Z3rXvb5w=",
+ "owner": "folke",
+ "repo": "which-key.nvim",
+ "rev": "7ccf476ebe0445a741b64e36c78a682c1c6118b7",
+ "type": "github"
+ },
+ "original": {
+ "owner": "folke",
+ "repo": "which-key.nvim",
+ "type": "github"
+ }
+ },
"wlroots": {
"flake": false,
"locked": {
"host": "gitlab.freedesktop.org",
- "lastModified": 1691073628,
- "narHash": "sha256-LlxE3o3UzRY7APYVLGNKM30DBMcDifCRIQiMVSbYLIc=",
+ "lastModified": 1697909146,
+ "narHash": "sha256-jU0I6FoCKnj4zIBL4daosFWh81U1fM719Z6cae8PxSY=",
"owner": "wlroots",
"repo": "wlroots",
- "rev": "c74f89d4f84bfed0284d3908aee5d207698c70c5",
+ "rev": "47bf87ade2bd32395615a385ebde1fefbcdf79a2",
"type": "gitlab"
},
"original": {
"host": "gitlab.freedesktop.org",
"owner": "wlroots",
"repo": "wlroots",
- "rev": "c74f89d4f84bfed0284d3908aee5d207698c70c5",
+ "rev": "47bf87ade2bd32395615a385ebde1fefbcdf79a2",
"type": "gitlab"
}
},
@@ -1804,14 +3882,14 @@
"nixpkgs": [
"nixpkgs"
],
- "systems": "systems_11"
+ "systems": "systems_13"
},
"locked": {
- "lastModified": 1691841170,
- "narHash": "sha256-RCTm1/MVWYPnReMgyp7tr2ogGYo/pvw38jZaFwemgPU=",
+ "lastModified": 1697981233,
+ "narHash": "sha256-y8q4XUwx+gVK7i2eLjfR32lVo7TYvEslyzrmzYEaPZU=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
- "rev": "57a3a41ba6b358109e4fc25c6a4706b5f7d93c6b",
+ "rev": "22e7a65ff9633e1dedfa5317fdffc49f68de2ff2",
"type": "github"
},
"original": {
@@ -1836,11 +3914,11 @@
]
},
"locked": {
- "lastModified": 1691841170,
- "narHash": "sha256-RCTm1/MVWYPnReMgyp7tr2ogGYo/pvw38jZaFwemgPU=",
+ "lastModified": 1697981233,
+ "narHash": "sha256-y8q4XUwx+gVK7i2eLjfR32lVo7TYvEslyzrmzYEaPZU=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
- "rev": "57a3a41ba6b358109e4fc25c6a4706b5f7d93c6b",
+ "rev": "22e7a65ff9633e1dedfa5317fdffc49f68de2ff2",
"type": "github"
},
"original": {
@@ -1848,6 +3926,26 @@
"repo": "xdg-desktop-portal-hyprland",
"type": "github"
}
+ },
+ "zig": {
+ "inputs": {
+ "flake-compat": "flake-compat_4",
+ "flake-utils": "flake-utils_6",
+ "nixpkgs": "nixpkgs_7"
+ },
+ "locked": {
+ "lastModified": 1690718829,
+ "narHash": "sha256-GN19SrCqWxIJN+rnbv+pIkF/yynh6FG2y7jY6PZRiYw=",
+ "owner": "mitchellh",
+ "repo": "zig-overlay",
+ "rev": "92e485cc7887f57be4d2921ed077f467912b7d33",
+ "type": "github"
+ },
+ "original": {
+ "owner": "mitchellh",
+ "repo": "zig-overlay",
+ "type": "github"
+ }
}
},
"root": "root",
diff --git a/flake.nix b/flake.nix
index 14c81df49..7cb657e76 100755
--- a/flake.nix
+++ b/flake.nix
@@ -8,6 +8,7 @@
...
} @ inputs:
flake-parts.lib.mkFlake {inherit inputs;} ({withSystem, ...}: {
+ # The system archtecitures, more can be added as needed
systems = [
"x86_64-linux"
"aarch64-linux"
@@ -19,89 +20,95 @@
inputs.flake-parts.flakeModules.easyOverlay
inputs.treefmt-nix.flakeModule
- ./parts/makeSys # args that is passsed to the flake, moved away from the main file
+ # flake parts
+ ./flake/makeSys.nix # args that is passsed to the flake, moved away from the main file
+ #./flake/checks.nix # checks for the flake
+
+ # flake part programs
+ ./flake/programs/pre-commit.nix # pre-commit hooks
+ ./flake/programs/treefmt.nix # treefmt configuration
+
+ ./flake/pkgs # packages exposed to the flake
+ ./flake/overlays # overlays that make the system that bit cleaner
+ ./flake/templates # programing templates for the quick setup of new programing enviorments
+ ./flake/schemas # nix schemas. whenever they actually work
+ ./flake/modules # nixos and home-manager modules
];
flake = let
- # extended nixpkgs lib, contains my custom functions
+ # extended nixpkgs lib, with additonal features
lib = import ./lib {inherit nixpkgs inputs;};
in {
- # entry-point for nixos configurations
nixosConfigurations = import ./hosts {inherit nixpkgs self lib withSystem;};
- nixosModules = {
- # extends the steam module from nixpkgs/nixos to add a STEAM_COMPAT_TOOLS option
- steam-compat = ./modules/extra/shared/nixos/steam;
-
- # we do not want to provide a default module
- default = null;
- };
-
- homeManagerModules = {
- gtklock = ./modules/extra/shared/home-manager/gtklock;
-
- default = null;
- };
-
# build with `nix build .#images.`
+ # alternatively hosts can be built with `nix build .#nixosConfigurations.hostName.config.system.build.isoImage`
images = import ./hosts/images.nix {inherit inputs self lib;};
};
perSystem = {
config,
- inputs',
pkgs,
...
}: {
imports = [{_module.args.pkgs = config.legacyPackages;}];
- # provide the formatter for nix fmt
+ # formatter for nix fmt
formatter = pkgs.alejandra;
- devShells.default = let
- extra = import ./parts/devShell;
- in
- inputs'.devshell.legacyPackages.mkShell {
- name = "setup";
- commands = extra.shellCommands;
- env = extra.shellEnv;
- packages = with pkgs; [
- config.treefmt.build.wrapper # treewide formatter
- nil # nix ls
- alejandra # nix formatter
- git # flakes require git, and so do I
- glow # markdown viewer
- statix # lints and suggestions
- deadnix # clean up unused nix code
- ];
- };
-
- # configure treefmt
- treefmt = {
- projectRootFile = "flake.nix";
-
- programs = {
- alejandra.enable = true;
- deadnix.enable = false;
- shellcheck.enable = true;
- shfmt = {
- enable = true;
- # https://flake.parts/options/treefmt-nix.html#opt-perSystem.treefmt.programs.shfmt.indent_size
- # 0 causes shfmt to use tabs
- indent_size = 0;
- };
- };
+ devShells.default = pkgs.mkShell {
+ name = "dotfiles";
+ meta.description = "Devlopment shell for this configuration";
+
+ shellHook = ''
+ ${config.pre-commit.installationScript}
+ '';
+
+ # tell direnv to shut up
+ DIRENV_LOG_FORMAT = "";
+
+ packages = with pkgs; [
+ config.treefmt.build.wrapper # treewide formatter
+ nil # nix language server
+ alejandra # nix formatter
+ git # flakes require git
+ glow # fancy markdown viewer
+ statix # lints and suggestions
+ deadnix # clean up unused nix code
+ (pkgs.writeShellApplication {
+ name = "update";
+ text = ''
+ ${pkgs.runtimeShell}
+ nix flake update && git commit flake.lock -m "flake: bump inputs"
+ '';
+ })
+ ];
+
+ inputsFrom = [
+ config.treefmt.build.devShell
+ ];
};
};
});
inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ flake-utils.url = "github:numtide/flake-utils";
+
+ # too hard to explain
+ pre-commit-hooks = {
+ url = "github:cachix/pre-commit-hooks.nix";
+ inputs = {
+ nixpkgs.follows = "nixpkgs";
+ flake-utils.follows = "flake-utils";
+ };
+ };
# Nix helper
nh = {
@@ -109,11 +116,17 @@
inputs.nixpkgs.follows = "nixpkgs";
};
+ # Run unpatched dynamic binaries on NixOS
nix-ld = {
url = "github:Mic92/nix-ld";
inputs.nixpkgs.follows = "nixpkgs";
};
+ nix-index-db = {
+ url = "github:nix-community/nix-index-database";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+
# a tree-wide formatter
treefmt-nix = {
url = "github:numtide/treefmt-nix";
@@ -132,13 +145,12 @@
inputs.nixpkgs.follows = "nixpkgs";
};
- # Automated, pre-built packages for Wayland
+ # Packages for Wayland
nixpkgs-wayland = {
url = "github:nix-community/nixpkgs-wayland";
inputs.nixpkgs.follows = "nixpkgs";
};
- # Nix gaming packages
nix-gaming = {
url = "github:fufexan/nix-gaming";
inputs.nixpkgs.follows = "nixpkgs";
@@ -163,10 +175,11 @@
inputs.rust-overlay.follows = "rust-overlay";
};
- # Amazing themeing
+ # Amazing themeing & tools
catppuccin.url = "github:isabelroses/ctp-nix";
+ catppuccin-toolbox.url = "github:catppuccin/toolbox";
- # Secrets
+ # Secrets, shhh
sops = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
@@ -186,6 +199,12 @@
inputs.nixpkgs.follows = "nixpkgs";
};
+ # More up to date auto-cpufreq
+ auto-cpufreq = {
+ url = "github:AdnanHodzic/auto-cpufreq";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+
# Firefox but really locked down and air tight
schizofox = {
url = "github:schizofox/schizofox";
@@ -195,6 +214,21 @@
};
};
+ # cool bars
+ ags = {
+ url = "github:Aylur/ags";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+
+ # lovely app
+ bellado.url = "github:isabelroses/bellado";
+
+ # cool wallpaper maker
+ catppuccinifier = {
+ url = "github:lighttigerXIV/catppuccinifier";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+
# secure-boot on nixos
lanzaboote = {
url = "github:nix-community/lanzaboote";
@@ -204,28 +238,27 @@
# mailserver on nixos
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
- # nushell scripts
- nu_scripts = {
- type = "git";
- url = "https://github.com/nushell/nu_scripts";
- submodules = true;
- flake = false;
- };
-
- # my nvim conf
- isabel-nvim = {
- type = "git";
- url = "https://github.com/isabelroses/nvim";
- submodules = false;
- flake = false;
+ # Highly customisable nixos neovim flake
+ neovim-flake = {
+ url = "github:NotAShelf/neovim-flake";
+ inputs = {
+ nixpkgs.follows = "nixpkgs";
+ nil.follows = "nil";
+ flake-utils.follows = "flake-utils";
+ flake-parts.follows = "flake-parts";
+ };
};
# nur's
- nur.url = "github:nix-community/nur";
- bella-nur.url = "github:isabelroses/nur";
- nekowinston-nur.url = "github:nekowinston/nur";
+ # nur.url = "github:nix-community/nur";
+ # nekowinston-nur.url = "github:nekowinston/nur";
+
+ # Schemas
+ flake-schemas.url = "github:DeterminateSystems/flake-schemas";
+ nixSchemas.url = "github:DeterminateSystems/nix/flake-schemas";
};
+ # This allows for the gathering of prebuilt binaries, making building much faster
nixConfig = {
extra-substituters = [
"https://nix-community.cachix.org"
diff --git a/flake/checks.nix b/flake/checks.nix
new file mode 100644
index 000000000..f15c7b721
--- /dev/null
+++ b/flake/checks.nix
@@ -0,0 +1,14 @@
+{inputs, ...}: {
+ imports = [inputs.pre-commit-hooks.flakeModule];
+
+ perSystem = {system, ...}: {
+ checks.${system} = {
+ pre-commit = inputs.pre-commit-hooks.lib.${system}.run {
+ src = ./.;
+ hooks = {
+ alejandra.enable = true;
+ };
+ };
+ };
+ };
+}
diff --git a/parts/makeSys/default.nix b/flake/makeSys.nix
similarity index 100%
rename from parts/makeSys/default.nix
rename to flake/makeSys.nix
diff --git a/flake/modules/default.nix b/flake/modules/default.nix
new file mode 100644
index 000000000..4c5079d94
--- /dev/null
+++ b/flake/modules/default.nix
@@ -0,0 +1,19 @@
+{self, ...}: let
+ mkModule = path:
+ if builtins.isPath path
+ then self + path
+ else builtins.throw "${path} does not exist";
+in {
+ flake = {
+ nixosModules = {
+ # i do not provide a default module, so throw an error
+ default = builtins.throw "There is no default module.";
+ };
+
+ homeManagerModules = {
+ gtklock = mkModule /modules/extra/shared/home-manager/gtklock;
+
+ default = builtins.throw "There is no default module.";
+ };
+ };
+}
diff --git a/flake/overlays/btop.nix b/flake/overlays/btop.nix
new file mode 100644
index 000000000..b2a5b244b
--- /dev/null
+++ b/flake/overlays/btop.nix
@@ -0,0 +1,14 @@
+_: prev: {
+ btop =
+ if prev.stdenv.isLinux
+ then
+ prev.symlinkJoin {
+ inherit (prev.btop) passthru;
+ name = "btop-nodesktop";
+ paths = [prev.btop];
+ postBuild = ''
+ rm $out/share/applications/btop.desktop
+ '';
+ }
+ else prev.btop;
+}
diff --git a/flake/overlays/default.nix b/flake/overlays/default.nix
new file mode 100644
index 000000000..0d4bfde12
--- /dev/null
+++ b/flake/overlays/default.nix
@@ -0,0 +1,8 @@
+{lib, ...}: {
+ flake.overlays.default = lib.composeManyExtensions [
+ (import ./btop.nix)
+ (import ./fish.nix)
+ (import ./neovim.nix)
+ (import ./ranger.nix)
+ ];
+}
diff --git a/flake/overlays/fish.nix b/flake/overlays/fish.nix
new file mode 100644
index 000000000..4e7fffc90
--- /dev/null
+++ b/flake/overlays/fish.nix
@@ -0,0 +1,14 @@
+_: prev: {
+ fish =
+ if prev.stdenv.isLinux
+ then
+ prev.symlinkJoin {
+ inherit (prev.fish) passthru;
+ name = "fish-nodesktop";
+ paths = [prev.fish];
+ postBuild = ''
+ rm $out/share/applications/fish.desktop
+ '';
+ }
+ else prev.fish;
+}
diff --git a/flake/overlays/neovim.nix b/flake/overlays/neovim.nix
new file mode 100644
index 000000000..61b5c4438
--- /dev/null
+++ b/flake/overlays/neovim.nix
@@ -0,0 +1,14 @@
+_: prev: {
+ neovim =
+ if prev.stdenv.isLinux
+ then
+ prev.symlinkJoin {
+ inherit (prev.neovim) passthru;
+ name = "neovim-nodesktop";
+ paths = [prev.neovim];
+ postBuild = ''
+ rm $out/share/applications/*.desktop
+ '';
+ }
+ else prev.neovim;
+}
diff --git a/flake/overlays/ranger.nix b/flake/overlays/ranger.nix
new file mode 100644
index 000000000..a85c6c47f
--- /dev/null
+++ b/flake/overlays/ranger.nix
@@ -0,0 +1,14 @@
+_: prev: {
+ btop =
+ if prev.stdenv.isLinux
+ then
+ prev.symlinkJoin {
+ inherit (prev.ranger) passthru;
+ name = "btop-nodesktop";
+ paths = [prev.ranger];
+ postBuild = ''
+ rm $out/share/applications/ranger.desktop
+ '';
+ }
+ else prev.btop;
+}
diff --git a/flake/pkgs/cyberchef.nix b/flake/pkgs/cyberchef.nix
new file mode 100644
index 000000000..6238fdfe8
--- /dev/null
+++ b/flake/pkgs/cyberchef.nix
@@ -0,0 +1,35 @@
+{
+ pkgs ? import {},
+ stdenv ? pkgs.stdenv,
+ lib ? pkgs.lib,
+ ...
+}:
+stdenv.mkDerivation rec {
+ pname = "cyberchef";
+ version = "10.4.0";
+
+ src = pkgs.fetchzip {
+ url = "https://github.com/gchq/CyberChef/releases/download/v${version}/CyberChef_v${version}.zip";
+ sha256 = "sha256-BjdeOTVZUMitmInL/kE6a/aw/lH4YwKNWxdi0B51xzc=";
+ stripRoot = false;
+ };
+
+ nativeBuildInputs = [
+ pkgs.unzip
+ ];
+
+ phases = ["installPhase"];
+
+ installPhase = ''
+ mkdir $out
+ cp -r ${src}/* $out
+ cp -r $out/CyberChef_v${version}.html $out/index.html
+ '';
+
+ meta = with lib; {
+ description = " The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis";
+ homepage = "https://gchq.github.io/CyberChef";
+ license = licenses.mit;
+ maintainers = with maintainers; [isabelroses];
+ };
+}
diff --git a/flake/pkgs/default.nix b/flake/pkgs/default.nix
new file mode 100644
index 000000000..9dad5506c
--- /dev/null
+++ b/flake/pkgs/default.nix
@@ -0,0 +1,24 @@
+_: {
+ systems = [
+ "x86_64-linux"
+ "aarch64-linux"
+ ];
+
+ perSystem = {
+ pkgs,
+ inputs',
+ ...
+ }: {
+ packages = {
+ cybershef = pkgs.callPackage ./cyberchef.nix {};
+ # https://github.com/NixOS/nixpkgs/issues/195512
+ lutgen-rs = pkgs.callPackage ./lutgen-rs.nix {};
+ patched-gjs = pkgs.callPackage ./patched-gjs.nix {};
+ plymouth-theme-catppuccin = pkgs.callPackage ./plymouth-theme-catppuccin.nix {};
+
+ bellado = inputs'.bellado.packages.default;
+ catppuccinifier-cli = inputs'.catppuccinifier.packages.cli;
+ ags = inputs'.ags.packages.default;
+ };
+ };
+}
diff --git a/flake/pkgs/lutgen-rs.nix b/flake/pkgs/lutgen-rs.nix
new file mode 100644
index 000000000..776bd6de7
--- /dev/null
+++ b/flake/pkgs/lutgen-rs.nix
@@ -0,0 +1,28 @@
+{
+ fetchFromGitHub,
+ lib,
+ rustPlatform,
+}: let
+ commit = "76b728a876741ac724cfb8eaaac1fd467c2d5d0e";
+in
+ rustPlatform.buildRustPackage rec {
+ pname = "lutgen-rs";
+ version = builtins.substring 0 7 commit;
+
+ src = fetchFromGitHub {
+ owner = "ozwaldorf";
+ repo = pname;
+ rev = commit;
+ sha256 = "ntKNWvVP9m+GQPct9grY/1AfXGdHpLuYzTwiV1FY6vY=";
+ };
+
+ cargoSha256 = "sha256-StVgZBZ36fTneTtZAg5rlpqG0JVFlEDYFeBpk+8Hg+o=";
+
+ meta = with lib; {
+ description = "A blazingly fast interpolated LUT generator and applicator for arbitrary and popular color palettes. Theme any image to your dekstop colorscheme!";
+ homepage = "https://github.com/ozwaldorf/lutgen-rs";
+ license = licenses.mit;
+ maintainers = with maintainers; [isabelroses];
+ platforms = platforms.linux;
+ };
+ }
diff --git a/flake/pkgs/patched-gjs.nix b/flake/pkgs/patched-gjs.nix
new file mode 100644
index 000000000..40c3abb71
--- /dev/null
+++ b/flake/pkgs/patched-gjs.nix
@@ -0,0 +1,171 @@
+{
+ fetchurl,
+ lib,
+ stdenv,
+ meson,
+ mesonEmulatorHook,
+ ninja,
+ pkg-config,
+ gnome,
+ gtk3,
+ atk,
+ gobject-introspection,
+ spidermonkey_102,
+ pango,
+ cairo,
+ readline,
+ libsysprof-capture,
+ glib,
+ libxml2,
+ dbus,
+ gdk-pixbuf,
+ networkmanager,
+ harfbuzz,
+ makeWrapper,
+ wrapGAppsHook,
+ which,
+ xvfb-run,
+ nixosTests,
+ upower,
+ glib-networking,
+ gtk-layer-shell,
+}: let
+ testDeps = [
+ gtk3
+ atk
+ pango.out
+ gdk-pixbuf
+ harfbuzz
+ ];
+in
+ stdenv.mkDerivation rec {
+ pname = "gjs";
+ version = "1.76.2";
+
+ outputs = ["out" "dev" "installedTests"];
+
+ src = fetchurl {
+ url = "mirror://gnome/sources/gjs/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+ sha256 = "sha256-99jJ1lPqb9eK/kpQcg4EaqK/wHj9pjXdEwZ90ZnGJdQ=";
+ };
+
+ patches = [
+ # Hard-code various paths
+ ./patches/gjs-fix-paths.patch
+
+ # Allow installing installed tests to a separate output.
+ ./patches/gjs-installed-tests-path.patch
+ ];
+
+ nativeBuildInputs =
+ [
+ meson
+ ninja
+ pkg-config
+ makeWrapper
+ wrapGAppsHook
+ which # for locale detection
+ libxml2 # for xml-stripblanks
+ dbus # for dbus-run-session
+ gobject-introspection
+ ]
+ ++ lib.optionals (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
+ mesonEmulatorHook
+ ];
+
+ buildInputs = [
+ cairo
+ upower
+ gnome.gnome-bluetooth
+ glib-networking
+ gtk-layer-shell
+ networkmanager
+ readline
+ libsysprof-capture
+ spidermonkey_102
+ ];
+
+ nativeCheckInputs =
+ [
+ xvfb-run
+ ]
+ ++ testDeps;
+
+ propagatedBuildInputs = [
+ glib
+ ];
+
+ mesonFlags =
+ [
+ "-Dinstalled_test_prefix=${placeholder "installedTests"}"
+ ]
+ ++ lib.optionals (!stdenv.isLinux || stdenv.hostPlatform.isMusl) [
+ "-Dprofiler=disabled"
+ ];
+
+ doCheck = !stdenv.isDarwin;
+
+ postPatch =
+ ''
+ patchShebangs build/choose-tests-locale.sh
+ substituteInPlace installed-tests/debugger-test.sh --subst-var-by gjsConsole $out/bin/gjs-console
+ ''
+ + lib.optionalString stdenv.hostPlatform.isMusl ''
+ substituteInPlace installed-tests/js/meson.build \
+ --replace "'Encoding'," "#'Encoding',"
+ '';
+
+ preCheck = ''
+ # Our gobject-introspection patches make the shared library paths absolute
+ # in the GIR files. When running tests, the library is not yet installed,
+ # though, so we need to replace the absolute path with a local one during build.
+ # We are using a symlink that will be overridden during installation.
+ mkdir -p $out/lib $installedTests/libexec/installed-tests/gjs
+ ln -s $PWD/libgjs.so.0 $out/lib/libgjs.so.0
+ ln -s $PWD/installed-tests/js/libgimarshallingtests.so $installedTests/libexec/installed-tests/gjs/libgimarshallingtests.so
+ ln -s $PWD/installed-tests/js/libgjstesttools/libgjstesttools.so $installedTests/libexec/installed-tests/gjs/libgjstesttools.so
+ ln -s $PWD/installed-tests/js/libregress.so $installedTests/libexec/installed-tests/gjs/libregress.so
+ ln -s $PWD/installed-tests/js/libwarnlib.so $installedTests/libexec/installed-tests/gjs/libwarnlib.so
+ '';
+
+ postInstall = ''
+ # TODO: make the glib setup hook handle moving the schemas in other outputs.
+ installedTestsSchemaDatadir="$installedTests/share/gsettings-schemas/${pname}-${version}"
+ mkdir -p "$installedTestsSchemaDatadir"
+ mv "$installedTests/share/glib-2.0" "$installedTestsSchemaDatadir"
+ '';
+
+ postFixup = ''
+ wrapProgram "$installedTests/libexec/installed-tests/gjs/minijasmine" \
+ --prefix XDG_DATA_DIRS : "$installedTestsSchemaDatadir" \
+ --prefix GI_TYPELIB_PATH : "${lib.makeSearchPath "lib/girepository-1.0" testDeps}"
+ '';
+
+ checkPhase = ''
+ runHook preCheck
+ xvfb-run -s '-screen 0 800x600x24' \
+ meson test --print-errorlogs
+ runHook postCheck
+ '';
+
+ separateDebugInfo = stdenv.isLinux;
+
+ passthru = {
+ tests = {
+ installed-tests = nixosTests.installed-tests.gjs;
+ };
+
+ updateScript = gnome.updateScript {
+ packageName = "gjs";
+ versionPolicy = "odd-unstable";
+ };
+ };
+
+ meta = with lib; {
+ description = "JavaScript bindings for GNOME";
+ homepage = "https://gitlab.gnome.org/GNOME/gjs/blob/master/doc/Home.md";
+ license = licenses.lgpl2Plus;
+ maintainers = teams.gnome.members;
+ platforms = platforms.unix;
+ };
+ }
diff --git a/flake/pkgs/patches/gjs-fix-paths.patch b/flake/pkgs/patches/gjs-fix-paths.patch
new file mode 100644
index 000000000..5ca5372ea
--- /dev/null
+++ b/flake/pkgs/patches/gjs-fix-paths.patch
@@ -0,0 +1,13 @@
+diff --git a/installed-tests/debugger-test.sh b/installed-tests/debugger-test.sh
+index 0d118490..54c5507e 100755
+--- a/installed-tests/debugger-test.sh
++++ b/installed-tests/debugger-test.sh
+@@ -3,7 +3,7 @@
+ if test "$GJS_USE_UNINSTALLED_FILES" = "1"; then
+ gjs="$TOP_BUILDDIR/gjs-console"
+ else
+- gjs=gjs-console
++ gjs=@gjsConsole@
+ fi
+
+ echo 1..1
diff --git a/flake/pkgs/patches/gjs-installed-tests-path.patch b/flake/pkgs/patches/gjs-installed-tests-path.patch
new file mode 100644
index 000000000..09cd8eaff
--- /dev/null
+++ b/flake/pkgs/patches/gjs-installed-tests-path.patch
@@ -0,0 +1,37 @@
+diff --git a/installed-tests/meson.build b/installed-tests/meson.build
+index 04c7910f..9647908c 100644
+--- a/installed-tests/meson.build
++++ b/installed-tests/meson.build
+@@ -1,7 +1,7 @@
+ ### Installed tests ############################################################
+
+-installed_tests_execdir = get_option('prefix') / get_option('libexecdir') / 'installed-tests' / meson.project_name()
+-installed_tests_metadir = abs_datadir / 'installed-tests' / meson.project_name()
++installed_tests_execdir = get_option('installed_test_prefix') / 'libexec' / 'installed-tests' / meson.project_name()
++installed_tests_metadir = get_option('installed_test_prefix') / 'share' / 'installed-tests' / meson.project_name()
+
+ # Simple shell script tests #
+
+diff --git a/meson.build b/meson.build
+index 9ab29475..42ffe07f 100644
+--- a/meson.build
++++ b/meson.build
+@@ -557,7 +557,7 @@ install_data('installed-tests/extra/lsan.supp',
+ install_dir: get_option('datadir') / api_name / 'lsan')
+
+ if get_option('installed_tests')
+- schemadir = abs_datadir / 'glib-2.0' / 'schemas'
++ schemadir = get_option('installed_test_prefix') / 'share' / 'glib-2.0' / 'schemas'
+ install_data('installed-tests/js/org.gnome.GjsTest.gschema.xml', install_dir: schemadir)
+ meson.add_install_script('build/compile-gschemas.py', schemadir)
+ endif
+diff --git a/meson_options.txt b/meson_options.txt
+index 825ba77a..21f0323c 100644
+--- a/meson_options.txt
++++ b/meson_options.txt
+@@ -25,3 +25,5 @@ option('skip_gtk_tests', type: 'boolean', value: false,
+ description: 'Skip tests that need a display connection')
+ option('verbose_logs', type: 'boolean', value: false,
+ description: 'Enable extra log messages that may decrease performance (not allowed in release builds)')
++option('installed_test_prefix', type: 'string', value: '',
++ description: 'Prefix for installed tests')
diff --git a/flake/pkgs/plymouth-theme-catppuccin.nix b/flake/pkgs/plymouth-theme-catppuccin.nix
new file mode 100644
index 000000000..92ff16b20
--- /dev/null
+++ b/flake/pkgs/plymouth-theme-catppuccin.nix
@@ -0,0 +1,33 @@
+{
+ lib,
+ pkgs,
+ stdenvNoCC,
+}:
+stdenvNoCC.mkDerivation {
+ pname = "plymouth-theme-catppuccin";
+ version = "2022-12-10";
+
+ src = pkgs.fetchFromGitHub {
+ owner = "catppuccin";
+ repo = "plymouth";
+ rev = "d4105cf336599653783c34c4a2d6ca8c93f9281c";
+ sha256 = "sha256-quBSH8hx3gD7y1JNWAKQdTk3CmO4t1kVo4cOGbeWlNE=";
+ };
+
+ installPhase = ''
+ mkdir -p "$out/share/plymouth/themes/"
+ cp -r "themes/"* "$out/share/plymouth/themes/"
+
+ themes=("mocha" "macchiato" "frappe" "latte")
+ for dir in "''${themes[@]}"; do
+ cat "themes/catppuccin-''${dir}/catppuccin-''${dir}.plymouth" | sed "s@\/usr\/@''${out}\/@" > "''${out}/share/plymouth/themes/catppuccin-''${dir}/catppuccin-''${dir}.plymouth"
+ done
+ '';
+
+ meta = with lib; {
+ description = "Soothing pastel theme for Plymouth";
+ homepage = "https://github.com/catppuccin/plymouth";
+ license = licenses.mit;
+ platforms = platforms.linux;
+ };
+}
diff --git a/flake/pkgs/sddm.nix b/flake/pkgs/sddm.nix
new file mode 100644
index 000000000..5972c259a
--- /dev/null
+++ b/flake/pkgs/sddm.nix
@@ -0,0 +1,31 @@
+{
+ pkgs,
+ lib,
+}: let
+ commit = "7fc67d1027cdb7f4d833c5d23a8c34a0029b0661";
+in
+ pkgs.stdenv.mkDerivation {
+ pname = "sddm-catppucin";
+ version = builtins.substring 0 7 commit;
+
+ src = pkgs.fetchFromGitHub {
+ owner = "catppuccin";
+ repo = "sddm";
+ rev = commit;
+ sha256 = "sha256-SjYwyUvvx/ageqVH5MmYmHNRKNvvnF3DYMJ/f2/L+Go=";
+ };
+
+ dontBuild = true;
+ installPhase = ''
+ mkdir -p $out/
+ cp -R $src/src/catppuccin-mocha/* $out/
+ '';
+
+ meta = with lib; {
+ description = "Catppucin for SDDM";
+ homepage = "https://github.com/catppuccin/sddm";
+ license = licenses.mit;
+ maintainers = with maintainers; [isabelroses];
+ platforms = platforms.linux;
+ };
+ }
diff --git a/parts/devShell/default.nix b/flake/programs/devShell/default.nix
similarity index 100%
rename from parts/devShell/default.nix
rename to flake/programs/devShell/default.nix
diff --git a/flake/programs/pre-commit.nix b/flake/programs/pre-commit.nix
new file mode 100644
index 000000000..8e5be567e
--- /dev/null
+++ b/flake/programs/pre-commit.nix
@@ -0,0 +1,32 @@
+{inputs, ...}: {
+ imports = [inputs.pre-commit-hooks.flakeModule];
+
+ perSystem.pre-commit = let
+ excludes = ["flake.lock" "secrets.yaml"];
+
+ mkHook = name: prev:
+ {
+ inherit excludes;
+ description = "pre-commit hook for ${name}";
+ fail_fast = true;
+ verbose = true;
+ }
+ // prev;
+ in {
+ check.enable = true;
+
+ settings = {
+ inherit excludes;
+
+ hooks = {
+ alejandra = mkHook "Alejandra" {enable = true;};
+ actionlint = mkHook "actionlint" {enable = true;};
+ prettier = mkHook "prettier" {enable = true;};
+ editorconfig-checker = mkHook "editorconfig" {
+ enable = false;
+ always_run = true;
+ };
+ };
+ };
+ };
+}
diff --git a/flake/programs/treefmt.nix b/flake/programs/treefmt.nix
new file mode 100644
index 000000000..3f11cad1f
--- /dev/null
+++ b/flake/programs/treefmt.nix
@@ -0,0 +1,31 @@
+_: {
+ systems = ["x86_64-linux" "aarch64-linux"];
+
+ perSystem = {pkgs, ...}: {
+ treefmt = {
+ projectRootFile = "flake.nix";
+
+ programs = {
+ alejandra.enable = true;
+ deadnix.enable = false;
+ shellcheck.enable = true;
+
+ prettier = {
+ enable = true;
+ package = pkgs.prettierd;
+ excludes = [];
+ settings = {
+ editorconfig = true;
+ };
+ };
+
+ shfmt = {
+ enable = true;
+ # https://flake.parts/options/treefmt-nix.html#opt-perSystem.treefmt.programs.shfmt.indent_size
+ # 0 causes shfmt to use tabs
+ indent_size = 2;
+ };
+ };
+ };
+ };
+}
diff --git a/flake/schemas/default.nix b/flake/schemas/default.nix
new file mode 100644
index 000000000..e1b62968b
--- /dev/null
+++ b/flake/schemas/default.nix
@@ -0,0 +1,9 @@
+{inputs, ...}: let
+ schemas = import ./schemas.nix;
+in {
+ flake = {
+ # extensible flake schemas
+ # https://github.com/DeterminateSystems/flake-schemas
+ schemas = inputs.flake-schemas.schemas // schemas;
+ };
+}
diff --git a/flake/schemas/schemas.nix b/flake/schemas/schemas.nix
new file mode 100644
index 000000000..eb00c4f2c
--- /dev/null
+++ b/flake/schemas/schemas.nix
@@ -0,0 +1,21 @@
+{
+ homeManagerModules = {
+ version = 1;
+ doc = "The `homeManagerModules` flake output defines Home-Manager modules exported by the flake.";
+ inventory = output: let
+ recurse = attrs: {
+ children = (name: value:
+ if builtins.isAttrs value
+ then {
+ # Tell `nix flake show` what this is.
+ what = "exported home-manager module";
+ # Make `nix flake check` enforce the camel case naming convention.
+ evalChecks.camelCase = builtins.match "[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?" name == [];
+ }
+ else throw "unsupported 'homeManagerModules' type")
+ attrs;
+ };
+ in
+ recurse output;
+ };
+}
diff --git a/flake/templates/c/.editorconfig b/flake/templates/c/.editorconfig
new file mode 100644
index 000000000..f2676050e
--- /dev/null
+++ b/flake/templates/c/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.c]
+ident_style = space
+ident_size = 4
+
+[Makefile*]
+ident_style = tab
+ident_size = 4
diff --git a/flake/templates/c/default.nix b/flake/templates/c/default.nix
new file mode 100644
index 000000000..f0198681e
--- /dev/null
+++ b/flake/templates/c/default.nix
@@ -0,0 +1,9 @@
+{clangStdenv}:
+clangStdenv.mkDerivation {
+ pname = "sample-c-cpp";
+ version = "0.0.1";
+
+ src = ./.;
+
+ makeFlags = ["PREFIX=$(out)"];
+}
diff --git a/flake/templates/c/flake.nix b/flake/templates/c/flake.nix
new file mode 100644
index 000000000..2d309391e
--- /dev/null
+++ b/flake/templates/c/flake.nix
@@ -0,0 +1,25 @@
+{
+ description = "C/C++ Project Template";
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs";
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ ...
+ }: let
+ systems = ["x86_64-linux" "aarch64-linux"];
+ forEachSystem = nixpkgs.lib.genAttrs systems;
+
+ pkgsForEach = nixpkgs.legacyPackages;
+ in {
+ packages = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./default.nix {};
+ });
+
+ devShells = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./shell.nix {};
+ });
+ };
+}
diff --git a/flake/templates/c/makefile b/flake/templates/c/makefile
new file mode 100644
index 000000000..01a94a964
--- /dev/null
+++ b/flake/templates/c/makefile
@@ -0,0 +1,42 @@
+PREFIX ?= /usr/local # this is overriden by the derivation makeFlags
+BIN_DIR ?= $(PREFIX)/bin
+
+
+TARGET_EXEC ?= foo-bar
+BUILD_DIR ?= ./build
+SRC_DIRS ?= ./src
+
+SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c)
+OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
+DEPS := $(OBJS:.o=.d)
+
+INC_DIRS := $(shell find $(SRC_DIRS) -type d)
+INC_FLAGS := $(addprefix -I,$(INC_DIRS))
+
+CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
+
+$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
+ $(CXX) $(OBJS) -o $@ $(LDFLAGS)
+
+# c source
+$(BUILD_DIR)/%.c.o: %.c
+ mkdir -p $(dir $@)
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+# c++ source
+$(BUILD_DIR)/%.cpp.o: %.cpp
+ mkdir -p $(dir $@)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
+
+.PHONY: clean install run
+
+clean:
+ rm -r $(BUILD_DIR)
+
+install: $(BUILD_DIR)/$(TARGET_EXEC)
+ install -Dt $(BIN_DIR) $<
+
+run: $(BUILD_DIR)/$(TARGET_EXEC)
+ ./$<
+
+-include $(DEPS)
diff --git a/flake/templates/c/shell.nix b/flake/templates/c/shell.nix
new file mode 100644
index 000000000..7f542b918
--- /dev/null
+++ b/flake/templates/c/shell.nix
@@ -0,0 +1,19 @@
+{
+ callPackage,
+ clang-tools,
+ gnumake,
+ libcxx,
+ cppcheck,
+}: let
+ mainPkg = callPackage ./default.nix {};
+in
+ mainPkg.overrideAttrs (oa: {
+ nativeBuildInputs =
+ [
+ clang-tools # fix headers not found
+ gnumake # builder
+ libcxx # stdlib for cpp
+ cppcheck # static analysis
+ ]
+ ++ (oa.nativeBuildInputs or []);
+ })
diff --git a/flake/templates/c/src/main.cpp b/flake/templates/c/src/main.cpp
new file mode 100644
index 000000000..027a27333
--- /dev/null
+++ b/flake/templates/c/src/main.cpp
@@ -0,0 +1,7 @@
+#include
+
+int main() {
+ std::cout << "Hello, World!";
+
+ return 0;
+}
diff --git a/flake/templates/default.nix b/flake/templates/default.nix
new file mode 100644
index 000000000..9a6a52c2f
--- /dev/null
+++ b/flake/templates/default.nix
@@ -0,0 +1,28 @@
+_: {
+ flake.templates = {
+ c = {
+ path = ./c; # C/C++
+ description = "Development environment for C/C++";
+ };
+
+ rust = {
+ path = ./rust; # Rust
+ description = "Development environment for Rust";
+ };
+
+ node = {
+ path = ./node; # NodeJS
+ description = "Development environment for NodeJS";
+ };
+
+ go = {
+ path = ./go; # golang
+ description = "Development environment for Golang";
+ };
+
+ python = {
+ path = ./python; # Python
+ description = "Development environment for Python";
+ };
+ };
+}
diff --git a/flake/templates/go/default.nix b/flake/templates/go/default.nix
new file mode 100644
index 000000000..69843783c
--- /dev/null
+++ b/flake/templates/go/default.nix
@@ -0,0 +1,11 @@
+{buildGoModule}:
+buildGoModule {
+ pname = "sample-go";
+ version = "0.0.1";
+
+ src = ./.;
+
+ vendorHash = null;
+
+ ldflags = ["-s" "-w"];
+}
diff --git a/flake/templates/go/flake.nix b/flake/templates/go/flake.nix
new file mode 100644
index 000000000..0a3b2e211
--- /dev/null
+++ b/flake/templates/go/flake.nix
@@ -0,0 +1,26 @@
+{
+ description = "Golang Project Template";
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs";
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ }: let
+ systems = ["x86_64-linux" "aarch64-linux"];
+ forEachSystem = nixpkgs.lib.genAttrs systems;
+
+ pkgsForEach = nixpkgs.legacyPackages;
+ in rec {
+ packages = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./default.nix {};
+ });
+
+ devShells = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./shell.nix {};
+ });
+
+ hydraJobs = packages;
+ };
+}
diff --git a/flake/templates/go/go.mod b/flake/templates/go/go.mod
new file mode 100644
index 000000000..51af4705b
--- /dev/null
+++ b/flake/templates/go/go.mod
@@ -0,0 +1,3 @@
+module notashelf.dev/sample
+
+go 1.20
diff --git a/flake/templates/go/main.go b/flake/templates/go/main.go
new file mode 100644
index 000000000..a3dd973f0
--- /dev/null
+++ b/flake/templates/go/main.go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("Hello, World!")
+}
diff --git a/flake/templates/go/shell.nix b/flake/templates/go/shell.nix
new file mode 100644
index 000000000..57104c6b5
--- /dev/null
+++ b/flake/templates/go/shell.nix
@@ -0,0 +1,15 @@
+{
+ callPackage,
+ gopls,
+ go,
+}: let
+ mainPkg = callPackage ./default.nix {};
+in
+ mainPkg.overrideAttrs (oa: {
+ nativeBuildInputs =
+ [
+ gopls
+ go
+ ]
+ ++ (oa.nativeBuildInputs or []);
+ })
diff --git a/flake/templates/node/.gitignore b/flake/templates/node/.gitignore
new file mode 100644
index 000000000..d5397511d
--- /dev/null
+++ b/flake/templates/node/.gitignore
@@ -0,0 +1,3 @@
+result
+build
+node_modules
diff --git a/flake/templates/node/default.nix b/flake/templates/node/default.nix
new file mode 100644
index 000000000..5bb53bcb9
--- /dev/null
+++ b/flake/templates/node/default.nix
@@ -0,0 +1,12 @@
+{
+ lib,
+ buildNpmPackage,
+}:
+buildNpmPackage {
+ pname = "foo-bar";
+ version = "0.1.0";
+
+ src = ./.;
+
+ npmDepsHash = lib.fakeSha256;
+}
diff --git a/flake/templates/node/flake.nix b/flake/templates/node/flake.nix
new file mode 100644
index 000000000..d12fe4e8b
--- /dev/null
+++ b/flake/templates/node/flake.nix
@@ -0,0 +1,26 @@
+{
+ description = "NodeJS Project Template";
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs";
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ }: let
+ systems = ["x86_64-linux" "aarch64-linux"];
+ forEachSystem = nixpkgs.lib.genAttrs systems;
+
+ pkgsForEach = nixpkgs.legacyPackages;
+ in rec {
+ packages = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./default.nix {};
+ });
+
+ devShells = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./shell.nix {};
+ });
+
+ hydraJobs = packages;
+ };
+}
diff --git a/flake/templates/node/package.json b/flake/templates/node/package.json
new file mode 100644
index 000000000..d362ca6d7
--- /dev/null
+++ b/flake/templates/node/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "sample-nodejs",
+ "version": "0.0.1",
+ "description": "Sample node program",
+ "bin": {
+ "sample-node": "build/index.js"
+ },
+ "scripts": {
+ "build": "tsc",
+ "start": "npm run build && node build/index.js"
+ },
+ "author": "NotAShelf",
+ "license": "MIT",
+ "devDependencies": {
+ "@types/node": "^20.1.2",
+ "typescript": "^5.0.4",
+ "typescript-language-server": "^3.3.2"
+ }
+}
diff --git a/flake/templates/node/shell.nix b/flake/templates/node/shell.nix
new file mode 100644
index 000000000..58ec4b342
--- /dev/null
+++ b/flake/templates/node/shell.nix
@@ -0,0 +1,24 @@
+{
+ callPackage,
+ writeShellScriptBin,
+ eslint_d,
+ prettierd,
+}: let
+ mainPkg = callPackage ./default.nix {};
+ mkNpxAlias = name: writeShellScriptBin name "npx ${name} \"$@\"";
+in
+ mainPkg.overrideAttrs (oa: {
+ nativeBuildInputs =
+ [
+ eslint_d
+ prettierd
+ (mkNpxAlias "tsc")
+ (mkNpxAlias "tsserver")
+ ]
+ ++ (oa.nativeBuildInputs or []);
+
+ shellHook = ''
+ eslint_d start # start eslint daemon
+ eslint_d status # inform user about eslint daemon status
+ '';
+ })
diff --git a/flake/templates/node/src/index.ts b/flake/templates/node/src/index.ts
new file mode 100644
index 000000000..940a3ff0e
--- /dev/null
+++ b/flake/templates/node/src/index.ts
@@ -0,0 +1 @@
+console.log("Hello world!");
diff --git a/flake/templates/node/tsconfig.json b/flake/templates/node/tsconfig.json
new file mode 100644
index 000000000..0e48dd3ac
--- /dev/null
+++ b/flake/templates/node/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "target": "es2016",
+ "lib": ["es6"],
+ "module": "commonjs",
+ "rootDir": "src",
+ "resolveJsonModule": true,
+ "allowJs": true,
+ "outDir": "build",
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitAny": true,
+ "skipLibCheck": true
+ }
+}
diff --git a/flake/templates/python/.envrc b/flake/templates/python/.envrc
new file mode 100644
index 000000000..fcffbd531
--- /dev/null
+++ b/flake/templates/python/.envrc
@@ -0,0 +1 @@
+use flake . --builders ""
diff --git a/flake/templates/python/default.nix b/flake/templates/python/default.nix
new file mode 100644
index 000000000..b7c031325
--- /dev/null
+++ b/flake/templates/python/default.nix
@@ -0,0 +1,24 @@
+{
+ lib,
+ python3Packages,
+ doCheck ? false,
+ ...
+}:
+python3Packages.buildPythonApplication {
+ pname = "sample-python-project";
+ version = "0.0.1";
+
+ src = ./.;
+
+ propagatedBuildInputs = with python3Packages; [];
+
+ nativeCheckInputs = [
+ python3Packages.pytest
+ ];
+
+ checkPhase = lib.optionals doCheck ''
+ runHook preCheck
+ pytest
+ runHook postCheck
+ '';
+}
diff --git a/flake/templates/python/flake.nix b/flake/templates/python/flake.nix
new file mode 100644
index 000000000..47d3b2867
--- /dev/null
+++ b/flake/templates/python/flake.nix
@@ -0,0 +1,26 @@
+{
+ description = "Python Project Template";
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs";
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ }: let
+ systems = ["x86_64-linux" "aarch64-linux"];
+ forEachSystem = nixpkgs.lib.genAttrs systems;
+
+ pkgsForEach = nixpkgs.legacyPackages;
+ in rec {
+ packages = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./default.nix {};
+ });
+
+ devShells = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./shell.nix {};
+ });
+
+ hydraJobs = packages;
+ };
+}
diff --git a/flake/templates/python/shell.nix b/flake/templates/python/shell.nix
new file mode 100644
index 000000000..9fa8a1229
--- /dev/null
+++ b/flake/templates/python/shell.nix
@@ -0,0 +1,13 @@
+{
+ callPackage,
+ mkShellNoCC,
+ python3,
+ ...
+}: let
+ defaultPackage = callPackage ./default.nix;
+in
+ mkShellNoCC {
+ packages = [
+ (python3.withPackages defaultPackage.propagatedBuildInputs)
+ ];
+ }
diff --git a/flake/templates/rust/Cargo.toml b/flake/templates/rust/Cargo.toml
new file mode 100644
index 000000000..c0a1285bd
--- /dev/null
+++ b/flake/templates/rust/Cargo.toml
@@ -0,0 +1,5 @@
+[package]
+name = "sample-rust"
+version = "0.0.1"
+license = "MIT"
+edition = "2021"
diff --git a/flake/templates/rust/default.nix b/flake/templates/rust/default.nix
new file mode 100644
index 000000000..58798a6cc
--- /dev/null
+++ b/flake/templates/rust/default.nix
@@ -0,0 +1,8 @@
+{rustPlatform}:
+rustPlatform.buildRustPackage {
+ pname = "sample-rust";
+ version = "0.0.1";
+
+ src = ./.;
+ cargoLock.lockFile = ./Cargo.lock;
+}
diff --git a/flake/templates/rust/flake.nix b/flake/templates/rust/flake.nix
new file mode 100644
index 000000000..0b7a0ddf7
--- /dev/null
+++ b/flake/templates/rust/flake.nix
@@ -0,0 +1,26 @@
+{
+ description = "Rust Project Template";
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs";
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ }: let
+ systems = ["x86_64-linux" "aarch64-linux"];
+ forEachSystem = nixpkgs.lib.genAttrs systems;
+
+ pkgsForEach = nixpkgs.legacyPackages;
+ in rec {
+ packages = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./default.nix {};
+ });
+
+ devShells = forEachSystem (system: {
+ default = pkgsForEach.${system}.callPackage ./shell.nix {};
+ });
+
+ hydraJobs = packages;
+ };
+}
diff --git a/flake/templates/rust/shell.nix b/flake/templates/rust/shell.nix
new file mode 100644
index 000000000..6b184ad26
--- /dev/null
+++ b/flake/templates/rust/shell.nix
@@ -0,0 +1,18 @@
+{
+ callPackage,
+ rust-analyzer,
+ rustfmt,
+ clippy,
+}: let
+ mainPkg = callPackage ./default.nix {};
+in
+ mainPkg.overrideAttrs (oa: {
+ nativeBuildInputs =
+ [
+ # Additional rust tooling
+ rust-analyzer
+ rustfmt
+ clippy
+ ]
+ ++ (oa.nativeBuildInputs or []);
+ })
diff --git a/flake/templates/rust/src/main.rs b/flake/templates/rust/src/main.rs
new file mode 100644
index 000000000..a30eb952c
--- /dev/null
+++ b/flake/templates/rust/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/home/default.nix b/home/default.nix
index 8d1a3168b..b09ea046b 100644
--- a/home/default.nix
+++ b/home/default.nix
@@ -7,11 +7,9 @@
lib,
...
}: let
- inherit (config) modules;
- env = modules.usrEnv;
- defaults = config.modules.programs.default;
+ inherit (config.modules.programs) defaults;
in {
- home-manager = lib.mkIf env.useHomeManager {
+ home-manager = {
verbose = true;
useUserPackages = true;
useGlobalPkgs = true;
diff --git a/home/isabel/default.nix b/home/isabel/default.nix
index 9f5d8e04e..6eddd07ca 100644
--- a/home/isabel/default.nix
+++ b/home/isabel/default.nix
@@ -1,6 +1,5 @@
{
inputs,
- config,
lib,
self,
...
@@ -12,22 +11,15 @@ in {
inputs.catppuccin.homeManagerModules.catppuccin
self.homeManagerModules.gtklock
- # important system level configurations
+ # important system enviroment config
./system
-
- # programs sets
+ # programs that are used, e.g. GUI apps
./programs
-
# system services, organized by display protocol
./services
-
- # declarative system and program themes (qt/gtk)
+ # Application themeing
./themes
-
- # dev shells
- ./shells
-
- # other settings that can't be organized as easly
+ # Other data that can't be organized as easly
./misc
];
config = {
@@ -43,7 +35,7 @@ in {
};
manual = {
- # the docs suck, so we disable them to save space
+ # I don't use docs, so just disable them
html.enable = false;
json.enable = false;
manpages.enable = false;
diff --git a/home/isabel/misc/pfps/avatar b/home/isabel/misc/pfps/avatar
index fdddfe2d6..def5e2060 100644
Binary files a/home/isabel/misc/pfps/avatar and b/home/isabel/misc/pfps/avatar differ
diff --git a/home/isabel/misc/pfps/avatar2 b/home/isabel/misc/pfps/avatar2
new file mode 100644
index 000000000..fdddfe2d6
Binary files /dev/null and b/home/isabel/misc/pfps/avatar2 differ
diff --git a/home/isabel/programs/cli/confs/bat.nix b/home/isabel/programs/cli/confs/bat.nix
index 4c18fab7c..5bd9457dc 100644
--- a/home/isabel/programs/cli/confs/bat.nix
+++ b/home/isabel/programs/cli/confs/bat.nix
@@ -2,14 +2,10 @@
osConfig,
lib,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
- device = osConfig.modules.device;
-
+}: let
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.cli.enable)) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && lib.isModernShell osConfig) {
programs.bat = {
enable = true;
catppuccin.enable = true;
diff --git a/home/isabel/programs/cli/confs/default.nix b/home/isabel/programs/cli/confs/default.nix
index 57e65fc11..0eef6963f 100644
--- a/home/isabel/programs/cli/confs/default.nix
+++ b/home/isabel/programs/cli/confs/default.nix
@@ -1,9 +1,7 @@
_: {
imports = [
- ./fish
- ./nushell
-
./bat.nix
+ ./eza.nix
./git.nix
./nix-shell.nix
./starship.nix
diff --git a/home/isabel/programs/cli/confs/eza.nix b/home/isabel/programs/cli/confs/eza.nix
new file mode 100644
index 000000000..8fd34a61f
--- /dev/null
+++ b/home/isabel/programs/cli/confs/eza.nix
@@ -0,0 +1,19 @@
+{
+ osConfig,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf isModernShell;
+in {
+ config = mkIf (isModernShell osConfig) {
+ programs.eza = {
+ enable = true;
+ icons = true;
+ enableAliases = true;
+ extraOptions = [
+ "--group-directories-first"
+ "--header"
+ ];
+ };
+ };
+}
diff --git a/home/isabel/programs/cli/confs/fish/default.nix b/home/isabel/programs/cli/confs/fish/default.nix
deleted file mode 100644
index ca70ad44f..000000000
--- a/home/isabel/programs/cli/confs/fish/default.nix
+++ /dev/null
@@ -1,59 +0,0 @@
-{osConfig, ...}: let
- sys = osConfig.modules.system;
- #symlink = fileName: {recursive ? false}: {
- # source = config.lib.file.mkOutOfStoreSymlink "${sys.flakePath}/${fileName}";
- # inherit recursive;
- #};
-in {
- programs.fish = {
- enable = true;
- catppuccin.enable = true;
- plugins = [];
- functions = {
- bj = "nohup $argv /dev/null &";
- "." = ''
- set -l input $argv[1]
- if echo $input | grep -q '^[1-9][0-9]*$'
- set -l levels $input
- for i in (seq $levels)
- cd ..
- end
- else
- echo "Invalid input format. Please use '' to go back a specific number of directories."
- end
- '';
- };
- shellAliases = {
- # ls to exa
- ls = "exa -al --color=always --icons --group-directories-first";
- la = "command exa -a --color=always --icons --group-directories-first";
- ll = "exa -abghHliS --icons --group-directories-first";
- lt = "exa -aT --color=always --icons --group-directories-first";
-
- mkidr = "mkdir -pv"; # always create pearent directory
- df = "df -h"; # human readblity
- rs = "sudo reboot";
- sysctl = "sudo systemctl";
- doas = "doas --";
- jctl = "journalctl -p 3 -xb"; # get error messages from journalctl
- lg = "lazygit";
-
- # nix stuff
- ssp = "~/shells/spawnshell.sh";
- rebuild = "sudo nixos-rebuild switch --flake ${sys.flakePath}#${sys.hostname}";
- nixclean = "sudo nix-collect-garbage --delete-older-than 3d && nix-collect-garbage -d";
- nixrepair = "nix-store --verify --check-contents --repair";
- };
- shellAbbrs = {};
- shellInit = ''
- starship init fish | source
- set -x MANPAGER "sh -c 'col -bx | bat -l man -p'"
- set TERM "xterm-256color"
- set fish_greeting
- set TERMINAL "alacritty"
- export "MICRO_TRUECOLOR=1"
- export GPG_TTY=$(tty)
- '';
- };
- #xdg.configFile."fish/conf.d" = symlink "home/${sys.username}/programs/cli/confs/fish/conf.d" {recursive = true;};
-}
diff --git a/home/isabel/programs/cli/confs/git.nix b/home/isabel/programs/cli/confs/git.nix
index 66be02234..afe8bb2f1 100644
--- a/home/isabel/programs/cli/confs/git.nix
+++ b/home/isabel/programs/cli/confs/git.nix
@@ -10,14 +10,14 @@ in {
home.packages = with pkgs; [
gist # manage github gists
act # local github actions
- gitflow
+ gitflow # Extend git with the Gitflow branching model
];
programs = {
# github cli
gh = {
enable = true;
- gitCredentialHelper.enable = false;
+ gitCredentialHelper.enable = false; # i use sops for this anyways
extensions = with pkgs; [
gh-cal # github activity stats in the CLI
gh-dash # dashboard with pull requests and issues
@@ -39,6 +39,7 @@ in {
key = cfg.signingKey;
signByDefault = true;
};
+ lfs.enable = true;
ignores = [
"*.bak"
"*.swp"
@@ -56,7 +57,7 @@ in {
"result-*"
];
extraConfig = {
- init.defaultBranch = "main";
+ init.defaultBranch = "main"; # warning the AUR hates this
branch.autosetupmerge = "true";
pull.ff = "only";
@@ -99,21 +100,20 @@ in {
"ssh://git@codeberg.org/".pushInsteadOf = "codeberg:";
};
};
- lfs.enable = true;
+
aliases = {
+ st = "status";
br = "branch";
c = "commit -m";
ca = "commit -am";
co = "checkout";
d = "diff";
df = "!git hist | peco | awk '{print $2}' | xargs -I {} git diff {}^ {}";
- edit-unmerged = "!f() { git ls-files --unmerged | cut -f2 | sort -u ; }; vim `f`";
fuck = "commit --amend -m";
graph = "log --all --decorate --graph";
ps = "!git push origin $(git rev-parse --abbrev-ref HEAD)";
pl = "!git pull origin $(git rev-parse --abbrev-ref HEAD)";
af = "!git add $(git ls-files -m -o --exclude-standard | fzf -m)";
- st = "status";
hist = ''
log --pretty=format:"%Cgreen%h %Creset%cd %Cblue[%cn] %Creset%s%C(yellow)%d%C(reset)" --graph --date=relative --decorate --all
'';
diff --git a/home/isabel/programs/cli/confs/nix-shell.nix b/home/isabel/programs/cli/confs/nix-shell.nix
index 39928f6d2..0b3ce7dd2 100644
--- a/home/isabel/programs/cli/confs/nix-shell.nix
+++ b/home/isabel/programs/cli/confs/nix-shell.nix
@@ -3,34 +3,11 @@
lib,
pkgs,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
- device = osConfig.modules.device;
-
- acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
-in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.cli.enable)) {
- home = {
- packages = with pkgs; [
- alejandra
- deadnix
- nix-index
- nix-tree
- statix
- nil
- ];
-
- sessionVariables = {
- DIRENV_LOG_FORMAT = "";
- };
- };
-
- programs.direnv = {
- enable = true;
- nix-direnv = {
- enable = true;
- };
- };
+}: {
+ config = lib.mkIf osConfig.modules.programs.cli.enable {
+ home.packages = with pkgs; [
+ alejandra
+ nix-tree
+ ];
};
}
diff --git a/home/isabel/programs/cli/confs/nushell/config.nu b/home/isabel/programs/cli/confs/nushell/config.nu
deleted file mode 100644
index 4a5d55d2a..000000000
--- a/home/isabel/programs/cli/confs/nushell/config.nu
+++ /dev/null
@@ -1,241 +0,0 @@
-let catppuccin = {
- latte: {
- rosewater: "#dc8a78"
- flamingo: "#dd7878"
- pink: "#ea76cb"
- mauve: "#8839ef"
- red: "#d20f39"
- maroon: "#e64553"
- peach: "#fe640b"
- yellow: "#df8e1d"
- green: "#40a02b"
- teal: "#179299"
- sky: "#04a5e5"
- sapphire: "#209fb5"
- blue: "#1e66f5"
- lavender: "#7287fd"
- text: "#4c4f69"
- subtext1: "#5c5f77"
- subtext0: "#6c6f85"
- overlay2: "#7c7f93"
- overlay1: "#8c8fa1"
- overlay0: "#9ca0b0"
- surface2: "#acb0be"
- surface1: "#bcc0cc"
- surface0: "#ccd0da"
- crust: "#dce0e8"
- mantle: "#e6e9ef"
- base: "#eff1f5"
- }
- frappe: {
- rosewater: "#f2d5cf"
- flamingo: "#eebebe"
- pink: "#f4b8e4"
- mauve: "#ca9ee6"
- red: "#e78284"
- maroon: "#ea999c"
- peach: "#ef9f76"
- yellow: "#e5c890"
- green: "#a6d189"
- teal: "#81c8be"
- sky: "#99d1db"
- sapphire: "#85c1dc"
- blue: "#8caaee"
- lavender: "#babbf1"
- text: "#c6d0f5"
- subtext1: "#b5bfe2"
- subtext0: "#a5adce"
- overlay2: "#949cbb"
- overlay1: "#838ba7"
- overlay0: "#737994"
- surface2: "#626880"
- surface1: "#51576d"
- surface0: "#414559"
- base: "#303446"
- mantle: "#292c3c"
- crust: "#232634"
- }
- macchiato: {
- rosewater: "#f4dbd6"
- flamingo: "#f0c6c6"
- pink: "#f5bde6"
- mauve: "#c6a0f6"
- red: "#ed8796"
- maroon: "#ee99a0"
- peach: "#f5a97f"
- yellow: "#eed49f"
- green: "#a6da95"
- teal: "#8bd5ca"
- sky: "#91d7e3"
- sapphire: "#7dc4e4"
- blue: "#8aadf4"
- lavender: "#b7bdf8"
- text: "#cad3f5"
- subtext1: "#b8c0e0"
- subtext0: "#a5adcb"
- overlay2: "#939ab7"
- overlay1: "#8087a2"
- overlay0: "#6e738d"
- surface2: "#5b6078"
- surface1: "#494d64"
- surface0: "#363a4f"
- base: "#24273a"
- mantle: "#1e2030"
- crust: "#181926"
- }
- mocha: {
- 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"
- subtext0: "#a6adc8"
- overlay2: "#9399b2"
- overlay1: "#7f849c"
- overlay0: "#6c7086"
- surface2: "#585b70"
- surface1: "#45475a"
- surface0: "#313244"
- base: "#1e1e2e"
- mantle: "#181825"
- crust: "#11111b"
- }
-}
-
-let stheme = $catppuccin.mocha
-
-let theme = {
- separator: $stheme.overlay0
- leading_trailing_space_bg: $stheme.overlay0
- header: $stheme.green
- date: $stheme.mauve
- filesize: $stheme.blue
- row_index: $stheme.pink
- bool: $stheme.peach
- int: $stheme.peach
- duration: $stheme.peach
- range: $stheme.peach
- float: $stheme.peach
- string: $stheme.green
- nothing: $stheme.peach
- binary: $stheme.peach
- cellpath: $stheme.peach
- hints: dark_gray
-
- shape_garbage: { fg: $stheme.crust bg: $stheme.red attr: b }
- shape_bool: $stheme.blue
- shape_int: { fg: $stheme.mauve attr: b}
- shape_float: { fg: $stheme.mauve attr: b}
- shape_range: { fg: $stheme.yellow attr: b}
- shape_internalcall: { fg: $stheme.blue attr: b}
- shape_external: { fg: $stheme.blue attr: b}
- shape_externalarg: $stheme.text
- shape_literal: $stheme.blue
- shape_operator: $stheme.yellow
- shape_signature: { fg: $stheme.green attr: b}
- shape_string: $stheme.green
- shape_filepath: $stheme.yellow
- shape_globpattern: { fg: $stheme.blue attr: b}
- shape_variable: $stheme.text
- shape_flag: { fg: $stheme.blue attr: b}
- shape_custom: {attr: b}
-}
-
-let-env config = {
- show_banner: false
- cursor_shape: {
- vi_normal: block
- vi_insert: line
- }
- edit_mode: vi
- render_right_prompt_on_last_line: true
- rm: {
- always_trash: true
- }
- color_config: $theme
- keybindings: [
- {
- name: completion_menu
- modifier: none
- keycode: tab
- mode: [emacs vi_normal vi_insert]
- event: {
- until: [
- { send: menu name: completion_menu }
- { send: menunext }
- ]
- }
- }
- {
- name: completion_previous
- modifier: shift
- keycode: backtab
- mode: [emacs, vi_normal, vi_insert] # Note: You can add the same keybinding to all modes by using a list
- event: { send: menuprevious }
- }
- {
- name: jump_to_start
- keycode: char_h
- modifier: shift
- mode: [vi_normal]
- event: { edit: MoveToLineStart }
- }
- {
- name: jump_to_end
- modifier: shift
- keycode: char_l
- mode: [vi_normal]
- event: { edit: MoveToLineEnd }
- }
- ]
- completions: {
- algorithm: "fuzzy"
- }
- hooks: {
- pre_prompt: [{ ||
- let direnv = (direnv export json | from json)
- let direnv = if ($direnv | length) == 1 { $direnv } else { {} }
- $direnv | load-env
- }]
- pre_execution: [{ || }]
- }
-}
-
-let-env PROMPT_INDICATOR_VI_INSERT = "I "
-let-env PROMPT_INDICATOR_VI_NORMAL = "N "
-
-# Aliases
-# ls to exa
-#alias ls = exa -al --color=always --icons --group-directories-first
-#alias la = exa -a --color=always --icons --group-directories-firt
-#alias ll = exa -abghHliS --icons --group-directories-first
-#alias lt = exa -aT --color=always --icons --group-directories-first
-
-alias df = df -h # human readblity
-alias rs = sudo reboot
-alias sysctl = sudo systemctl
-alias doas = doas --
-alias jctl = journalctl -p 3 -xb # get error messages from journalctl
-alias lg = lazygit
-alias ssp = ~/shells/spawnshell.sh
-
-use "~/.config/nushell/scripts/custom-completions/nix/nix-completions.nu" *
-use "~/.config/nushell/scripts/custom-completions/git/git-completions.nu" *
-use "~/.config/nushell/scripts/custom-completions/npm/npm-completions.nu" *
-use "~/.config/nushell/scripts/custom-completions/just/just-completions.nu" *
-use "~/.config/nushell/scripts/custom-completions/tealdeer/tldr-completions.nu" *
-use "~/.config/nushell/scripts/custom-completions/btm/btm-completions.nu" *
-use "~/.config/nushell/scripts/custom-completions/make/make-completions.nu" *
-
-source ~/.cache/starship/init.nu
diff --git a/home/isabel/programs/cli/confs/nushell/default.nix b/home/isabel/programs/cli/confs/nushell/default.nix
deleted file mode 100644
index e4f12d723..000000000
--- a/home/isabel/programs/cli/confs/nushell/default.nix
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- config,
- lib,
- pkgs,
- inputs,
- osConfig,
- ...
-}: let
- inherit (lib) mkIf;
- programs = osConfig.modules.programs;
- flakePath = osConfig.modules.system.flakePath;
-in {
- config = mkIf (programs.cli.enable) {
- programs.nushell = {
- enable = true;
- package = pkgs.nushell;
- };
-
- home.file = {
- "${config.xdg.configHome}/nushell/config.nu" = lib.mkForce {
- source = config.lib.file.mkOutOfStoreSymlink "${flakePath}/home/isabel/packages/cli/confs/nushell/config.nu";
- };
- "${config.xdg.configHome}/nushell/env.nu" = lib.mkForce {
- source = config.lib.file.mkOutOfStoreSymlink "${flakePath}/home/isabel/packages/cli/confs/nushell/env.nu";
- };
- "${config.xdg.configHome}/nushell/history.txt" = {
- source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.dataHome}/history";
- };
- "${config.xdg.configHome}/nushell/env-nix.nu" = with lib; let
- environmentVariables = {
- EDITOR = "nvim";
- GIT_EDITOR = "nvim";
- VISUAL = "code";
- TERMINAL = "alacritty";
- };
- in {
- text = ''
- ${concatStringsSep "\n"
- (mapAttrsToList (k: v: "let-env ${k} = ${v}")
- environmentVariables)}
- '';
- };
- "${config.xdg.configHome}/nushell/scripts" = {
- source = inputs.nu_scripts;
- };
- };
- };
-}
diff --git a/home/isabel/programs/cli/confs/nushell/env.nu b/home/isabel/programs/cli/confs/nushell/env.nu
deleted file mode 100644
index 6fd23a9b1..000000000
--- a/home/isabel/programs/cli/confs/nushell/env.nu
+++ /dev/null
@@ -1,44 +0,0 @@
-mkdir ~/.cache/starship
-starship init nu | str replace "term size -c" "term size" | save -f ~/.cache/starship/init.nu
-
-let-env SSH_AGENT_TIMEOUT = 300
-mkdir ~/.cache/ssh-agent/
-
-if ("~/.cache/ssh-agent/agent" | path exists) {
- let ssh_env = (open ~/.cache/ssh-agent/agent | from json)
-
- let nc = (do { ^nc -zU $ssh_env.SSH_AUTH_SOCK } | complete)
- let sock_exit = $nc.exit_code
-
- if ($sock_exit == 0) {
- $ssh_env | load-env
- } else {
- print "Starting new ssh agent"
-
- let ssh_env = (ssh-agent -c -t $env.SSH_AGENT_TIMEOUT
- | lines
- | first 2
- | parse "setenv {name} {value};"
- | transpose -i -r -d)
-
- $ssh_env | to json | save -f ~/.cache/ssh-agent/agent
- $ssh_env | load-env
- }
-} else {
- print "Starting ssh agent"
-
- let ssh_env = (ssh-agent -c -t $env.SSH_AGENT_TIMEOUT
- | lines
- | first 2
- | parse "setenv {name} {value};"
- | transpose -i -r -d)
-
- $ssh_env | to json | save ~/.cache/ssh-agent/agent
- $ssh_env | load-env
-}
-
-if ("~/.ssh/github" | path exists ) {
- do { ssh-add ~/.ssh/github } out> /dev/null
-}
-
-source ~/.config/nushell/env-nix.nu
diff --git a/home/isabel/programs/cli/confs/starship.nix b/home/isabel/programs/cli/confs/starship.nix
index 980ba5173..b7aff576c 100644
--- a/home/isabel/programs/cli/confs/starship.nix
+++ b/home/isabel/programs/cli/confs/starship.nix
@@ -2,146 +2,139 @@
osConfig,
lib,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
- device = osConfig.modules.device;
-
- acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
-in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.cli.enable)) {
- programs.starship = {
- enable = true;
- catppuccin.enable = true;
- settings = {
- add_newline = true;
- format = lib.strings.concatStrings [
- "[╭╴](238)$os"
- "$all[╰─](237)$character"
- ];
- character = {
- success_symbol = "";
- error_symbol = "";
- };
- container = {
- symbol = " ";
- format = "[$symbol ](yellow dimmed)";
- };
- username = {
- style_user = "white";
- style_root = "black";
- format = "[$user]($style) ";
- show_always = true;
- };
- directory = {
- truncation_length = 3;
- truncation_symbol = "…/";
- home_symbol = " ~";
- read_only_style = "197";
- read_only = " ";
- format = "at [$path]($style)[$read_only]($read_only_style) ";
- };
- directory.substitutions = {
- "documents" = " ";
- "downloads" = " ";
- "media/music" = " ";
- "media/pictures" = " ";
- "media/videos" = " ";
- "dev" = " ";
- "skl" = " ";
- ".setup" = " ";
- };
- os = {
- disabled = true;
- style = "bold white";
- format = "[$symbol]($style)";
- };
- os.symbols = {
- Arch = "";
- Artix = "";
- Debian = "";
- # Kali = "";
- EndeavourOS = "";
- Fedora = "";
- NixOS = "";
- openSUSE = "";
- SUSE = "";
- Ubuntu = "";
- Raspbian = "";
- #elementary = "";
- #Coreos = "";
- Gentoo = "";
- #mageia = ""
- CentOS = "";
- #sabayon = "";
- #slackware = "";
- Mint = "";
- Alpine = "";
- #aosc = "";
- #devuan = "";
- Manjaro = "";
- #rhel = "";
- Macos = "";
- Linux = "";
- Windows = "";
- };
- python = {
- symbol = "";
- format = "[$symbol ](yellow)";
- };
- nodejs = {
- symbol = " ";
- format = "[$symbol ](yellow)";
- };
- lua = {
- symbol = "";
- format = "[$symbol ](blue)";
- };
- rust = {
- symbol = "";
- format = "[$symbol ](red)";
- };
- docker_context = {
- symbol = "";
- format = "[$symbol ](blue)";
- };
- java = {
- symbol = "";
- format = "[$symbol ](red)";
- };
- c = {
- symbol = "";
- format = "[$symbol ](blue)";
- };
- golang = {
- symbol = "";
- format = "[$symbol ](blue)";
- };
- battery = {
- disabled = true;
- };
- git_branch = {
- symbol = " ";
- format = "on [$symbol$branch]($style) ";
- truncation_length = 4;
- truncation_symbol = "…/";
- style = "bold green";
- };
- git_status = {
- format = "[($all_status$ahead_behind)]($style) ";
- style = "bold green";
- conflicted = "🏳";
- up_to_date = " ";
- untracked = " ";
- ahead = "⇡$count";
- diverged = "⇕⇡$ahead_count⇣$behind_count";
- behind = "⇣$count";
- stashed = " ";
- modified = " ";
- staged = "[++($count)](green)";
- renamed = " ";
- deleted = " ";
- };
+}: {
+ programs.starship = {
+ inherit (osConfig.modules.programs.cli) enable;
+ catppuccin.enable = true;
+ settings = {
+ add_newline = true;
+ format = lib.strings.concatStrings [
+ "[╭╴](238)$os"
+ "$all[╰─](237)$character"
+ ];
+ character = {
+ success_symbol = "";
+ error_symbol = "";
+ };
+ container = {
+ symbol = " ";
+ format = "[$symbol ](yellow dimmed)";
+ };
+ username = {
+ style_user = "white";
+ style_root = "black";
+ format = "[$user]($style) ";
+ show_always = true;
+ };
+ directory = {
+ truncation_length = 3;
+ truncation_symbol = "…/";
+ home_symbol = " ~";
+ read_only_style = "197";
+ read_only = " ";
+ format = "at [$path]($style)[$read_only]($read_only_style) ";
+ };
+ directory.substitutions = {
+ "documents" = " ";
+ "downloads" = " ";
+ "media/music" = " ";
+ "media/pictures" = " ";
+ "media/videos" = " ";
+ "dev" = " ";
+ "skl" = " ";
+ ".config" = " ";
+ };
+ os = {
+ disabled = true;
+ style = "bold white";
+ format = "[$symbol]($style)";
+ };
+ # If it is commented out it does not exist yet
+ os.symbols = {
+ Arch = "";
+ Artix = "";
+ Debian = "";
+ # Kali = "";
+ EndeavourOS = "";
+ Fedora = "";
+ NixOS = "";
+ openSUSE = "";
+ SUSE = "";
+ Ubuntu = "";
+ Raspbian = "";
+ #elementary = "";
+ #Coreos = "";
+ Gentoo = "";
+ #mageia = ""
+ CentOS = "";
+ #sabayon = "";
+ #slackware = "";
+ Mint = "";
+ Alpine = "";
+ #aosc = "";
+ #devuan = "";
+ Manjaro = "";
+ #rhel = "";
+ Macos = "";
+ Linux = "";
+ Windows = "";
+ };
+ python = {
+ symbol = "";
+ format = "[$symbol ](yellow)";
+ };
+ nodejs = {
+ symbol = " ";
+ format = "[$symbol ](yellow)";
+ };
+ lua = {
+ symbol = "";
+ format = "[$symbol ](blue)";
+ };
+ rust = {
+ symbol = "";
+ format = "[$symbol ](red)";
+ };
+ docker_context = {
+ symbol = "";
+ format = "[$symbol ](blue)";
+ };
+ java = {
+ symbol = "";
+ format = "[$symbol ](red)";
+ };
+ c = {
+ symbol = "";
+ format = "[$symbol ](blue)";
+ };
+ golang = {
+ symbol = "";
+ format = "[$symbol ](blue)";
+ };
+ battery = {
+ disabled = true;
+ };
+ git_branch = {
+ symbol = " ";
+ format = "on [$symbol$branch]($style) ";
+ truncation_length = 4;
+ truncation_symbol = "…/";
+ style = "bold green";
+ };
+ git_status = {
+ format = "[($all_status$ahead_behind)]($style) ";
+ style = "bold green";
+ conflicted = "🏳";
+ up_to_date = " ";
+ untracked = " ";
+ ahead = "⇡$count";
+ diverged = "⇕⇡$ahead_count⇣$behind_count";
+ behind = "⇣$count";
+ stashed = " ";
+ modified = " ";
+ staged = "[++($count)](green)";
+ renamed = " ";
+ deleted = " ";
};
};
};
diff --git a/home/isabel/programs/cli/confs/tealdear.nix b/home/isabel/programs/cli/confs/tealdear.nix
index f0ab9b8cd..36e5358c5 100644
--- a/home/isabel/programs/cli/confs/tealdear.nix
+++ b/home/isabel/programs/cli/confs/tealdear.nix
@@ -2,14 +2,10 @@
osConfig,
lib,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
- device = osConfig.modules.device;
-
+}: let
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.cli.enable)) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && lib.isModernShell osConfig) {
programs.tealdeer = {
enable = true;
settings = {
diff --git a/home/isabel/programs/cli/default.nix b/home/isabel/programs/cli/default.nix
index a8cec92d1..42a903758 100644
--- a/home/isabel/programs/cli/default.nix
+++ b/home/isabel/programs/cli/default.nix
@@ -2,7 +2,6 @@ _: {
imports = [
./confs
- ./scripts
./shared.nix
./desktop.nix
./wayland.nix
diff --git a/home/isabel/programs/cli/desktop.nix b/home/isabel/programs/cli/desktop.nix
index 243309c58..2ac5229dd 100644
--- a/home/isabel/programs/cli/desktop.nix
+++ b/home/isabel/programs/cli/desktop.nix
@@ -3,21 +3,16 @@
lib,
pkgs,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
- device = osConfig.modules.device;
-
+}: let
+ inherit (lib) mkIf isAcceptedDevice;
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.cli.enable)) {
+ config = mkIf ((isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.cli.enable) {
home.packages = with pkgs; [
- # CLI
- libnotify
- imagemagick
- bitwarden-cli
- trash-cli
- brightnessctl
+ libnotify # needed for some notifcations
+ bitwarden-cli # bitwarden, my chosen package manager
+ trash-cli # `rm` skips the "rubish bin", this cli tool uses that
+ brightnessctl # brightness managed via cli
];
};
}
diff --git a/home/isabel/programs/cli/scripts/extract.nix b/home/isabel/programs/cli/scripts/extract.nix
deleted file mode 100644
index 8d4156c92..000000000
--- a/home/isabel/programs/cli/scripts/extract.nix
+++ /dev/null
@@ -1,48 +0,0 @@
-_: ''
- SAVEIFS=$IFS
- IFS="$(printf '\n\t')"
-
- function extract {
- if [ $# -eq 0 ]; then
- # display usage if no parameters given
- echo "Usage: extract ."
- echo " extract [path/file_name_2.ext] [path/file_name_3.ext]"
- fi
- for n in "$@"; do
- if [ ! -f "$n" ]; then
- echo "'$n' - file doesn't exist"
- return 1
- fi
-
- case "''${n%,}" in
- *.cbt|*.tar.bz2|*.tar.gz|*.tar.xz|*.tbz2|*.tgz|*.txz|*.tar)
- tar zxvf "$n" ;;
- *.lzma) unlzma ./"$n" ;;
- *.bz2) bunzip2 ./"$n" ;;
- *.cbr|*.rar) unrar x -ad ./"$n" ;;
- *.gz) gunzip ./"$n" ;;
- *.cbz|*.epub|*.zip) unzip ./"$n" ;;
- *.z) uncompress ./"$n" ;;
- *.7z|*.apk|*.arj|*.cab|*.cb7|*.chm|*.deb|*.iso|*.lzh|*.msi|*.pkg|*.rpm|*.udf|*.wim|*.xar|*.vhd)
- 7z x ./"$n" ;;
- *.xz) unxz ./"$n" ;;
- *.exe) cabextract ./"$n" ;;
- *.cpio) cpio -id < ./"$n" ;;
- *.cba|*.ace) unace x ./"$n" ;;
- *.zpaq) zpaq x ./"$n" ;;
- *.arc) arc e ./"$n" ;;
- *.cso) ciso 0 ./"$n" ./"$n.iso" && \
- extract "$n.iso" && \rm -f "$n" ;;
- *.zlib) zlib-flate -uncompress < ./"$n" > ./"$n.tmp" && \
- mv ./"$n.tmp" ./"''${n%.*zlib}" && rm -f "$n" ;;
- *.dmg)
- hdiutil mount ./"$n" -mountpoint "./$n.mounted" ;;
- *)
- echo "extract: '$n' - unknown archive method"
- return 1
- ;;
- esac
- done
- }
-
- IFS=$SAVEIFS''
diff --git a/home/isabel/programs/cli/shared.nix b/home/isabel/programs/cli/shared.nix
index 3064a3457..7c7229a14 100644
--- a/home/isabel/programs/cli/shared.nix
+++ b/home/isabel/programs/cli/shared.nix
@@ -2,27 +2,31 @@
osConfig,
lib,
pkgs,
+ inputs',
+ self',
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
+}: let
+ inherit (lib) mkIf optionals;
+ cfg = osConfig.modules.programs;
in {
- config = mkIf (programs.cli.enable) {
+ config = mkIf cfg.cli.enable {
home.packages = with pkgs;
[
# CLI packages from nixpkgs
unzip
- ripgrep
rsync
fd
jq
dconf
nitch
- exa
+ hyfetch
+ cached-nix-shell
+ self'.packages.bellado
+ self'.packages.catppuccinifier-cli
]
- ++ optionals (programs.nur.enable && programs.nur.bella) [
- nur.repos.bella.bellado
- nur.repos.bella.catppuccinifier-cli
+ ++ optionals cfg.cli.modernShell.enable [
+ ripgrep
+ inputs'.catppuccin-toolbox.packages.catwalk
];
};
}
diff --git a/home/isabel/programs/cli/wayland.nix b/home/isabel/programs/cli/wayland.nix
index d6ae0d9be..3ed5c8c97 100644
--- a/home/isabel/programs/cli/wayland.nix
+++ b/home/isabel/programs/cli/wayland.nix
@@ -3,14 +3,10 @@
lib,
pkgs,
...
-}:
-with lib; let
- device = osConfig.modules.device;
- env = osConfig.modules.usrEnv;
- sys = osConfig.modules.system;
+}: let
acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (env.isWayland && sys.video.enable)) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && (lib.isWayland osConfig) && osConfig.modules.programs.cli.enable) {
home.packages = with pkgs; [
grim
slurp
diff --git a/home/isabel/programs/default.nix b/home/isabel/programs/default.nix
index 0f734b4bd..3c9d1ad8a 100644
--- a/home/isabel/programs/default.nix
+++ b/home/isabel/programs/default.nix
@@ -1,9 +1,12 @@
_: {
imports = [
- ./gui
+ ./cli # command line applications
./editors # not all editors are GUI so they don't fit into the current catagories
- ./cli
- ./tui
- ./wm
+ ./gui # graphical applications
+ ./scripts # useful shell scrips
+ ./shells # shell configurations
+ ./tui # terminal interface applications
+ ./wm # window managers
+ # TODO DE's
];
}
diff --git a/home/isabel/programs/editors/default.nix b/home/isabel/programs/editors/default.nix
index 5b7050db0..5a5978923 100644
--- a/home/isabel/programs/editors/default.nix
+++ b/home/isabel/programs/editors/default.nix
@@ -1,7 +1,10 @@
-_: {
+{pkgs, ...}: {
imports = [
./micro
- ./nvim
+ ./nvim # https://github.com/NotAShelf/neovim-flake/
./vscode
];
+ config.home.packages = with pkgs; [
+ arduino # need this one for uni
+ ];
}
diff --git a/home/isabel/programs/editors/micro/default.nix b/home/isabel/programs/editors/micro/default.nix
index bb073a960..45707721f 100644
--- a/home/isabel/programs/editors/micro/default.nix
+++ b/home/isabel/programs/editors/micro/default.nix
@@ -3,10 +3,8 @@
config,
defaults,
...
-}: let
- inherit (lib) mkIf;
-in {
- config = mkIf (defaults.editor == "micro") {
+}: {
+ config = lib.mkIf (defaults.editor == "micro") {
programs.micro = {
enable = true;
catppuccin.enable = true;
diff --git a/home/isabel/programs/editors/nvim/default.nix b/home/isabel/programs/editors/nvim/default.nix
index 36168c88c..9061f7005 100644
--- a/home/isabel/programs/editors/nvim/default.nix
+++ b/home/isabel/programs/editors/nvim/default.nix
@@ -1,90 +1,412 @@
{
- pkgs,
- lib,
- config,
inputs,
- defaults,
+ pkgs,
...
-}: let
- inherit (lib) mkIf;
-in {
- config = mkIf (defaults.editor == "nvim") {
- home.file."${config.xdg.configHome}/nvim" = {
- source = inputs.isabel-nvim;
- };
+}: {
+ imports = [inputs.neovim-flake.homeManagerModules.default];
- programs.neovim = {
- enable = true;
- package = pkgs.symlinkJoin {
- name = "neovim";
- paths = [pkgs.neovim-unwrapped];
- buildInputs = [pkgs.makeWrapper pkgs.gcc];
- postBuild = "wrapProgram $out/bin/nvim --prefix CC : ${pkgs.lib.getExe pkgs.gcc}";
- };
+ # https://notashelf.github.io/neovim-flake/
+ programs.neovim-flake = {
+ enable = true;
+ settings.vim = {
+ package = pkgs.neovim-unwrapped;
+ viAlias = true;
vimAlias = true;
- viAlias = false;
- vimdiffAlias = false;
- withRuby = false;
- withNodeJs = false;
- withPython3 = false;
- extraPackages = with pkgs; [
- # external deps
- fd
- ripgrep
- lazygit
-
- texlab # latex LSP
- nil # nix language server
- alejandra # nix formatter
- shellcheck
-
- #rust
- cargo
- rust-analyzer
- rustc
- rustfmt
-
- # web dev
- nodePackages.alex
-
- # python
- nodePackages.pyright
-
- # lua
- stylua
- lua-language-server
- ];
- plugins = with pkgs.vimPlugins; [
- (nvim-treesitter.withPlugins (plugins:
- with plugins; [
- tree-sitter-python
- tree-sitter-c
- tree-sitter-nix
- tree-sitter-cpp
- tree-sitter-rust
- tree-sitter-toml
- tree-sitter-json
- tree-sitter-lua
- tree-sitter-go
- tree-sitter-java
- tree-sitter-typescript
- tree-sitter-javascript
- tree-sitter-cmake
- tree-sitter-comment
- tree-sitter-http
- tree-sitter-regex
- tree-sitter-make
- tree-sitter-html
- tree-sitter-css
- tree-sitter-latex
- tree-sitter-bibtex
- tree-sitter-php
- tree-sitter-sql
- tree-sitter-zig
- tree-sitter-dockerfile
- tree-sitter-markdown
- ]))
+
+ enableEditorconfig = true;
+ preventJunkFiles = true;
+ enableLuaLoader = true;
+ useSystemClipboard = true;
+
+ treesitter.grammars = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
+ regex
+ markdown
+ markdown-inline
];
+
+ extraPlugins = let
+ inherit (pkgs.vimPlugins) friendly-snippets aerial-nvim nvim-surround undotree harpoon;
+ in {
+ friendly-snippets = {package = friendly-snippets;};
+
+ aerial = {
+ package = aerial-nvim;
+ setup = "require('aerial').setup {}";
+ };
+
+ harpoon = {
+ package = harpoon;
+ setup = "require('harpoon').setup {}";
+ after = ["aerial"];
+ };
+
+ nvim-surround = {
+ package = nvim-surround;
+ setup = "require('nvim-surround').setup {}";
+ };
+
+ undotree = {
+ package = undotree;
+ setup = ''
+ vim.g.undotree_ShortIndicators = true
+ vim.g.undotree_TreeVertShape = '│'
+ '';
+ };
+ };
+
+ spellChecking.enable = true;
+
+ languages = {
+ enableLSP = true;
+ enableFormat = true;
+ enableTreesitter = true;
+ enableExtraDiagnostics = true;
+
+ nix.enable = true;
+ html.enable = true;
+ markdown.enable = true;
+ sql.enable = false;
+ ts.enable = true;
+ go.enable = false;
+ python.enable = false;
+ zig.enable = false;
+ dart.enable = false;
+ elixir.enable = false;
+ svelte.enable = false;
+ php.enable = false;
+
+ lua = {
+ enable = false;
+ lsp.neodev.enable = false;
+ };
+
+ rust = {
+ enable = true;
+ crates.enable = true;
+ };
+
+ clang = {
+ enable = false;
+ lsp = {
+ enable = true;
+ server = "clangd";
+ };
+ };
+ };
+
+ lsp = {
+ formatOnSave = true;
+ lspkind.enable = true;
+ lsplines.enable = true;
+ lightbulb.enable = true;
+ lspsaga.enable = false;
+ lspSignature.enable = true;
+ nvimCodeActionMenu.enable = true;
+ trouble.enable = false;
+ # nvim-docs-view.enable = true;
+ };
+
+ debugMode = {
+ enable = false;
+ logFile = "/tmp/nvim.log";
+ };
+
+ debugger.nvim-dap = {
+ enable = true;
+ ui.enable = true;
+ };
+
+ visuals = {
+ enable = true;
+ nvimWebDevicons.enable = true;
+ scrollBar.enable = false;
+ smoothScroll.enable = true;
+ cellularAutomaton.enable = false;
+ fidget-nvim.enable = true;
+
+ indentBlankline = {
+ enable = true;
+ fillChar = null;
+ eolChar = null;
+ showCurrContext = true;
+ };
+
+ cursorline = {
+ enable = true;
+ lineTimeout = 0;
+ };
+ };
+
+ statusline = {
+ lualine = {
+ enable = true;
+ theme = "catppuccin";
+ };
+ };
+
+ theme = {
+ enable = true;
+ name = "catppuccin";
+ style = "mocha";
+ transparent = true;
+ };
+
+ autopairs.enable = true;
+
+ autocomplete = {
+ enable = true;
+ type = "nvim-cmp";
+
+ mappings = {
+ confirm = "";
+ next = "";
+ previous = "";
+ };
+ };
+
+ filetree = {
+ nvimTree = {
+ enable = true;
+ openOnSetup = true;
+ disableNetrw = true;
+
+ hijackUnnamedBufferWhenOpening = true;
+ hijackCursor = true;
+ hijackDirectories = {
+ enable = true;
+ autoOpen = true;
+ };
+
+ git = {
+ enable = true;
+ showOnDirs = false;
+ timeout = 100;
+ };
+
+ view = {
+ preserveWindowProportions = false;
+ cursorline = false;
+ width = 35;
+ };
+
+ renderer = {
+ indentMarkers.enable = true;
+ rootFolderLabel = false;
+
+ icons = {
+ modifiedPlacement = "after";
+ gitPlacement = "after";
+ show.git = true;
+ show.modified = true;
+ };
+ };
+
+ filters = {
+ dotfiles = true;
+ gitIgnored = true;
+ };
+
+ diagnostics.enable = true;
+
+ modified = {
+ enable = true;
+ showOnDirs = false;
+ showOnOpenDirs = true;
+ };
+
+ mappings = {
+ toggle = "e";
+ refresh = "er";
+ findFile = "ef";
+ focus = "et";
+ };
+ };
+ };
+
+ tabline = {
+ nvimBufferline.enable = true;
+ };
+
+ treesitter = {
+ fold = true;
+ context.enable = true;
+ };
+
+ binds = {
+ whichKey.enable = true;
+ cheatsheet.enable = false;
+ };
+
+ telescope = {
+ enable = true;
+
+ mappings = {
+ findFiles = "";
+ liveGrep = "fs";
+ treesitter = "ffs";
+
+ gitCommits = "fgc";
+ gitBufferCommits = "fgbc";
+ gitBranches = "fgb";
+ gitStatus = "fgs";
+ gitStash = " fgx";
+ };
+ };
+
+ git = {
+ enable = true;
+ gitsigns.enable = true;
+ gitsigns.codeActions = false;
+ };
+
+ minimap = {
+ minimap-vim.enable = false;
+ codewindow.enable = false;
+ };
+
+ dashboard = {
+ dashboard-nvim.enable = false;
+ alpha.enable = false;
+ startify.enable = false;
+ };
+
+ notify = {
+ nvim-notify.enable = true;
+ };
+
+ projects = {
+ project-nvim = {
+ enable = true;
+ manualMode = false;
+ detectionMethods = ["lsp" "pattern"];
+ };
+ };
+
+ utility = {
+ ccc.enable = false; # color picker
+ icon-picker.enable = true;
+ diffview-nvim.enable = true;
+ surround.enable = true; # quick delimters altering
+
+ # TODO wakatime
+
+ motion = {
+ hop.enable = true;
+ leap.enable = false;
+ };
+ };
+
+ notes = {
+ todo-comments = {
+ enable = true;
+
+ mappings = {
+ quickFix = "tdf";
+ telescope = "tds";
+ };
+ };
+
+ obsidian = {
+ enable = true;
+ dir = "~/documents/obsidian";
+ completion.nvim_cmp = true;
+ };
+ };
+
+ terminal = {
+ toggleterm = {
+ mappings.open = "";
+ enable = true;
+ direction = "tab";
+ lazygit = {
+ enable = true;
+ direction = "tab";
+ };
+ };
+ };
+
+ ui = {
+ noice.enable = true;
+ colorizer.enable = true;
+ illuminate.enable = true;
+
+ breadcrumbs = {
+ enable = true;
+ source = "nvim-navic";
+ navbuddy.enable = false;
+ };
+
+ smartcolumn = {
+ enable = true;
+ columnAt.languages = {
+ markdown = 80;
+ nix = 150;
+ ruby = 110;
+ java = 120;
+ go = [130];
+ };
+ };
+
+ borders = {
+ enable = true;
+ globalStyle = "rounded";
+ };
+ };
+
+ assistant = {
+ copilot = {
+ enable = true;
+ cmp.enable = true;
+ };
+ };
+
+ session = {
+ nvim-session-manager = {
+ enable = true;
+
+ mappings = {
+ deleteSession = "sd";
+ loadLastSession = "slt";
+ loadSession = "sl";
+ saveCurrentSession = "ss";
+ };
+ };
+ };
+
+ gestures = {
+ gesture-nvim.enable = false;
+ };
+
+ comments = {
+ comment-nvim.enable = true;
+ };
+
+ presence = {
+ presence-nvim.enable = false;
+ };
+
+ maps.normal = {
+ "qq" = {
+ action = "qall!";
+ silent = true;
+ desc = "Quit all";
+ };
+ "" = {
+ action = ":w";
+ silent = true;
+ desc = "Save";
+ };
+ "es" = {
+ action = ''
+ function ()
+ nvim-tree-api.tree.toggle_hidden_filter()
+ nvim-tree-api.tree.toggle_gitignore_filter()
+ end)
+ '';
+ silent = true;
+ desc = "Show hidden files";
+ };
+ };
};
};
}
diff --git a/home/isabel/programs/editors/vscode/default.nix b/home/isabel/programs/editors/vscode/default.nix
index b1e58c2a3..fd59301cb 100644
--- a/home/isabel/programs/editors/vscode/default.nix
+++ b/home/isabel/programs/editors/vscode/default.nix
@@ -2,33 +2,70 @@
lib,
pkgs,
osConfig,
+ config,
...
}: let
- inherit (lib) mkIf;
- inherit (osConfig.modules) device programs;
- sys = osConfig.modules.system;
acceptedTypes = ["laptop" "desktop" "hybrid"];
+ inherit (osConfig.modules.system) flakePath mainUser;
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable) {
- programs.vscode = {
- enable = true;
- package = pkgs.vscodium;
- extensions = with pkgs.vscode-extensions; [
- bradlc.vscode-tailwindcss
- catppuccin.catppuccin-vsc-icons
- catppuccin.catppuccin-vsc
- eamodio.gitlens
- github.copilot
- github.vscode-pull-request-github
- jnoortheen.nix-ide
- kamadorueda.alejandra
- rust-lang.rust-analyzer
- devsense.phptools-vscode
- shd101wyy.markdown-preview-enhanced
- ms-vscode-remote.remote-ssh
- ms-vscode.live-server
- ];
- mutableExtensionsDir = true;
- };
+ programs.vscode = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable) {
+ enable = true;
+ package = pkgs.vscodium;
+ extensions = with pkgs.vscode-extensions; [
+ # THEMEING
+ catppuccin.catppuccin-vsc-icons
+ catppuccin.catppuccin-vsc
+
+ # GIT
+ github.copilot
+ github.copilot-chat
+ github.vscode-pull-request-github
+ github.vscode-github-actions
+ eamodio.gitlens
+
+ # UTILITIES
+ ms-vscode-remote.remote-ssh
+ ms-vscode.live-server
+ vscodevim.vim #yes i hate myself
+
+ # LANGUAGES BASED EXTENSIONS
+ ## NIX
+ jnoortheen.nix-ide
+ kamadorueda.alejandra
+ mkhl.direnv
+
+ ## RUST
+ serayuzgur.crates
+ rust-lang.rust-analyzer
+
+ ## GO
+ golang.go
+
+ ## LUA
+ sumneko.lua
+
+ ## TOML
+ tamasfe.even-better-toml
+
+ ## WEB DEV
+ ### GENERAL
+ bradlc.vscode-tailwindcss
+ dbaeumer.vscode-eslint
+ denoland.vscode-deno
+
+ ### PHP
+ devsense.phptools-vscode
+
+ ### MARKDOWN
+ shd101wyy.markdown-preview-enhanced
+ unifiedjs.vscode-mdx
+ valentjn.vscode-ltex
+ ];
+ mutableExtensionsDir = true;
+ };
+
+ xdg.configFile = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable) {
+ "VSCodium/User/keybindings.json".source = config.lib.file.mkOutOfStoreSymlink "${flakePath}/home/${mainUser}/programs/editors/vscode/keybindings.json";
+ "VSCodium/User/settings.json".source = config.lib.file.mkOutOfStoreSymlink "${flakePath}/home/${mainUser}/programs/editors/vscode/settings.json";
};
}
diff --git a/home/isabel/programs/editors/vscode/keybindings.json b/home/isabel/programs/editors/vscode/keybindings.json
new file mode 100644
index 000000000..56c50500b
--- /dev/null
+++ b/home/isabel/programs/editors/vscode/keybindings.json
@@ -0,0 +1,16 @@
+[
+ {
+ "key": "ctrl+alt+up",
+ "command": "-editor.action.copyLinesUpAction",
+ "when": "editorTextFocus"
+ },
+ {
+ "key": "ctrl+alt+down",
+ "command": "-editor.action.copyLinesDownAction",
+ "when": "editorTextFocus"
+ },
+ {
+ "key": "ctrl+m",
+ "command": "-editor.action.toggleTabFocusMode"
+ }
+]
diff --git a/home/isabel/programs/editors/vscode/settings.json b/home/isabel/programs/editors/vscode/settings.json
new file mode 100644
index 000000000..7e49a2c3e
--- /dev/null
+++ b/home/isabel/programs/editors/vscode/settings.json
@@ -0,0 +1,47 @@
+{
+ "workbench.preferredLightColorTheme": "Catppuccin Mocha",
+ "security.workspace.trust.untrustedFiles": "open",
+ "editor.suggestSelection": "first",
+ "editor.formatOnPaste": true,
+ "explorer.confirmDragAndDrop": false,
+ "files.autoSave": "onWindowChange",
+ "editor.multiCursorModifier": "ctrlCmd",
+ "workbench.editor.untitled.hint": "hidden",
+ "git.autofetch": true,
+ "git.confirmSync": false,
+ "git.ignoreRebaseWarning": true,
+ "git.enableSmartCommit": true,
+ "editor.guides.bracketPairs": true,
+ "editor.guides.bracketPairsHorizontal": true,
+ "emmet.triggerExpansionOnTab": true,
+ "editor.inlineSuggest.enabled": true,
+ "github.copilot.enable": {
+ "*": true
+ },
+ "editor.accessibilitySupport": "off",
+ "editor.fontFamily": "JetBrainsMono Nerd Font Mono",
+ "terminal.integrated.fontSize": 16,
+ "editor.linkedEditing": true,
+ "workbench.startupEditor": "none",
+ "markdown-preview-enhanced.liveUpdate": true,
+ "editor.formatOnSave": true,
+ "explorer.confirmDelete": false,
+ "catppuccin.accentColor": "sapphire",
+ "catppuccin.workbenchMode": "flat",
+ "workbench.settings.applyToAllProfiles": [],
+ "workbench.iconTheme": "catppuccin-mocha",
+ "workbench.colorTheme": "Catppuccin Mocha",
+ "window.titleBarStyle": "custom",
+ "nix.enableLanguageServer": true,
+ "nix.serverPath": "nil",
+ // using flakes with `formatter = pkgs.alejandra;`
+ "nix.formatterPath": ["nix", "fmt", "--", "-"],
+ "nix.serverSettings": {
+ // settings for 'nil' LSP
+ "nil": {
+ "formatting": {
+ "command": ["alejandra"]
+ }
+ }
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/.gitignore b/home/isabel/programs/gui/confs/bars/ags/config/.gitignore
deleted file mode 100644
index 3eb0febcc..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.sass-cache
-*.css
-scss/generated.scss
-scss/.goutputstream-*
-settings.json
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/config.js b/home/isabel/programs/gui/confs/bars/ags/config/config.js
index 3471fb447..b395bddfe 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/config.js
+++ b/home/isabel/programs/gui/confs/bars/ags/config/config.js
@@ -1,26 +1,39 @@
-/* exported config */
-import { Theme } from './theme/theme.js';
-import topbar from './layouts/topbar.js';
-import leftbar from './layouts/leftbar.js';
-import * as shared from './layouts/shared.js';
+"use strict";
-const layouts = {
- topbar,
- leftbar,
-};
+import TopBar from "./js/bar/TopBar.js";
+import ScreenCorners from "./js/screencorner/ScreenCorners.js";
+import Dashboard from "./js/dashboard/Dashboard.js";
+import OSD from "./js/osd/OSD.js";
+import Applauncher from "./js/applauncher/Applauncher.js";
+import PowerMenu from "./js/powermenu/PowerMenu.js";
+import Verification from "./js/powermenu/Verification.js";
+import Notifications from "./js/notifications/Notifications.js";
+import QuickSettings from "./js/quicksettings/QuickSettings.js";
+import options from "./js/options.js";
+import * as setup from "./js/utils.js";
+import { forMonitors } from "./js/utils.js";
-const monitors = ags.Service.Hyprland.HyprctlGet('monitors')
- .map(mon => mon.id);
+setup.warnOnLowBattery();
+setup.scssWatcher();
+setup.globalServices();
+setup.activePlayer();
export default {
+ maxStreamVolume: 1.05,
+ cacheNotificationActions: true,
closeWindowDelay: {
- 'quicksettings': 300,
- 'dashboard': 300,
+ quicksettings: options.windowAnimationDuration,
+ dashboard: options.windowAnimationDuration,
},
windows: [
- ...layouts[Theme.getSetting('layout')](monitors),
- shared.ApplauncherPopup(),
- shared.PowermenuPopup(),
- shared.VerificationPopup(),
- ],
+ forMonitors(TopBar),
+ forMonitors(ScreenCorners),
+ forMonitors(OSD),
+ forMonitors(Notifications),
+ Applauncher(),
+ Dashboard(),
+ QuickSettings(),
+ PowerMenu(),
+ Verification(),
+ ].flat(2),
};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/applauncher/Applauncher.js b/home/isabel/programs/gui/confs/bars/ags/config/js/applauncher/Applauncher.js
new file mode 100644
index 000000000..5d4f88b16
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/applauncher/Applauncher.js
@@ -0,0 +1,111 @@
+import { Widget, App, Applications } from "../imports.js";
+import Separator from "../misc/Separator.js";
+import PopupWindow from "../misc/PopupWindow.js";
+import icons from "../icons.js";
+import { launchApp } from "../utils.js";
+
+const WINDOW_NAME = "applauncher";
+
+const AppItem = (app) =>
+ Widget.Button({
+ className: "app",
+ onClicked: () => {
+ App.closeWindow(WINDOW_NAME);
+ launchApp(app);
+ },
+ child: Widget.Box({
+ children: [
+ Widget.Icon({
+ icon: app.iconName,
+ size: 48,
+ }),
+ Widget.Box({
+ vertical: true,
+ children: [
+ Widget.Label({
+ className: "title",
+ label: app.name,
+ xalign: 0,
+ valign: "center",
+ ellipsize: 3,
+ }),
+ Widget.Label({
+ className: "description",
+ label: app.description || "",
+ wrap: true,
+ xalign: 0,
+ justification: "left",
+ valign: "center",
+ }),
+ ],
+ }),
+ ],
+ }),
+ });
+
+const Applauncher = () => {
+ const list = Widget.Box({ vertical: true });
+
+ const placeholder = Widget.Label({
+ label: " Couldn't find a match",
+ className: "placeholder",
+ });
+
+ const entry = Widget.Entry({
+ hexpand: true,
+ text: "-",
+ placeholderText: "Search",
+ onAccept: ({ text }) => {
+ const list = Applications.query(text);
+ if (list[0]) {
+ App.toggleWindow(WINDOW_NAME);
+ launchApp(list[0]);
+ }
+ },
+ onChange: ({ text }) => {
+ list.children = Applications.query(text)
+ .map((app) => [Separator(), AppItem(app)])
+ .flat();
+ list.add(Separator());
+ list.show_all();
+
+ placeholder.visible = list.children.length === 1;
+ },
+ });
+
+ return Widget.Box({
+ className: "applauncher",
+ properties: [["list", list]],
+ vertical: true,
+ children: [
+ Widget.Box({
+ className: "header",
+ children: [Widget.Icon(icons.apps.search), entry],
+ }),
+ Widget.Scrollable({
+ hscroll: "never",
+ child: Widget.Box({
+ vertical: true,
+ children: [list, placeholder],
+ }),
+ }),
+ ],
+ connections: [
+ [
+ App,
+ (_, name, visible) => {
+ if (name !== WINDOW_NAME) return;
+
+ entry.set_text("");
+ if (visible) entry.grab_focus();
+ },
+ ],
+ ],
+ });
+};
+
+export default () =>
+ PopupWindow({
+ name: WINDOW_NAME,
+ content: Applauncher(),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/PanelButton.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/PanelButton.js
new file mode 100644
index 000000000..e61099810
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/PanelButton.js
@@ -0,0 +1,8 @@
+import { Widget } from "../imports.js";
+
+export default ({ className, content, ...rest }) =>
+ Widget.Button({
+ className: `panel-button ${className}`,
+ child: Widget.Box({ children: [content] }),
+ ...rest,
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/TopBar.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/TopBar.js
new file mode 100644
index 000000000..1ac39f38c
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/TopBar.js
@@ -0,0 +1,91 @@
+import ApplauncherButton from "./buttons/ApplauncherButton.js";
+import Workspaces from "./buttons/Workspaces.js";
+import MediaIndicator from "./buttons/MediaIndicator.js";
+import DateButton from "./buttons/DateButton.js";
+import NotificationIndicator from "./buttons/NotificationIndicator.js";
+import SysTray from "./buttons/SysTray.js";
+import ColorPicker from "./buttons/ColorPicker.js";
+import SystemIndicators from "./buttons/SystemIndicators.js";
+import PowerMenu from "./buttons/PowerMenu.js";
+import Separator from "../misc/Separator.js";
+import BatteryBar from "./buttons/BatteryBar.js";
+import SubMenu from "./buttons/SubMenu.js";
+import { SystemTray, Widget, Variable } from "../imports.js";
+import { Notifications, Mpris, Battery } from "../imports.js";
+
+const submenuItems = Variable(1);
+SystemTray.connect("changed", () => {
+ submenuItems.setValue(SystemTray.items.length + 1);
+});
+
+const SeparatorDot = (service, condition) =>
+ Separator({
+ orientation: "vertical",
+ valign: "center",
+ connections: service && [
+ [
+ service,
+ (dot) => {
+ dot.visible = condition(service);
+ },
+ ],
+ ],
+ });
+
+const Start = () =>
+ Widget.Box({
+ className: "start",
+ children: [
+ ApplauncherButton(),
+ SeparatorDot(),
+ Workspaces(),
+ SeparatorDot(),
+ Widget.Box({ hexpand: true }),
+ NotificationIndicator(),
+ SeparatorDot(
+ Notifications,
+ (n) => n.notifications.length > 0 || n.dnd,
+ ),
+ ],
+ });
+
+const Center = () =>
+ Widget.Box({
+ className: "center",
+ children: [DateButton()],
+ });
+
+const End = () =>
+ Widget.Box({
+ className: "end",
+ children: [
+ SeparatorDot(Mpris, (m) => m.players.length > 0),
+ MediaIndicator(),
+ Widget.Box({ hexpand: true }),
+
+ SubMenu({
+ items: submenuItems,
+ children: [SysTray(), ColorPicker()],
+ }),
+ SeparatorDot(),
+ SystemIndicators(),
+ SeparatorDot(Battery, (b) => b.available),
+ BatteryBar(),
+ SeparatorDot(),
+ PowerMenu(),
+ ],
+ });
+
+export default (monitor) =>
+ Widget.Window({
+ name: `bar${monitor}`,
+ exclusive: true,
+ monitor,
+ anchor: ["top", "left", "right"],
+ child: Widget.CenterBox({
+ className: "panel",
+ startWidget: Start(),
+ centerWidget: Center(),
+ endWidget: End(),
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/ApplauncherButton.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/ApplauncherButton.js
new file mode 100644
index 000000000..690fb3eea
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/ApplauncherButton.js
@@ -0,0 +1,22 @@
+import PanelButton from "../PanelButton.js";
+import FontIcon from "../../misc/FontIcon.js";
+import { distroIcon } from "../../variables.js";
+import { App } from "../../imports.js";
+
+export default () =>
+ PanelButton({
+ className: "applauncher",
+ connections: [
+ [
+ App,
+ (btn, win, visible) => {
+ btn.toggleClassName(
+ "active",
+ win === "applauncher" && visible,
+ );
+ },
+ ],
+ ],
+ onClicked: () => App.toggleWindow("applauncher"),
+ content: FontIcon(distroIcon),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/BatteryBar.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/BatteryBar.js
new file mode 100644
index 000000000..2a1e5ae51
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/BatteryBar.js
@@ -0,0 +1,70 @@
+import icons from "../../icons.js";
+import FontIcon from "../../misc/FontIcon.js";
+import options from "../../options.js";
+import PanelButton from "../PanelButton.js";
+import Gtk from "gi://Gtk";
+import { Battery, Widget } from "../../imports.js";
+
+const Indicator = () =>
+ Widget.Stack({
+ items: [
+ ["false", Widget.Icon({ binds: [["icon", Battery, "icon-name"]] })],
+ ["true", FontIcon({ icon: icons.battery.charging })],
+ ],
+ connections: [
+ [
+ Battery,
+ (stack) => {
+ stack.shown = `${Battery.charging || Battery.charged}`;
+ },
+ ],
+ ],
+ });
+
+const PercentLabel = () =>
+ Widget.Revealer({
+ transition: "slide_right",
+ revealChild: options.battaryBar.showPercentage,
+ child: Widget.Label({
+ binds: [["label", Battery, "percent", (p) => `${p}%`]],
+ }),
+ });
+
+const LevelBar = () =>
+ Widget({
+ type: Gtk.LevelBar,
+ valign: "center",
+ binds: [["value", Battery, "percent", (p) => p / 100]],
+ });
+
+export default () => {
+ const revaler = PercentLabel();
+
+ return PanelButton({
+ className: "battery-bar",
+ onClicked: () => (revaler.revealChild = !revaler.revealChild),
+ content: Widget.Box({
+ binds: [["visible", Battery, "available"]],
+ connections: [
+ [
+ Battery,
+ (w) => {
+ w.toggleClassName(
+ "charging",
+ Battery.charging || Battery.charged,
+ );
+ w.toggleClassName(
+ "medium",
+ Battery.percent < options.battaryBar.medium,
+ );
+ w.toggleClassName(
+ "low",
+ Battery.percent < options.battaryBar.low,
+ );
+ },
+ ],
+ ],
+ children: [Indicator(), revaler, LevelBar()],
+ }),
+ });
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/ColorPicker.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/ColorPicker.js
new file mode 100644
index 000000000..04ec1339a
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/ColorPicker.js
@@ -0,0 +1,67 @@
+import PanelButton from "../PanelButton.js";
+import { Notifications, Utils, Widget, Variable } from "../../imports.js";
+import Gdk from "gi://Gdk";
+
+const COLORS_CACHE = Utils.CACHE_DIR + "/colorpicker.json";
+const wlCopy = (color) =>
+ Utils.execAsync(["wl-copy", color]).catch(() =>
+ print("no colorpicker cache found"),
+ );
+const colors = Variable([]);
+Utils.readFileAsync(COLORS_CACHE)
+ .then((out) => colors.setValue(JSON.parse(out || "[]")))
+ .catch(() => print("no colorpicker cache found"));
+
+export default () =>
+ PanelButton({
+ className: "panel-button colorpicker",
+ content: Widget.Icon("color-select-symbolic"),
+ binds: [["tooltip-text", colors, "value", (v) => `${v.length} colors`]],
+ onClicked: (btn) =>
+ Utils.execAsync("hyprpicker")
+ .then((color) => {
+ if (!color) return;
+
+ wlCopy(color);
+ const list = colors.value;
+ if (!list.includes(color)) {
+ list.push(color);
+ if (list > 10) list.shift();
+
+ colors.value = list;
+ Utils.writeFile(
+ JSON.stringify(list, null, 2),
+ COLORS_CACHE,
+ ).catch((err) => console.error(err));
+ }
+
+ btn._id = Notifications.Notify(
+ "Color Picker",
+ btn._id || null,
+ "color-select-symbolic",
+ color,
+ "",
+ [],
+ {},
+ );
+ })
+ .catch((err) => console.error(err)),
+ onSecondaryClick: (btn) =>
+ colors.value.length > 0
+ ? Widget.Menu({
+ className: "colorpicker",
+ children: colors.value.map((color) =>
+ Widget.MenuItem({
+ child: Widget.Label(color),
+ style: `background-color: ${color}`,
+ onActivate: () => wlCopy(color),
+ }),
+ ),
+ }).popup_at_widget(
+ btn,
+ Gdk.Gravity.SOUTH,
+ Gdk.Gravity.NORTH,
+ null,
+ )
+ : false,
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/DateButton.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/DateButton.js
new file mode 100644
index 000000000..cb8e6deed
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/DateButton.js
@@ -0,0 +1,21 @@
+import Clock from "../../misc/Clock.js";
+import PanelButton from "../PanelButton.js";
+import { App } from "../../imports.js";
+
+export default ({ format = "%I:%M:%S | %d/%m/%y" } = {}) =>
+ PanelButton({
+ className: "dashboard panel-button",
+ onClicked: () => App.toggleWindow("dashboard"),
+ connections: [
+ [
+ App,
+ (btn, win, visible) => {
+ btn.toggleClassName(
+ "active",
+ win === "dashboard" && visible,
+ );
+ },
+ ],
+ ],
+ child: Clock({ format }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/MediaIndicator.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/MediaIndicator.js
new file mode 100644
index 000000000..7e85fdf85
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/MediaIndicator.js
@@ -0,0 +1,71 @@
+import HoverRevealer from "../../misc/HoverRevealer.js";
+import * as mpris from "../../misc/mpris.js";
+import options from "../../options.js";
+import { Widget, Mpris, Utils } from "../../imports.js";
+
+export const getPlayer = (name = options.preferredMpris) =>
+ Mpris.getPlayer(name) || Mpris.players[0] || null;
+
+const Indicator = ({ player, direction = "right" } = {}) =>
+ HoverRevealer({
+ className: `media panel-button ${player.name}`,
+ direction,
+ onPrimaryClick: () => player.playPause(),
+ onScrollUp: () => player.next(),
+ onScrollDown: () => player.previous(),
+ onSecondaryClick: () => player.playPause(),
+ indicator: mpris.PlayerIcon(player),
+ child: Widget.Label({
+ vexpand: true,
+ truncate: "end",
+ maxWidthChars: 40,
+ connections: [
+ [
+ player,
+ (label) => {
+ label.label = `${player.trackArtists.join(", ")} - ${
+ player.trackTitle
+ }`;
+ },
+ ],
+ ],
+ }),
+ connections: [
+ [
+ player,
+ (revealer) => {
+ if (revealer._current === player.trackTitle) return;
+
+ revealer._current = player.trackTitle;
+ revealer.revealChild = true;
+ Utils.timeout(3000, () => {
+ revealer.revealChild = false;
+ });
+ },
+ ],
+ ],
+ });
+
+export default ({ direction } = {}) =>
+ Widget.Box({
+ connections: [
+ [
+ Mpris,
+ (box) => {
+ const player = getPlayer();
+ box.visible = !!player;
+
+ if (!player) {
+ box._player = null;
+ return;
+ }
+
+ if (box._player === player) return;
+
+ box._player = player;
+ box.children = [Indicator({ player, direction })];
+ },
+ "notify::players",
+ ],
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/NotificationIndicator.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/NotificationIndicator.js
new file mode 100644
index 000000000..f549634ab
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/NotificationIndicator.js
@@ -0,0 +1,59 @@
+import icons from "../../icons.js";
+import HoverRevealer from "../../misc/HoverRevealer.js";
+import { Widget, Notifications, Utils, App } from "../../imports.js";
+
+export default ({ direction = "left" } = {}) =>
+ HoverRevealer({
+ className: "notifications panel-button",
+ eventboxConnections: [
+ ["button-press-event", () => App.openWindow("dashboard")],
+ [
+ Notifications,
+ (box) =>
+ (box.visible =
+ Notifications.notifications.length > 0 ||
+ Notifications.dnd),
+ ],
+ ],
+ connections: [
+ [
+ Notifications,
+ (revealer) => {
+ const title = Notifications.notifications[0]?.summary;
+ if (revealer._title === title) return;
+
+ revealer._title = title;
+ revealer.revealChild = true;
+ Utils.timeout(3000, () => {
+ revealer.revealChild = false;
+ });
+ },
+ ],
+ ],
+ direction,
+ indicator: Widget.Icon({
+ binds: [
+ [
+ "icon",
+ Notifications,
+ "dnd",
+ (dnd) =>
+ dnd
+ ? icons.notifications.silent
+ : icons.notifications.noisy,
+ ],
+ ],
+ }),
+ child: Widget.Label({
+ truncate: "end",
+ maxWidthChars: 40,
+ binds: [
+ [
+ "label",
+ Notifications,
+ "notifications",
+ (n) => n[0]?.summary || "",
+ ],
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/PowerMenu.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/PowerMenu.js
new file mode 100644
index 000000000..bc411e712
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/PowerMenu.js
@@ -0,0 +1,10 @@
+import icons from "../../icons.js";
+import PanelButton from "../PanelButton.js";
+import { Widget, App } from "../../imports.js";
+
+export default () =>
+ PanelButton({
+ className: "powermenu",
+ content: Widget.Icon(icons.powermenu.shutdown),
+ onClicked: () => App.openWindow("powermenu"),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SubMenu.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SubMenu.js
new file mode 100644
index 000000000..82684a1d7
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SubMenu.js
@@ -0,0 +1,62 @@
+import icons from "../../icons.js";
+import PanelButton from "../PanelButton.js";
+import { Widget, Utils, Variable } from "../../imports.js";
+
+const Arrow = (revealer, direction, items) =>
+ PanelButton({
+ className: "sub-menu",
+ connections: [
+ [
+ items,
+ (btn) => {
+ btn.tooltipText = `${items.value} Items`;
+ },
+ ],
+ ],
+ onClicked: (button) => {
+ const icon = button.child;
+ revealer.revealChild = !revealer.revealChild;
+ icon._animate(icon);
+ },
+ child: Widget.Icon({
+ icon: icons.ui.arrow[direction],
+ setup: (i) => i._animate(i),
+ properties: [
+ ["deg", 180],
+ [
+ "animate",
+ (icon) => {
+ const step = revealer.revealChild ? 10 : -10;
+ for (let i = 0; i < 18; ++i) {
+ Utils.timeout(2 * i, () => {
+ icon._deg += step;
+ icon.setStyle(
+ `-gtk-icon-transform: rotate(${icon._deg}deg);`,
+ );
+ });
+ }
+ },
+ ],
+ ],
+ }),
+ });
+
+export default ({ children, direction = "left", items = Variable(0) }) => {
+ const posStart = direction === "up" || direction === "left";
+ const posEnd = direction === "down" || direction === "right";
+ const revealer = Widget.Revealer({
+ transition: `slide_${direction}`,
+ child: Widget.Box({
+ children,
+ }),
+ });
+
+ return Widget.Box({
+ vertical: direction === "up" || direction === "down",
+ children: [
+ posStart && revealer,
+ Arrow(revealer, direction, items),
+ posEnd && revealer,
+ ],
+ });
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SysTray.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SysTray.js
new file mode 100644
index 000000000..66c9427d4
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SysTray.js
@@ -0,0 +1,37 @@
+import PanelButton from "../PanelButton.js";
+import { SystemTray, Widget } from "../../imports.js";
+import Gdk from "gi://Gdk";
+
+const SysTrayItem = (item) =>
+ PanelButton({
+ content: Widget.Icon({ binds: [["icon", item, "icon"]] }),
+ binds: [["tooltipMarkup", item, "tooltip-markup"]],
+ setup: (btn) => {
+ const id = item.menu.connect("popped-up", (menu) => {
+ btn.toggleClassName("active");
+ menu.connect("notify::visible", (menu) => {
+ btn.toggleClassName("active", menu.visible);
+ });
+ menu.disconnect(id);
+ });
+ },
+ onPrimaryClick: (btn) =>
+ item.menu.popup_at_widget(
+ btn,
+ Gdk.Gravity.SOUTH,
+ Gdk.Gravity.NORTH,
+ null,
+ ),
+ onSecondaryClick: (btn) =>
+ item.menu.popup_at_widget(
+ btn,
+ Gdk.Gravity.SOUTH,
+ Gdk.Gravity.NORTH,
+ null,
+ ),
+ });
+
+export default () =>
+ Widget.Box({
+ binds: [["children", SystemTray, "items", (i) => i.map(SysTrayItem)]],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SystemIndicators.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SystemIndicators.js
new file mode 100644
index 000000000..65297ac01
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/SystemIndicators.js
@@ -0,0 +1,150 @@
+import HoverRevealer from "../../misc/HoverRevealer.js";
+import PanelButton from "../PanelButton.js";
+import Indicator from "../../services/onScreenIndicator.js";
+import icons from "../../icons.js";
+import { App, Widget } from "../../imports.js";
+import { Bluetooth, Audio, Notifications, Network } from "../../imports.js";
+
+const MicrophoneIndicator = () =>
+ Widget.Icon({
+ icon: icons.audio.mic.muted,
+ connections: [
+ [
+ Audio,
+ (icon) => {
+ icon.visible = Audio.microphone?.isMuted;
+ },
+ "microphone-changed",
+ ],
+ ],
+ });
+
+const DNDIndicator = () =>
+ Widget.Icon({
+ icon: icons.notifications.silent,
+ binds: [["visible", Notifications, "dnd"]],
+ });
+
+const BluetoothDevicesIndicator = () =>
+ Widget.Box({
+ connections: [
+ [
+ Bluetooth,
+ (box) => {
+ box.children = Bluetooth.connectedDevices.map(
+ ({ iconName, name }) =>
+ HoverRevealer({
+ indicator: Widget.Icon(iconName + "-symbolic"),
+ child: Widget.Label(name),
+ }),
+ );
+
+ box.visible = Bluetooth.connectedDevices.length > 0;
+ },
+ "notify::connected-devices",
+ ],
+ ],
+ });
+
+const BluetoothIndicator = () =>
+ Widget.Icon({
+ className: "bluetooth",
+ icon: icons.bluetooth.enabled,
+ binds: [["visible", Bluetooth, "enabled"]],
+ });
+
+const NetworkIndicator = () =>
+ Widget.Stack({
+ items: [
+ [
+ "wifi",
+ Widget.Icon({
+ connections: [
+ [
+ Network,
+ (icon) => {
+ icon.icon = Network.wifi?.iconName;
+ },
+ ],
+ ],
+ }),
+ ],
+ [
+ "wired",
+ Widget.Icon({
+ connections: [
+ [
+ Network,
+ (icon) => {
+ icon.icon = Network.wired?.iconName;
+ },
+ ],
+ ],
+ }),
+ ],
+ ],
+ binds: [["shown", Network, "primary"]],
+ });
+
+const AudioIndicator = () =>
+ Widget.Icon({
+ connections: [
+ [
+ Audio,
+ (icon) => {
+ if (!Audio.speaker) return;
+
+ const { muted, low, medium, high, overamplified } =
+ icons.audio.volume;
+ if (Audio.speaker.isMuted) return (icon.icon = muted);
+
+ icon.icon = [
+ [101, overamplified],
+ [67, high],
+ [34, medium],
+ [1, low],
+ [0, muted],
+ ].find(
+ ([threshold]) =>
+ threshold <= Audio.speaker.volume * 100,
+ )[1];
+ },
+ "speaker-changed",
+ ],
+ ],
+ });
+
+export default () =>
+ PanelButton({
+ className: "quicksettings panel-button",
+ onClicked: () => App.toggleWindow("quicksettings"),
+ onScrollUp: () => {
+ Audio.speaker.volume += 0.02;
+ Indicator.speaker();
+ },
+ onScrollDown: () => {
+ Audio.speaker.volume -= 0.02;
+ Indicator.speaker();
+ },
+ connections: [
+ [
+ App,
+ (btn, win, visible) => {
+ btn.toggleClassName(
+ "active",
+ win === "quicksettings" && visible,
+ );
+ },
+ ],
+ ],
+ child: Widget.Box({
+ children: [
+ DNDIndicator(),
+ BluetoothDevicesIndicator(),
+ BluetoothIndicator(),
+ NetworkIndicator(),
+ AudioIndicator(),
+ MicrophoneIndicator(),
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/Workspaces.js b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/Workspaces.js
new file mode 100644
index 000000000..5b4c9651d
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/bar/buttons/Workspaces.js
@@ -0,0 +1,64 @@
+import { Hyprland, Widget, Utils } from "../../imports.js";
+import options from "../../options.js";
+import { range } from "../../utils.js";
+
+const ws = options.workspaces;
+const dispatch = (arg) => () =>
+ Utils.execAsync(`hyprctl dispatch workspace ${arg}`);
+
+const Workspaces = () =>
+ Widget.Box({
+ children: range(ws || 20).map((i) =>
+ Widget.Button({
+ setup: (btn) => (btn.id = i),
+ onClicked: dispatch(i),
+ child: Widget.Label({
+ label: `${i}`,
+ className: "indicator",
+ valign: "center",
+ }),
+ connections: [
+ [
+ Hyprland,
+ (btn) => {
+ btn.toggleClassName(
+ "active",
+ Hyprland.active.workspace.id === i,
+ );
+ btn.toggleClassName(
+ "occupied",
+ Hyprland.getWorkspace(i)?.windows > 0,
+ );
+ },
+ ],
+ ],
+ }),
+ ),
+ connections: ws
+ ? []
+ : [
+ [
+ Hyprland.active.workspace,
+ (box) =>
+ box.children.map((btn) => {
+ btn.visible = Hyprland.workspaces.some(
+ (ws) => ws.id === btn.id,
+ );
+ }),
+ ],
+ ],
+ });
+
+export default () =>
+ Widget.Box({
+ className: "workspaces panel-button",
+ child: Widget.Box({
+ // its nested like this to keep it consistent with other PanelButton widgets
+ child: Widget.EventBox({
+ onScrollUp: dispatch(`${ws ? "r" : "m"}+1`),
+ onScrollDown: dispatch(`${ws ? "r" : "m"}-1`),
+ className: "eventbox",
+ child: Workspaces(),
+ }),
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/Dashboard.js b/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/Dashboard.js
new file mode 100644
index 000000000..d6304f399
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/Dashboard.js
@@ -0,0 +1,20 @@
+import DateColumn from "./DateColumn.js";
+import NotificationColumn from "./NotificationColumn.js";
+import PopupWindow from "../misc/PopupWindow.js";
+import Separator from "../misc/Separator.js";
+import { Widget } from "../imports.js";
+
+export default ({ anchor = ["top"], layout = "top" } = {}) =>
+ PopupWindow({
+ name: "dashboard",
+ layout,
+ anchor,
+ content: Widget.Box({
+ className: "dashboard",
+ children: [
+ NotificationColumn(),
+ Separator({ orientation: "vertical" }),
+ DateColumn(),
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/DateColumn.js b/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/DateColumn.js
new file mode 100644
index 000000000..7c6497d62
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/DateColumn.js
@@ -0,0 +1,62 @@
+import icons from "../icons.js";
+import Clock from "../misc/Clock.js";
+import * as vars from "../variables.js";
+import { Widget } from "../imports.js";
+import Theme from "../services/theme/theme.js";
+
+const SysProgress = (type, title, unit) =>
+ Widget.Box({
+ className: `circular-progress-box ${type}`,
+ hexpand: true,
+ binds: [
+ [
+ "tooltipText",
+ vars[type],
+ "value",
+ (v) => `${title}: ${Math.floor(v * 100)}${unit}`,
+ ],
+ ],
+ child: Widget.CircularProgress({
+ hexpand: true,
+ className: `circular-progress ${type}`,
+ child: Widget.Icon(icons.system[type]),
+ startAt: 0.75,
+ binds: [["value", vars[type]]],
+ connections: [
+ [
+ Theme,
+ (prog) => {
+ prog.rounded = Theme.getSetting("radii") > 0;
+ },
+ ],
+ ],
+ }),
+ });
+
+export default () =>
+ Widget.Box({
+ vertical: true,
+ className: "datemenu",
+ children: [
+ Clock({ format: "%I:%M" }),
+ Widget.Label({
+ binds: [["label", vars.uptime, "value", (t) => `uptime: ${t}`]],
+ }),
+ Widget.Box({
+ className: "calendar",
+ child: Widget({
+ type: imports.gi.Gtk.Calendar,
+ hexpand: true,
+ halign: "center",
+ }),
+ }),
+ Widget.Box({
+ className: "system-info",
+ children: [
+ SysProgress("cpu", "Cpu", "%"),
+ SysProgress("ram", "Ram", "%"),
+ SysProgress("temp", "Temperature", "°"),
+ ],
+ }),
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/NotificationColumn.js b/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/NotificationColumn.js
new file mode 100644
index 000000000..8e12447f2
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/dashboard/NotificationColumn.js
@@ -0,0 +1,93 @@
+import icons from "../icons.js";
+import Notification from "../misc/Notification.js";
+import { Widget, Notifications } from "../imports.js";
+
+const ClearButton = () =>
+ Widget.Button({
+ onClicked: () => Notifications.clear(),
+ binds: [
+ ["sensitive", Notifications, "notifications", (n) => n.length > 0],
+ ],
+ child: Widget.Box({
+ children: [
+ Widget.Label("Clear "),
+ Widget.Icon({
+ binds: [
+ [
+ "icon",
+ Notifications,
+ "notifications",
+ (n) =>
+ n.length > 0
+ ? icons.trash.full
+ : icons.trash.empty,
+ ],
+ ],
+ }),
+ ],
+ }),
+ });
+
+const Header = () =>
+ Widget.Box({
+ className: "header",
+ children: [
+ Widget.Label({ label: "Notifications", hexpand: true, xalign: 0 }),
+ ClearButton(),
+ ],
+ });
+
+const NotificationList = () =>
+ Widget.Box({
+ vertical: true,
+ vexpand: true,
+ connections: [
+ [
+ Notifications,
+ (box) => {
+ box.children = Notifications.notifications
+ .reverse()
+ .map(Notification);
+
+ box.visible = Notifications.notifications.length > 0;
+ },
+ ],
+ ],
+ });
+
+const Placeholder = () =>
+ Widget.Box({
+ className: "placeholder",
+ vertical: true,
+ valign: "center",
+ halign: "center",
+ vexpand: true,
+ hexpand: true,
+ children: [
+ Widget.Icon(icons.notifications.silent),
+ Widget.Label("Your inbox is empty"),
+ ],
+ binds: [
+ ["visible", Notifications, "notifications", (n) => n.length === 0],
+ ],
+ });
+
+export default () =>
+ Widget.Box({
+ className: "notifications",
+ vertical: true,
+ children: [
+ Header(),
+ Widget.Scrollable({
+ vexpand: true,
+ className: "notification-scrollable",
+ hscroll: "never",
+ vscroll: "automatic",
+ child: Widget.Box({
+ className: "notification-list",
+ vertical: true,
+ children: [NotificationList(), Placeholder()],
+ }),
+ }),
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/icons.js b/home/isabel/programs/gui/confs/bars/ags/config/js/icons.js
new file mode 100644
index 000000000..61b31e6c0
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/icons.js
@@ -0,0 +1,87 @@
+export default {
+ settings: "emblem-system-symbolic",
+ tick: "object-select-symbolic",
+ lock: "system-lock-screen-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: "",
+ },
+ apps: {
+ apps: "view-app-grid-symbolic",
+ search: "folder-saved-search-symbolic",
+ },
+ battery: {
+ charging: "",
+ 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",
+ },
+ notifications: {
+ noisy: "preferences-system-notifications-symbolic",
+ silent: "notifications-disabled-symbolic",
+ },
+ trash: {
+ full: "user-trash-full-symbolic",
+ empty: "user-trash-symbolic",
+ },
+ mpris: {
+ fallback: "audio-x-generic-symbolic",
+ shuffle: {
+ enabled: "",
+ disabled: "",
+ },
+ loop: {
+ none: "",
+ track: "",
+ playlist: "",
+ },
+ playing: "",
+ paused: "",
+ stopped: "",
+ prev: "",
+ next: "",
+ },
+ ui: {
+ arrow: {
+ right: "pan-end-symbolic",
+ left: "pan-start-symbolic",
+ down: "pan-down-symbolic",
+ up: "pan-up-symbolic",
+ },
+ },
+ system: {
+ cpu: "org.gnome.SystemMonitor-symbolic",
+ ram: "drive-harddisk-solidstate-symbolic",
+ temp: "temperature-symbolic",
+ },
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/imports.js b/home/isabel/programs/gui/confs/bars/ags/config/js/imports.js
new file mode 100644
index 000000000..1d981b474
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/imports.js
@@ -0,0 +1,19 @@
+const resource = (file) => `resource:///com/github/Aylur/ags/${file}.js`;
+const require = async (file) => (await import(resource(file))).default;
+const service = async (file) => await require(`service/${file}`);
+
+export const App = await require("app");
+export const Widget = await require("widget");
+export const Service = await require("service");
+export const Variable = await require("variable");
+export const Utils = await import(resource("utils"));
+
+export const Applications = await service("applications");
+export const Audio = await service("audio");
+export const Battery = await service("battery");
+export const Bluetooth = await service("bluetooth");
+export const Hyprland = await service("hyprland");
+export const Mpris = await service("mpris");
+export const Network = await service("network");
+export const Notifications = await service("notifications");
+export const SystemTray = await service("systemtray");
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Avatar.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Avatar.js
new file mode 100644
index 000000000..f9d31ff8e
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Avatar.js
@@ -0,0 +1,19 @@
+import Theme from "../services/theme/theme.js";
+import { Widget } from "../imports.js";
+
+export default (props) =>
+ Widget.Box({
+ ...props,
+ className: "avatar",
+ connections: [
+ [
+ Theme,
+ (box) => {
+ box.setStyle(`
+ background-image: url('${Theme.getSetting("avatar")}');
+ background-size: cover;
+ `);
+ },
+ ],
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/BatteryIcon.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/BatteryIcon.js
new file mode 100644
index 000000000..0669e8ed6
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/BatteryIcon.js
@@ -0,0 +1,19 @@
+import { Battery, Widget } from "../imports.js";
+
+export default () =>
+ Widget.Icon({
+ className: "battery",
+ binds: [["icon", Battery, "icon-name"]],
+ connections: [
+ [
+ Battery,
+ (stack) => {
+ const { charging, charged } = Battery;
+ stack.shown = `${charging || charged}`;
+ stack.toggleClassName("charging", Battery.charging);
+ stack.toggleClassName("charged", Battery.charged);
+ stack.toggleClassName("low", Battery.percent < 30);
+ },
+ ],
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Clock.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Clock.js
new file mode 100644
index 000000000..f1dc31b2d
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Clock.js
@@ -0,0 +1,20 @@
+import { Widget } from "../imports.js";
+import GLib from "gi://GLib";
+
+export default ({
+ format = "%H:%M:%S %B %e. %A",
+ interval = 1000,
+ ...props
+} = {}) =>
+ Widget.Label({
+ className: "clock",
+ ...props,
+ connections: [
+ [
+ interval,
+ (label) =>
+ (label.label =
+ GLib.DateTime.new_now_local().format(format)),
+ ],
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/FontIcon.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/FontIcon.js
new file mode 100644
index 000000000..1d7ff7fdb
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/FontIcon.js
@@ -0,0 +1,44 @@
+import Gtk from "gi://Gtk";
+import GObject from "gi://GObject";
+import { Widget } from "../imports.js";
+
+class FontIcon extends Gtk.Label {
+ static {
+ GObject.registerClass(this);
+ }
+
+ constructor(params = "") {
+ const { icon = "", ...rest } = params;
+ super(typeof params === "string" ? {} : rest);
+ this.toggleClassName("font-icon");
+
+ if (typeof params === "object") this.icon = icon;
+ }
+
+ get icon() {
+ return this.label;
+ }
+ set icon(icon) {
+ this.label = icon;
+ }
+
+ get size() {
+ return this.get_style_context().get_property(
+ "font-size",
+ Gtk.StateFlags.NORMAL,
+ );
+ }
+
+ vfunc_get_preferred_height() {
+ return [this.size, this.size];
+ }
+
+ vfunc_get_preferred_width() {
+ return [this.size, this.size];
+ }
+}
+
+export default (params) =>
+ typeof params === "string"
+ ? Widget({ type: FontIcon, icon: params })
+ : Widget({ type: FontIcon, ...params });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/HoverRevealer.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/HoverRevealer.js
new file mode 100644
index 000000000..a4dc2205d
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/HoverRevealer.js
@@ -0,0 +1,50 @@
+import { Widget, Utils } from "../imports.js";
+
+export default ({
+ indicator,
+ child,
+ direction = "left",
+ duration = 300,
+ connections,
+ eventboxConnections,
+ binds,
+ ...rest
+}) => {
+ let open = false;
+ const vertical = direction === "down" || direction === "up";
+ const posStart = direction === "down" || direction === "right";
+ const posEnd = direction === "up" || direction === "left";
+
+ const revealer = Widget.Revealer({
+ transition: `slide_${direction}`,
+ connections,
+ binds,
+ transitionDuration: duration,
+ child,
+ });
+
+ const box = Widget.EventBox({
+ ...rest,
+ connections: eventboxConnections,
+ onHover: () => {
+ if (open) return;
+
+ revealer.revealChild = true;
+ Utils.timeout(duration, () => (open = true));
+ },
+ onHoverLost: () => {
+ if (!open) return;
+
+ revealer.revealChild = false;
+ open = false;
+ },
+ child: Widget.Box({
+ vertical,
+ children: [posStart && indicator, revealer, posEnd && indicator],
+ }),
+ });
+
+ return Widget.Box({
+ children: [box],
+ });
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/IconBrowser.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/IconBrowser.js
new file mode 100644
index 000000000..c8c18a9ca
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/IconBrowser.js
@@ -0,0 +1,68 @@
+import { Widget } from "../imports.js";
+import Gtk from "gi://Gtk";
+
+export default () => {
+ const selected = Widget.Label({
+ style: "font-size: 1.2em;",
+ });
+
+ const flowbox = Widget({
+ type: Gtk.FlowBox,
+ min_children_per_line: 10,
+ connections: [
+ [
+ "child-activated",
+ (_, { child }) => {
+ selected.label = child.iconName;
+ },
+ ],
+ ],
+ setup: (self) => {
+ Gtk.IconTheme.get_default()
+ .list_icons(null)
+ .sort()
+ .map((icon) => {
+ !icon.endsWith(".symbolic") &&
+ self.insert(
+ Widget.Icon({
+ icon,
+ size: 38,
+ }),
+ -1,
+ );
+ });
+
+ self.show_all();
+ },
+ });
+
+ const entry = Widget.Entry({
+ onChange: ({ text }) =>
+ flowbox.get_children().forEach((child) => {
+ child.visible = child.child.iconName.includes(text);
+ }),
+ });
+
+ return Widget({
+ name: "icons",
+ type: Gtk.Window,
+ visible: true,
+ child: Widget.Box({
+ style: "padding: 30px;",
+ spacing: 20,
+ vertical: true,
+ children: [
+ entry,
+ Widget.Scrollable({
+ hscroll: "never",
+ vscroll: "always",
+ hexpand: true,
+ vexpand: true,
+ style: "min-width: 500px;" + "min-height: 500px;",
+ child: flowbox,
+ }),
+ selected,
+ ],
+ }),
+ });
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Notification.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Notification.js
new file mode 100644
index 000000000..5a28a842a
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Notification.js
@@ -0,0 +1,150 @@
+import { Utils, Widget, Variable } from "../imports.js";
+import GLib from "gi://GLib";
+
+const NotificationIcon = ({ appEntry, appIcon, image }) => {
+ if (image) {
+ return Widget.Box({
+ valign: "start",
+ hexpand: false,
+ className: "icon img",
+ style: `
+ background-image: url("${image}");
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ min-width: 78px;
+ min-height: 78px;
+ `,
+ });
+ }
+
+ let icon = "dialog-information-symbolic";
+ if (Utils.lookUpIcon(appIcon)) icon = appIcon;
+
+ if (Utils.lookUpIcon(appEntry)) icon = appEntry;
+
+ return Widget.Box({
+ valign: "start",
+ hexpand: false,
+ className: "icon",
+ style: `
+ min-width: 78px;
+ min-height: 78px;
+ `,
+ child: Widget.Icon({
+ icon,
+ size: 58,
+ halign: "center",
+ hexpand: true,
+ valign: "center",
+ vexpand: true,
+ }),
+ });
+};
+
+export default (notification) => {
+ const hovered = Variable(false);
+
+ const hover = () => {
+ hovered.value = true;
+ hovered._block = true;
+
+ Utils.timeout(100, () => (hovered._block = false));
+ };
+
+ const hoverLost = () =>
+ GLib.idle_add(0, () => {
+ if (hovered._block) return GLib.SOURCE_REMOVE;
+
+ hovered.value = false;
+ notification.dismiss();
+ return GLib.SOURCE_REMOVE;
+ });
+
+ const content = Widget.Box({
+ className: "content",
+ children: [
+ NotificationIcon(notification),
+ Widget.Box({
+ hexpand: true,
+ vertical: true,
+ children: [
+ Widget.Box({
+ children: [
+ Widget.Label({
+ className: "title",
+ xalign: 0,
+ justification: "left",
+ hexpand: true,
+ maxWidthChars: 24,
+ truncate: "end",
+ wrap: true,
+ label: notification.summary,
+ useMarkup: notification.summary.startsWith("<"),
+ }),
+ Widget.Label({
+ className: "time",
+ valign: "start",
+ label: GLib.DateTime.new_from_unix_local(
+ notification.time,
+ ).format("%H:%M"),
+ }),
+ Widget.Button({
+ onHover: hover,
+ className: "close-button",
+ valign: "start",
+ child: Widget.Icon("window-close-symbolic"),
+ onClicked: () => notification.close(),
+ }),
+ ],
+ }),
+ Widget.Label({
+ className: "description",
+ hexpand: true,
+ useMarkup: true,
+ xalign: 0,
+ justification: "left",
+ label: notification.body,
+ wrap: true,
+ }),
+ ],
+ }),
+ ],
+ });
+
+ const actionsbox = Widget.Revealer({
+ transition: "slide_down",
+ binds: [["revealChild", hovered]],
+ child: Widget.EventBox({
+ onHover: hover,
+ child: Widget.Box({
+ className: "actions",
+ children: notification.actions.map((action) =>
+ Widget.Button({
+ onHover: hover,
+ className: "action-button",
+ onClicked: () => notification.invoke(action.id),
+ hexpand: true,
+ child: Widget.Label(action.label),
+ }),
+ ),
+ }),
+ }),
+ });
+
+ return Widget.EventBox({
+ className: `notification ${notification.urgency}`,
+ vexpand: false,
+ onPrimaryClick: () => {
+ hovered.value = false;
+ notification.dismiss();
+ },
+ properties: [["hovered", hovered]],
+ onHover: hover,
+ onHoverLost: hoverLost,
+ child: Widget.Box({
+ vertical: true,
+ children: [content, notification.actions.length > 0 && actionsbox],
+ }),
+ });
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/PopupWindow.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/PopupWindow.js
new file mode 100644
index 000000000..9dc618bb1
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/PopupWindow.js
@@ -0,0 +1,98 @@
+import options from "../options.js";
+import { App, Widget } from "../imports.js";
+
+const Padding = (windowName) =>
+ Widget.EventBox({
+ className: "padding",
+ hexpand: true,
+ vexpand: true,
+ connections: [
+ ["button-press-event", () => App.toggleWindow(windowName)],
+ ],
+ });
+
+const PopupRevealer = (windowName, transition, child) =>
+ Widget.Box({
+ style: "padding: 1px;",
+ child: Widget.Revealer({
+ transition,
+ child,
+ transitionDuration: options.windowAnimationDuration,
+ connections: [
+ [
+ App,
+ (revealer, name, visible) => {
+ if (name === windowName)
+ revealer.reveal_child = visible;
+ },
+ ],
+ ],
+ }),
+ });
+
+const layouts = {
+ center: (windowName, child, expand) =>
+ Widget.CenterBox({
+ className: "shader",
+ style: expand ? "min-width: 5000px; min-height: 3000px;" : "",
+ children: [
+ Padding(windowName),
+ Widget.CenterBox({
+ vertical: true,
+ children: [Padding(windowName), child, Padding(windowName)],
+ }),
+ Padding(windowName),
+ ],
+ }),
+ top: (windowName, child) =>
+ Widget.CenterBox({
+ children: [
+ Padding(windowName),
+ Widget.Box({
+ vertical: true,
+ children: [
+ PopupRevealer(windowName, "slide_down", child),
+ Padding(windowName),
+ ],
+ }),
+ Padding(windowName),
+ ],
+ }),
+ "top right": (windowName, child) =>
+ Widget.Box({
+ children: [
+ Padding(windowName),
+ Widget.Box({
+ hexpand: false,
+ vertical: true,
+ children: [
+ PopupRevealer(windowName, "slide_down", child),
+ Padding(windowName),
+ ],
+ }),
+ ],
+ }),
+ "bottom right": (windowName, child) =>
+ Widget.Box({
+ children: [
+ Padding(windowName),
+ Widget.Box({
+ hexpand: false,
+ vertical: true,
+ children: [
+ Padding(windowName),
+ PopupRevealer(windowName, "slide_up", child),
+ ],
+ }),
+ ],
+ }),
+};
+
+export default ({ layout = "center", expand = true, name, content, ...rest }) =>
+ Widget.Window({
+ name,
+ child: layouts[layout](name, content, expand),
+ popup: true,
+ focusable: true,
+ ...rest,
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Progress.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Progress.js
new file mode 100644
index 000000000..0b108e3ae
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Progress.js
@@ -0,0 +1,54 @@
+import { Widget, Utils } from "../imports.js";
+
+export default ({
+ height = 18,
+ width = 180,
+ vertical = false,
+ child,
+ ...props
+}) => {
+ const fill = Widget.Box({
+ className: "fill",
+ hexpand: vertical,
+ vexpand: !vertical,
+ halign: vertical ? "fill" : "start",
+ valign: vertical ? "end" : "fill",
+ children: [child],
+ });
+
+ return Widget.Box({
+ ...props,
+ className: "progress",
+ style: `
+ min-width: ${width}px;
+ min-height: ${height}px;
+ `,
+ children: [fill],
+ setup: (progress) =>
+ (progress.setValue = (value) => {
+ if (value < 0) return;
+
+ const axis = vertical ? "height" : "width";
+ const axisv = vertical ? height : width;
+ const min = vertical ? width : height;
+ const preferred = (axisv - min) * value + min;
+
+ if (!fill._size) {
+ fill._size = preferred;
+ fill.setStyle(`min-${axis}: ${preferred}px;`);
+ return;
+ }
+
+ const frames = 10;
+ const goal = preferred - fill._size;
+ const step = goal / frames;
+
+ for (let i = 0; i < frames; ++i) {
+ Utils.timeout(5 * i, () => {
+ fill._size += step;
+ fill.setStyle(`min-${axis}: ${fill._size}px`);
+ });
+ }
+ }),
+ });
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Separator.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Separator.js
new file mode 100644
index 000000000..2110059bf
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Separator.js
@@ -0,0 +1,9 @@
+import Gtk from "gi://Gtk";
+import { Widget } from "../imports.js";
+
+export default ({ orientation = "vertical", ...rest } = {}) =>
+ Widget({
+ ...rest,
+ type: Gtk.Separator,
+ orientation: Gtk.Orientation[orientation.toUpperCase()],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Spinner.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Spinner.js
new file mode 100644
index 000000000..61d428c5a
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Spinner.js
@@ -0,0 +1,9 @@
+import Gtk from "gi://Gtk";
+import { Widget } from "../imports.js";
+
+export default (props) =>
+ Widget({
+ ...props,
+ type: Gtk.Spinner,
+ active: true,
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Wallpaper.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Wallpaper.js
new file mode 100644
index 000000000..0e7b2da01
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/Wallpaper.js
@@ -0,0 +1,19 @@
+import Theme from "../services/theme/theme.js";
+import { Widget } from "../imports.js";
+
+export default ({ className, ...props }) =>
+ Widget.Box({
+ ...props,
+ className: `wallpaper ${className}`,
+ connections: [
+ [
+ Theme,
+ (box) => {
+ box.setStyle(`
+ background-image: url('${Theme.getSetting("wallpaper")}');
+ background-size: cover;
+ `);
+ },
+ ],
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/misc/mpris.js b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/mpris.js
new file mode 100644
index 000000000..0965572cc
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/misc/mpris.js
@@ -0,0 +1,299 @@
+import icons from "../icons.js";
+import { Utils, Widget } from "../imports.js";
+import GLib from "gi://GLib";
+
+const MEDIA_CACHE_PATH = Utils.CACHE_DIR + "/media";
+
+export const CoverArt = (player, props) =>
+ Widget.Box({
+ ...props,
+ className: "cover",
+ binds: [
+ [
+ "style",
+ player,
+ "cover-path",
+ (path) => `background-image: url("${path}")`,
+ ],
+ ],
+ });
+
+export const BlurredCoverArt = (player, props) =>
+ Widget.Box({
+ ...props,
+ className: "blurred-cover",
+ connections: [
+ [
+ player,
+ (box) => {
+ const url = player.coverPath;
+ if (!url) return;
+
+ const blurredPath = MEDIA_CACHE_PATH + "/blurred";
+ const blurred =
+ blurredPath + url.substring(MEDIA_CACHE_PATH.length);
+
+ if (GLib.file_test(blurred, GLib.FileTest.EXISTS)) {
+ box.setStyle(`background-image: url("${blurred}")`);
+ return;
+ }
+
+ Utils.ensureDirectory(blurredPath);
+ Utils.execAsync(["convert", url, "-blur", "0x22", blurred])
+ .then(() =>
+ box.setStyle(`background-image: url("${blurred}")`),
+ )
+ .catch(() => {});
+ },
+ "notify::cover-path",
+ ],
+ ],
+ });
+
+export const TitleLabel = (player, props) =>
+ Widget.Label({
+ ...props,
+ className: "title",
+ binds: [["label", player, "track-title"]],
+ });
+
+export const ArtistLabel = (player, props) =>
+ Widget.Label({
+ ...props,
+ className: "artist",
+ binds: [["label", player, "track-artists", (a) => a.join(", ") || ""]],
+ });
+
+export const PlayerIcon = (player, { symbolic = true, ...props } = {}) =>
+ Widget.Icon({
+ ...props,
+ className: "player-icon",
+ tooltipText: player.identity || "",
+ connections: [
+ [
+ player,
+ (icon) => {
+ const name = `${player.entry}${
+ symbolic ? "-symbolic" : ""
+ }`;
+ Utils.lookUpIcon(name)
+ ? (icon.icon = name)
+ : (icon.icon = icons.mpris.fallback);
+ },
+ ],
+ ],
+ });
+
+export const PositionSlider = (player, props) =>
+ Widget.Slider({
+ ...props,
+ className: "position-slider",
+ drawValue: false,
+ onChange: ({ value }) => {
+ player.position = player.length * value;
+ },
+ properties: [
+ [
+ "update",
+ (slider) => {
+ if (slider.dragging) return;
+
+ slider.visible = player.length > 0;
+ if (player.length > 0)
+ slider.value = player.position / player.length;
+ },
+ ],
+ ],
+ connections: [
+ [player, (s) => s._update(s)],
+ [player, (s) => s._update(s), "position"],
+ [1000, (s) => s._update(s)],
+ ],
+ });
+
+function lengthStr(length) {
+ const min = Math.floor(length / 60);
+ const sec = Math.floor(length % 60);
+ const sec0 = sec < 10 ? "0" : "";
+ return `${min}:${sec0}${sec}`;
+}
+
+export const PositionLabel = (player) =>
+ Widget.Label({
+ properties: [
+ [
+ "update",
+ (label, time) => {
+ player.length > 0
+ ? (label.label = lengthStr(time || player.position))
+ : (label.visible = !!player);
+ },
+ ],
+ ],
+ connections: [
+ [player, (l, time) => l._update(l, time), "position"],
+ [1000, (l) => l._update(l)],
+ ],
+ });
+
+export const LengthLabel = (player) =>
+ Widget.Label({
+ connections: [
+ [
+ player,
+ (label) => {
+ player.length > 0
+ ? (label.label = lengthStr(player.length))
+ : (label.visible = !!player);
+ },
+ ],
+ ],
+ });
+
+export const Slash = (player) =>
+ Widget.Label({
+ label: "/",
+ connections: [
+ [
+ player,
+ (label) => {
+ label.visible = player.length > 0;
+ },
+ ],
+ ],
+ });
+
+const PlayerButton = ({ player, items, onClick, prop, canProp, cantValue }) =>
+ Widget.Button({
+ child: Widget.Stack({
+ items,
+ binds: [["shown", player, prop, (p) => `${p}`]],
+ }),
+ onClicked: player[onClick].bind(player),
+ binds: [["visible", player, canProp, (c) => c !== cantValue]],
+ });
+
+export const ShuffleButton = (player) =>
+ PlayerButton({
+ player,
+ items: [
+ [
+ "true",
+ Widget.Label({
+ className: "shuffle enabled",
+ label: icons.mpris.shuffle.enabled,
+ }),
+ ],
+ [
+ "false",
+ Widget.Label({
+ className: "shuffle disabled",
+ label: icons.mpris.shuffle.disabled,
+ }),
+ ],
+ ],
+ onClick: "shuffle",
+ prop: "shuffle-status",
+ canProp: "shuffle-status",
+ cantValue: null,
+ });
+
+export const LoopButton = (player) =>
+ PlayerButton({
+ player,
+ items: [
+ [
+ "None",
+ Widget.Label({
+ className: "loop none",
+ label: icons.mpris.loop.none,
+ }),
+ ],
+ [
+ "Track",
+ Widget.Label({
+ className: "loop track",
+ label: icons.mpris.loop.track,
+ }),
+ ],
+ [
+ "Playlist",
+ Widget.Label({
+ className: "loop playlist",
+ label: icons.mpris.loop.playlist,
+ }),
+ ],
+ ],
+ onClick: "loop",
+ prop: "loop-status",
+ canProp: "loop-status",
+ cantValue: null,
+ });
+
+export const PlayPauseButton = (player) =>
+ PlayerButton({
+ player,
+ items: [
+ [
+ "Playing",
+ Widget.Label({
+ className: "playing",
+ label: icons.mpris.playing,
+ }),
+ ],
+ [
+ "Paused",
+ Widget.Label({
+ className: "paused",
+ label: icons.mpris.paused,
+ }),
+ ],
+ [
+ "Stopped",
+ Widget.Label({
+ className: "stopped",
+ label: icons.mpris.stopped,
+ }),
+ ],
+ ],
+ onClick: "playPause",
+ prop: "play-back-status",
+ canProp: "can-play",
+ cantValue: false,
+ });
+
+export const PreviousButton = (player) =>
+ PlayerButton({
+ player,
+ items: [
+ [
+ "true",
+ Widget.Label({
+ className: "previous",
+ label: icons.mpris.prev,
+ }),
+ ],
+ ],
+ onClick: "previous",
+ prop: "can-go-prev",
+ canProp: "can-go-prev",
+ cantValue: false,
+ });
+
+export const NextButton = (player) =>
+ PlayerButton({
+ player,
+ items: [
+ [
+ "true",
+ Widget.Label({
+ className: "next",
+ label: icons.mpris.next,
+ }),
+ ],
+ ],
+ onClick: "next",
+ prop: "can-go-next",
+ canProp: "can-go-next",
+ cantValue: false,
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/notifications/Notifications.js b/home/isabel/programs/gui/confs/bars/ags/config/js/notifications/Notifications.js
new file mode 100644
index 000000000..44c909210
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/notifications/Notifications.js
@@ -0,0 +1,59 @@
+import Notification from "../misc/Notification.js";
+import { Notifications, Widget, Utils } from "../imports.js";
+
+const Popups = () => {
+ const map = new Map();
+
+ const onDismissed = (box, id, force = false) => {
+ if (!id || !map.has(id)) return;
+
+ if (map.get(id)._hovered.value && !force) return;
+
+ if (map.size - 1 === 0) box.get_parent().revealChild = false;
+
+ Utils.timeout(200, () => {
+ map.get(id)?.destroy();
+ map.delete(id);
+ });
+ };
+
+ const onNotified = (box, id) => {
+ if (!id || Notifications.dnd) return;
+
+ map.delete(id);
+ map.set(id, Notification(Notifications.getNotification(id)));
+ box.children = Array.from(map.values()).reverse();
+ Utils.timeout(10, () => {
+ box.get_parent().revealChild = true;
+ });
+ };
+
+ return Widget.Box({
+ vertical: true,
+ connections: [
+ [Notifications, onNotified, "notified"],
+ [Notifications, onDismissed, "dismissed"],
+ [Notifications, (box, id) => onDismissed(box, id, true), "closed"],
+ ],
+ });
+};
+
+const PopupList = ({ transition = "slide_down" } = {}) =>
+ Widget.Box({
+ className: "notifications-popup-list",
+ style: "padding: 1px",
+ children: [
+ Widget.Revealer({
+ transition,
+ child: Popups(),
+ }),
+ ],
+ });
+
+export default (monitor) =>
+ Widget.Window({
+ monitor,
+ name: `notifications${monitor}`,
+ anchor: ["top"],
+ child: PopupList(),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/options.js b/home/isabel/programs/gui/confs/bars/ags/config/js/options.js
new file mode 100644
index 000000000..592c33358
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/options.js
@@ -0,0 +1,25 @@
+export default {
+ // if this player is running this will be shown on panel
+ preferredMpris: "spotify",
+
+ // number of workspaces shown on panel and overview
+ workspaces: 7,
+
+ battaryBar: {
+ // wether to show percentage by deafult
+ showPercentage: false,
+
+ // at what percentages should the battery-bar change color
+ low: 30,
+ medium: 50,
+ },
+
+ // path to read temperature from
+ temperature: "/sys/class/thermal/thermal_zone0/temp",
+
+ // at what intervals should cpu, ram, temperature refresh
+ systemFetchInterval: 5000,
+
+ // the slide down animation on quicksettings and dashboard
+ windowAnimationDuration: 250,
+};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/osd/OSD.js b/home/isabel/programs/gui/confs/bars/ags/config/js/osd/OSD.js
new file mode 100644
index 000000000..a5506d671
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/osd/OSD.js
@@ -0,0 +1,83 @@
+import { Utils, Widget } from "../imports.js";
+import FontIcon from "../misc/FontIcon.js";
+import Progress from "../misc/Progress.js";
+import Indicator from "../services/onScreenIndicator.js";
+
+export const OnScreenIndicator = ({ height = 300, width = 48 } = {}) =>
+ Widget.Box({
+ className: "indicator",
+ style: "padding: 1px;",
+ child: Widget.Revealer({
+ transition: "slide_left",
+ connections: [
+ [
+ Indicator,
+ (revealer, value) => {
+ revealer.revealChild = value > -1;
+ },
+ ],
+ ],
+ child: Progress({
+ width,
+ height,
+ vertical: true,
+ connections: [
+ [Indicator, (progress, value) => progress.setValue(value)],
+ ],
+ child: Widget.Stack({
+ valign: "start",
+ halign: "center",
+ hexpand: false,
+ items: [
+ [
+ "true",
+ Widget.Icon({
+ halign: "center",
+ size: width,
+ connections: [
+ [
+ Indicator,
+ (icon, _v, name) =>
+ (icon.icon = name || ""),
+ ],
+ ],
+ }),
+ ],
+ [
+ "false",
+ FontIcon({
+ halign: "center",
+ hexpand: true,
+ style: `font-size: ${width}px;`,
+ connections: [
+ [
+ Indicator,
+ (icon, _v, name) =>
+ (icon.icon = name || ""),
+ ],
+ ],
+ }),
+ ],
+ ],
+ connections: [
+ [
+ Indicator,
+ (stack, _v, name) => {
+ stack.shown = `${!!Utils.lookUpIcon(name)}`;
+ },
+ ],
+ ],
+ }),
+ }),
+ }),
+ });
+
+export default (monitor) =>
+ Widget.Window({
+ name: `indicator${monitor}`,
+ monitor,
+ className: "indicator",
+ layer: "overlay",
+ anchor: ["right"],
+ child: OnScreenIndicator(),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/powermenu/PowerMenu.js b/home/isabel/programs/gui/confs/bars/ags/config/js/powermenu/PowerMenu.js
new file mode 100644
index 000000000..304f50572
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/powermenu/PowerMenu.js
@@ -0,0 +1,32 @@
+import icons from "../icons.js";
+import PowerMenu from "../services/powermenu.js";
+import PopupWindow from "../misc/PopupWindow.js";
+import { Widget } from "../imports.js";
+
+const SysButton = (action, label) =>
+ Widget.Button({
+ onClicked: () => PowerMenu.action(action),
+ child: Widget.Box({
+ vertical: true,
+ children: [
+ Widget.Icon(icons.powermenu[action]),
+ Widget.Label(label),
+ ],
+ }),
+ });
+
+export default () =>
+ PopupWindow({
+ name: "powermenu",
+ expand: true,
+ content: Widget.Box({
+ className: "powermenu",
+ homogeneous: true,
+ children: [
+ SysButton("sleep", "Sleep"),
+ SysButton("reboot", "Reboot"),
+ SysButton("logout", "Log Out"),
+ SysButton("shutdown", "Shutdown"),
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/powermenu/Verification.js b/home/isabel/programs/gui/confs/bars/ags/config/js/powermenu/Verification.js
new file mode 100644
index 000000000..0a7060e0f
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/powermenu/Verification.js
@@ -0,0 +1,39 @@
+import PopupWindow from "../misc/PopupWindow.js";
+import PowerMenu from "../services/powermenu.js";
+import { Widget, App, Utils } from "../imports.js";
+
+export default () =>
+ PopupWindow({
+ name: "verification",
+ expand: true,
+ content: Widget.Box({
+ className: "verification",
+ vertical: true,
+ children: [
+ Widget.Label({
+ className: "title",
+ binds: [["label", PowerMenu, "title"]],
+ }),
+ Widget.Label({
+ className: "desc",
+ label: "Are you sure?",
+ }),
+ Widget.Box({
+ className: "buttons",
+ vexpand: true,
+ valign: "end",
+ homogeneous: true,
+ children: [
+ Widget.Button({
+ child: Widget.Label("No"),
+ onClicked: () => App.toggleWindow("verification"),
+ }),
+ Widget.Button({
+ child: Widget.Label("Yes"),
+ onClicked: () => Utils.exec(PowerMenu.cmd),
+ }),
+ ],
+ }),
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/QuickSettings.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/QuickSettings.js
new file mode 100644
index 000000000..60a7cf40f
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/QuickSettings.js
@@ -0,0 +1,68 @@
+import Header from "./widgets/Header.js";
+import PopupWindow from "../misc/PopupWindow.js";
+import {
+ Volume,
+ Microphone,
+ SinkSelector,
+ AppMixer,
+} from "./widgets/Volume.js";
+import { NetworkToggle, WifiSelection } from "./widgets/Network.js";
+import { BluetoothToggle, BluetoothDevices } from "./widgets/Bluetooth.js";
+import { ThemeToggle, ThemeSelector } from "./widgets/Theme.js";
+import Media from "./widgets/Media.js";
+import Brightness from "./widgets/Brightness.js";
+import DND from "./widgets/DND.js";
+import MicMute from "./widgets/MicMute.js";
+import { Widget } from "../imports.js";
+
+const Row = (toggles, menus = []) =>
+ Widget.Box({
+ className: "row",
+ vertical: true,
+ children: [
+ Widget.Box({
+ children: toggles,
+ }),
+ ...menus,
+ ],
+ });
+
+const Homogeneous = (toggles) =>
+ Widget.Box({
+ homogeneous: true,
+ children: toggles,
+ });
+
+export default () =>
+ PopupWindow({
+ name: "quicksettings",
+ anchor: ["top", "right"],
+ layout: "top right",
+ content: Widget.Box({
+ className: "quicksettings",
+ vertical: true,
+ children: [
+ Row([Header()]),
+ Row([
+ Widget.Box({
+ className: "slider-box",
+ vertical: true,
+ children: [
+ Row([Volume()], [SinkSelector(), AppMixer()]),
+ Row([Microphone()]),
+ Row([Brightness()]),
+ ],
+ }),
+ ]),
+ Row(
+ [Homogeneous([NetworkToggle(), BluetoothToggle()]), DND()],
+ [WifiSelection(), BluetoothDevices()],
+ ),
+ Row(
+ [Homogeneous([ThemeToggle()]), MicMute()],
+ [ThemeSelector()],
+ ),
+ Media(),
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/ToggleButton.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/ToggleButton.js
new file mode 100644
index 000000000..529a31c70
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/ToggleButton.js
@@ -0,0 +1,131 @@
+import icons from "../icons.js";
+import Separator from "../misc/Separator.js";
+import { Utils, Widget, App, Variable } from "../imports.js";
+
+export const opened = Variable("");
+App.connect("window-toggled", (_, name, visible) => {
+ if (name === "quicksettings" && !visible)
+ Utils.timeout(500, () => (opened.value = ""));
+});
+
+export const Arrow = (name, activate) =>
+ Widget.Button({
+ child: Widget.Icon({
+ icon: icons.ui.arrow.right,
+ properties: [["deg", 0]],
+ connections: [
+ [
+ opened,
+ (icon) => {
+ if (
+ (opened.value === name && !icon._opened) ||
+ (opened.value !== name && icon._opened)
+ ) {
+ const step = opened.value === name ? 10 : -10;
+ icon._opened = !icon._opened;
+ for (let i = 0; i < 9; ++i) {
+ Utils.timeout(15 * i, () => {
+ icon._deg += step;
+ icon.setStyle(
+ `-gtk-icon-transform: rotate(${icon._deg}deg);`,
+ );
+ });
+ }
+ }
+ },
+ ],
+ ],
+ }),
+ onClicked: () => {
+ opened.value = opened.value === name ? "" : name;
+ if (activate) activate();
+ },
+ });
+
+export const ArrowToggleButton = ({
+ name,
+ icon,
+ label,
+ activate,
+ deactivate,
+ activateOnArrow = true,
+ connection: [service, condition],
+}) =>
+ Widget.Box({
+ className: "toggle-button",
+ connections: [
+ [
+ service,
+ (box) => {
+ box.toggleClassName("active", condition());
+ },
+ ],
+ ],
+ children: [
+ Widget.Button({
+ child: Widget.Box({
+ hexpand: true,
+ children: [icon, label],
+ }),
+ onClicked: () => {
+ if (condition()) {
+ deactivate();
+ if (opened.value === name) opened.value = "";
+ } else {
+ activate();
+ }
+ },
+ }),
+ Arrow(name, activateOnArrow && activate),
+ ],
+ });
+
+export const Menu = ({ name, icon, title, content }) =>
+ Widget.Revealer({
+ transition: "slide_down",
+ connections: [
+ [
+ opened,
+ (revealer) => {
+ revealer.revealChild = opened.value === name;
+ },
+ ],
+ ],
+ child: Widget.Box({
+ className: "menu",
+ vertical: true,
+ children: [
+ Widget.Box({
+ className: "title",
+ children: [icon, title],
+ }),
+ Separator({ orientation: "horizontal" }),
+ Widget.Box({
+ className: "content",
+ children: [content],
+ }),
+ ],
+ }),
+ });
+
+export const SimpleToggleButton = ({
+ icon,
+ label,
+ toggle,
+ connection: [service, condition],
+}) =>
+ Widget.Button({
+ className: "simple-toggle",
+ connections: [
+ [
+ service,
+ (box) => {
+ box.toggleClassName("active", condition());
+ },
+ ],
+ ],
+ child: Widget.Box({
+ children: [icon, label],
+ }),
+ onClicked: toggle,
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Bluetooth.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Bluetooth.js
new file mode 100644
index 000000000..18f083753
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Bluetooth.js
@@ -0,0 +1,97 @@
+import icons from "../../icons.js";
+import Spinner from "../../misc/Spinner.js";
+import { Menu, ArrowToggleButton } from "../ToggleButton.js";
+import { Bluetooth, Widget } from "../../imports.js";
+import Gtk from "gi://Gtk";
+
+export const BluetoothToggle = () =>
+ ArrowToggleButton({
+ name: "bluetooth",
+ icon: Widget.Icon({
+ connections: [
+ [
+ Bluetooth,
+ (icon) => {
+ icon.icon = Bluetooth.enabled
+ ? icons.bluetooth.enabled
+ : icons.bluetooth.disabled;
+ },
+ ],
+ ],
+ }),
+ label: Widget.Label({
+ truncate: "end",
+ connections: [
+ [
+ Bluetooth,
+ (label) => {
+ if (!Bluetooth.enabled)
+ return (label.label = "Disabled");
+
+ if (Bluetooth.connectedDevices.length === 0)
+ return (label.label = "Not Connected");
+
+ if (Bluetooth.connectedDevices.length === 1)
+ return (label.label =
+ Bluetooth.connectedDevices[0].alias);
+
+ label.label = `${Bluetooth.connectedDevices.length} Connected`;
+ },
+ ],
+ ],
+ }),
+ connection: [Bluetooth, () => Bluetooth.enabled],
+ deactivate: () => (Bluetooth.enabled = false),
+ activate: () => (Bluetooth.enabled = true),
+ });
+
+export const BluetoothDevices = () =>
+ Menu({
+ name: "bluetooth",
+ icon: Widget.Icon(icons.bluetooth.disabled),
+ title: Widget.Label("Bluetooth"),
+ content: Widget.Box({
+ hexpand: true,
+ vertical: true,
+ connections: [
+ [
+ Bluetooth,
+ (box) => {
+ box.children = Bluetooth.devices
+ .filter((d) => d.name)
+ .map((device) =>
+ Widget.Box({
+ children: [
+ Widget.Icon(
+ device.iconName + "-symbolic",
+ ),
+ Widget.Label(device.name),
+ device.batteryPercentage > 0 &&
+ Widget.Label(
+ `${device.batteryPercentage}%`,
+ ),
+ Widget.Box({ hexpand: true }),
+ device.connecting
+ ? Spinner()
+ : Widget({
+ type: Gtk.Switch,
+ active: device.connected,
+ connections: [
+ [
+ "notify::active",
+ ({ active }) => {
+ device.setConnection(
+ active,
+ );
+ },
+ ],
+ ],
+ }),
+ ],
+ }),
+ );
+ },
+ ],
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Brightness.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Brightness.js
new file mode 100644
index 000000000..1c83efaac
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Brightness.js
@@ -0,0 +1,31 @@
+import icons from "../../icons.js";
+import Brightness from "../../services/brightness.js";
+import { Widget } from "../../imports.js";
+
+const BrightnessSlider = () =>
+ Widget.Slider({
+ drawValue: false,
+ hexpand: true,
+ binds: [["value", Brightness, "screen"]],
+ onChange: ({ value }) => (Brightness.screen = value),
+ });
+
+export default () =>
+ Widget.Box({
+ className: "slider",
+ children: [
+ Widget.Icon({
+ icon: icons.brightness.indicator,
+ className: "icon",
+ binds: [
+ [
+ "tooltip-text",
+ Brightness,
+ "screen",
+ (v) => `Screen Brightness: ${Math.floor(v * 100)}%`,
+ ],
+ ],
+ }),
+ BrightnessSlider(),
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/DND.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/DND.js
new file mode 100644
index 000000000..f57b58854
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/DND.js
@@ -0,0 +1,22 @@
+import icons from "../../icons.js";
+import { SimpleToggleButton } from "../ToggleButton.js";
+import { Notifications, Widget } from "../../imports.js";
+
+export default () =>
+ SimpleToggleButton({
+ icon: Widget.Icon({
+ connections: [
+ [
+ Notifications,
+ (icon) => {
+ icon.icon = Notifications.dnd
+ ? icons.notifications.silent
+ : icons.notifications.noisy;
+ },
+ "notify::dnd",
+ ],
+ ],
+ }),
+ toggle: () => (Notifications.dnd = !Notifications.dnd),
+ connection: [Notifications, () => Notifications.dnd],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Header.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Header.js
new file mode 100644
index 000000000..22724ccf9
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Header.js
@@ -0,0 +1,95 @@
+import icons from "../../icons.js";
+import PowerMenu from "../../services/powermenu.js";
+import Theme from "../../services/theme/theme.js";
+import Avatar from "../../misc/Avatar.js";
+import { uptime } from "../../variables.js";
+import { Battery, Widget } from "../../imports.js";
+
+export const BatteryProgress = () =>
+ Widget.Box({
+ className: "battery-progress",
+ vexpand: true,
+ binds: [["visible", Battery, "available"]],
+ connections: [
+ [
+ Battery,
+ (w) => {
+ w.toggleClassName("half", Battery.percent < 46);
+ w.toggleClassName("low", Battery.percent < 30);
+ },
+ ],
+ ],
+ child: Widget.Overlay({
+ vexpand: true,
+ child: Widget.ProgressBar({
+ hexpand: true,
+ vexpand: true,
+ connections: [
+ [
+ Battery,
+ (progress) => {
+ progress.fraction = Battery.percent / 100;
+ },
+ ],
+ ],
+ }),
+ overlays: [
+ Widget.Label({
+ connections: [
+ [
+ Battery,
+ (l) => {
+ l.label =
+ Battery.charging || Battery.charged
+ ? icons.battery.charging
+ : `${Battery.percent}%`;
+ },
+ ],
+ ],
+ }),
+ ],
+ }),
+ });
+
+export default () =>
+ Widget.Box({
+ className: "header",
+ children: [
+ Avatar(),
+ Widget.Box({
+ className: "system-box",
+ vertical: true,
+ hexpand: true,
+ children: [
+ Widget.Box({
+ children: [
+ Widget.Button({
+ valign: "center",
+ onClicked: () => Theme.openSettings(),
+ child: Widget.Icon(icons.settings),
+ }),
+ Widget.Label({
+ className: "uptime",
+ hexpand: true,
+ valign: "center",
+ connections: [
+ [
+ uptime,
+ (label) => {
+ label.label = `uptime: ${uptime.value}`;
+ },
+ ],
+ ],
+ }),
+ Widget.Button({
+ valign: "center",
+ onClicked: () => PowerMenu.action("shutdown"),
+ child: Widget.Icon(icons.powermenu.shutdown),
+ }),
+ ],
+ }),
+ BatteryProgress(),
+ ],
+ }),
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Media.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Media.js
new file mode 100644
index 000000000..ed41c85d8
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Media.js
@@ -0,0 +1,103 @@
+import * as mpris from "../../misc/mpris.js";
+import { Mpris, Widget } from "../../imports.js";
+
+const blackList = ["Caprine"];
+
+const Footer = (player) =>
+ Widget.CenterBox({
+ className: "footer-box",
+ children: [
+ Widget.Box({
+ className: "position",
+ children: [
+ mpris.PositionLabel(player),
+ mpris.Slash(player),
+ mpris.LengthLabel(player),
+ ],
+ }),
+ Widget.Box({
+ className: "controls",
+ children: [
+ mpris.ShuffleButton(player),
+ mpris.PreviousButton(player),
+ mpris.PlayPauseButton(player),
+ mpris.NextButton(player),
+ mpris.LoopButton(player),
+ ],
+ }),
+ mpris.PlayerIcon(player, {
+ symbolic: false,
+ hexpand: true,
+ halign: "end",
+ }),
+ ],
+ });
+
+const TextBox = (player) =>
+ Widget.Box({
+ children: [
+ mpris.CoverArt(player, {
+ halign: "end",
+ hexpand: false,
+ child: Widget.Box({
+ className: "shader",
+ hexpand: true,
+ }),
+ }),
+ Widget.Box({
+ hexpand: true,
+ vertical: true,
+ className: "labels",
+ children: [
+ mpris.TitleLabel(player, {
+ xalign: 0,
+ justification: "left",
+ wrap: true,
+ }),
+ mpris.ArtistLabel(player, {
+ xalign: 0,
+ justification: "left",
+ wrap: true,
+ }),
+ ],
+ }),
+ ],
+ });
+
+const PlayerBox = (player) =>
+ Widget.Box({
+ className: `player ${player.name}`,
+ child: mpris.BlurredCoverArt(player, {
+ className: "cover-art-bg",
+ hexpand: true,
+ children: [
+ Widget.Box({
+ className: "shader",
+ hexpand: true,
+ vertical: true,
+ children: [
+ TextBox(player),
+ mpris.PositionSlider(player),
+ Footer(player),
+ ],
+ }),
+ ],
+ }),
+ });
+
+export default () =>
+ Widget.Box({
+ vertical: true,
+ className: "media",
+ binds: [
+ [
+ "children",
+ Mpris,
+ "players",
+ (ps) =>
+ ps
+ .filter((p) => !blackList.includes(p.identity))
+ .map(PlayerBox),
+ ],
+ ],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/MicMute.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/MicMute.js
new file mode 100644
index 000000000..469b3982c
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/MicMute.js
@@ -0,0 +1,22 @@
+import icons from "../../icons.js";
+import { SimpleToggleButton } from "../ToggleButton.js";
+import { Audio, Widget } from "../../imports.js";
+
+export default () =>
+ SimpleToggleButton({
+ icon: Widget.Icon({
+ connections: [
+ [
+ Audio,
+ (icon) => {
+ icon.icon = Audio.microphone?.isMuted
+ ? icons.audio.mic.muted
+ : icons.audio.mic.high;
+ },
+ "microphone-changed",
+ ],
+ ],
+ }),
+ toggle: () => (Audio.microphone.isMuted = !Audio.microphone.isMuted),
+ connection: [Audio, () => Audio.microphone?.isMuted],
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Network.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Network.js
new file mode 100644
index 000000000..a267de142
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Network.js
@@ -0,0 +1,77 @@
+import icons from "../../icons.js";
+import { Menu, ArrowToggleButton } from "../ToggleButton.js";
+import { Network, Widget } from "../../imports.js";
+
+export const NetworkToggle = () =>
+ ArrowToggleButton({
+ name: "network",
+ icon: Widget.Icon({
+ connections: [
+ [
+ Network,
+ (icon) => {
+ icon.icon = Network.wifi?.iconName || "";
+ },
+ ],
+ ],
+ }),
+ label: Widget.Label({
+ truncate: "end",
+ connections: [
+ [
+ Network,
+ (label) => {
+ label.label = Network.wifi?.ssid || "Not Connected";
+ },
+ ],
+ ],
+ }),
+ connection: [Network, () => Network.wifi?.enabled],
+ deactivate: () => (Network.wifi.enabled = false),
+ activate: () => {
+ Network.wifi.enabled = true;
+ Network.wifi.scan();
+ },
+ });
+
+export const WifiSelection = () =>
+ Menu({
+ name: "network",
+ icon: Widget.Icon({
+ connections: [
+ [
+ Network,
+ (icon) => {
+ icon.icon = Network.wifi?.iconName;
+ },
+ ],
+ ],
+ }),
+ title: Widget.Label("Wifi Selection"),
+ content: Widget.Box({
+ vertical: true,
+ connections: [
+ [
+ Network,
+ (box) =>
+ (box.children = Network.wifi?.accessPoints.map((ap) =>
+ Widget.Button({
+ onClicked: `nmcli device wifi connect ${ap.bssid}`,
+ child: Widget.Box({
+ children: [
+ Widget.Icon(ap.iconName),
+ Widget.Label(ap.ssid),
+ ap.active &&
+ Widget.Icon({
+ icon: icons.tick,
+ hexpand: true,
+ halign: "end",
+ }),
+ ],
+ }),
+ }),
+ )),
+ ],
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Theme.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Theme.js
new file mode 100644
index 000000000..8332d407c
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Theme.js
@@ -0,0 +1,91 @@
+import Theme from "../../services/theme/theme.js";
+import { ArrowToggleButton, Menu, opened } from "../ToggleButton.js";
+import themes from "../../themes.js";
+import icons from "../../icons.js";
+import Separator from "../../misc/Separator.js";
+import { Widget } from "../../imports.js";
+
+const prettyName = (name) =>
+ name
+ .split("_")
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(" ");
+
+const ThemeIcon = () =>
+ Widget.Stack({
+ transition: "crossfade",
+ items: themes.map(({ name, icon }) => [name, Widget.Label(icon)]),
+ connections: [
+ [Theme, (stack) => (stack.shown = Theme.getSetting("theme"))],
+ ],
+ });
+
+export const ThemeToggle = () =>
+ ArrowToggleButton({
+ name: "theme",
+ icon: ThemeIcon(),
+ label: Widget.Label({
+ connections: [
+ [
+ Theme,
+ (label) => {
+ label.label = prettyName(Theme.getSetting("theme"));
+ },
+ ],
+ ],
+ }),
+ connection: [opened, () => opened.value === "theme"],
+ activate: () => opened.setValue("theme"),
+ activateOnArrow: false,
+ deactivate: () => {},
+ });
+
+export const ThemeSelector = () =>
+ Menu({
+ name: "theme",
+ icon: ThemeIcon(),
+ title: Widget.Label("Theme Selector"),
+ content: Widget.Box({
+ vertical: true,
+ children: themes
+ .map(({ name, icon }) =>
+ Widget.Button({
+ onClicked: () => Theme.setSetting("theme", name),
+ child: Widget.Box({
+ children: [
+ Widget.Label(icon),
+ Widget.Label(prettyName(name)),
+ Widget.Icon({
+ icon: icons.tick,
+ hexpand: true,
+ halign: "end",
+ connections: [
+ [
+ Theme,
+ (icon) => {
+ icon.visible =
+ Theme.getSetting(
+ "theme",
+ ) === name;
+ },
+ ],
+ ],
+ }),
+ ],
+ }),
+ }),
+ )
+ .concat([
+ Separator({ orientation: "horizontal" }),
+ Widget.Button({
+ onClicked: () => Theme.openSettings(),
+ child: Widget.Box({
+ children: [
+ Widget.Icon(icons.settings),
+ Widget.Label("Theme Settings"),
+ ],
+ }),
+ }),
+ ]),
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Volume.js b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Volume.js
new file mode 100644
index 000000000..dd340d1b4
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/quicksettings/widgets/Volume.js
@@ -0,0 +1,212 @@
+import icons from "../../icons.js";
+import FontIcon from "../../misc/FontIcon.js";
+import Separator from "../../misc/Separator.js";
+import { getAudioTypeIcon } from "../../utils.js";
+import { Arrow } from "../ToggleButton.js";
+import { Menu } from "../ToggleButton.js";
+import { Audio, Widget, Utils } from "../../imports.js";
+
+const VolumeIndicator = (type = "speaker") =>
+ Widget.Button({
+ onClicked: () => (Audio[type].isMuted = !Audio[type].isMuted),
+ child: Widget.Icon({
+ connections: [
+ [
+ Audio,
+ (icon) => {
+ if (!Audio[type]) return;
+
+ icon.icon =
+ type === "speaker"
+ ? getAudioTypeIcon(Audio[type].iconName)
+ : icons.audio.mic.high;
+
+ icon.tooltipText = `Volume ${Math.floor(
+ Audio[type].volume * 100,
+ )}%`;
+ },
+ `${type}-changed`,
+ ],
+ ],
+ }),
+ });
+
+const VolumeSlider = (type = "speaker") =>
+ Widget.Slider({
+ hexpand: true,
+ drawValue: false,
+ onChange: ({ value }) => (Audio[type].volume = value),
+ connections: [
+ [
+ Audio,
+ (slider) => {
+ slider.value = Audio[type].volume;
+ },
+ `${type}-changed`,
+ ],
+ ],
+ });
+
+export const Volume = () =>
+ Widget.Box({
+ className: "slider",
+ children: [
+ VolumeIndicator("speaker"),
+ VolumeSlider("speaker"),
+ Arrow("sink-selector"),
+ Widget.Box({
+ child: Arrow("app-mixer"),
+ connections: [
+ [
+ Audio,
+ (box) => {
+ box.visible = Audio.apps.length > 0;
+ },
+ ],
+ ],
+ }),
+ ],
+ });
+
+export const Microphone = () =>
+ Widget.Box({
+ className: "slider",
+ binds: [["visible", Audio, "recorders", (r) => r.length > 0]],
+ children: [VolumeIndicator("microphone"), VolumeSlider("microphone")],
+ });
+
+const MixerItem = (stream) =>
+ Widget.Box({
+ hexpand: true,
+ className: "mixer-item",
+ children: [
+ Widget.Icon({
+ binds: [["tooltipText", stream, "name"]],
+ connections: [
+ [
+ stream,
+ (icon) => {
+ icon.icon = Utils.lookUpIcon(stream.name)
+ ? stream.name
+ : icons.mpris.fallback;
+ },
+ ],
+ ],
+ }),
+ Widget.Box({
+ children: [
+ Widget.Box({
+ vertical: true,
+ children: [
+ Widget.Label({
+ xalign: 0,
+ truncate: "end",
+ binds: [["label", stream, "description"]],
+ }),
+ Widget.Slider({
+ hexpand: true,
+ drawValue: false,
+ binds: [["value", stream, "volume"]],
+ onChange: ({ value }) =>
+ (stream.volume = value),
+ }),
+ ],
+ }),
+ Widget.Label({
+ xalign: 1,
+ connections: [
+ [
+ stream,
+ (l) => {
+ l.label = `${Math.floor(
+ stream.volume * 100,
+ )}%`;
+ },
+ ],
+ ],
+ }),
+ ],
+ }),
+ ],
+ });
+
+const SinkItem = (stream) =>
+ Widget.Button({
+ hexpand: true,
+ onClicked: () => (Audio.speaker = stream),
+ child: Widget.Box({
+ children: [
+ Widget.Icon({
+ icon: getAudioTypeIcon(stream.iconName),
+ tooltipText: stream.iconName,
+ }),
+ Widget.Label(
+ stream.description.split(" ").slice(0, 4).join(" "),
+ ),
+ Widget.Icon({
+ icon: icons.tick,
+ hexpand: true,
+ halign: "end",
+ connections: [
+ [
+ "draw",
+ (icon) => {
+ icon.visible = Audio.speaker === stream;
+ },
+ ],
+ ],
+ }),
+ ],
+ }),
+ });
+
+const SettingsButton = () =>
+ Widget.Button({
+ onClicked: "pavucontrol",
+ hexpand: true,
+ child: Widget.Box({
+ children: [Widget.Icon(icons.settings), Widget.Label("Settings")],
+ }),
+ });
+
+export const AppMixer = () =>
+ Menu({
+ name: "app-mixer",
+ icon: FontIcon(icons.audio.mixer),
+ title: Widget.Label("App Mixer"),
+ content: Widget.Box({
+ className: "app-mixer",
+ vertical: true,
+ children: [
+ Widget.Box({
+ vertical: true,
+ binds: [
+ ["children", Audio, "apps", (a) => a.map(MixerItem)],
+ ],
+ }),
+ Separator({ orientation: "horizontal" }),
+ SettingsButton(),
+ ],
+ }),
+ });
+
+export const SinkSelector = () =>
+ Menu({
+ name: "sink-selector",
+ icon: Widget.Icon(icons.audio.type.headset),
+ title: Widget.Label("Sink Selector"),
+ content: Widget.Box({
+ className: "sink-selector",
+ vertical: true,
+ children: [
+ Widget.Box({
+ vertical: true,
+ binds: [
+ ["children", Audio, "speakers", (s) => s.map(SinkItem)],
+ ],
+ }),
+ Separator({ orientation: "horizontal" }),
+ SettingsButton(),
+ ],
+ }),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/screencorner/ScreenCorners.js b/home/isabel/programs/gui/confs/bars/ags/config/js/screencorner/ScreenCorners.js
new file mode 100644
index 000000000..9feacb0a2
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/screencorner/ScreenCorners.js
@@ -0,0 +1,72 @@
+import Gtk from "gi://Gtk";
+import { Widget } from "../imports.js";
+
+const Corner = (place) =>
+ Widget({
+ type: Gtk.DrawingArea,
+ className: "corner",
+ hexpand: true,
+ vexpand: true,
+ halign: place.includes("left") ? "start" : "end",
+ valign: place.includes("top") ? "start" : "end",
+ setup: (widget) => widget.set_size_request(32, 32),
+ connections: [
+ [
+ "draw",
+ (widget, cr) => {
+ const context = widget.get_style_context();
+ const c = context.get_property(
+ "background-color",
+ Gtk.StateFlags.NORMAL,
+ );
+ const r = context.get_property(
+ "border-radius",
+ Gtk.StateFlags.NORMAL,
+ );
+ widget.set_size_request(r, r);
+
+ switch (place) {
+ case "topleft":
+ cr.arc(r, r, r, Math.PI, (3 * Math.PI) / 2);
+ cr.lineTo(0, 0);
+ break;
+
+ case "topright":
+ cr.arc(0, r, r, (3 * Math.PI) / 2, 2 * Math.PI);
+ cr.lineTo(r, 0);
+ break;
+
+ case "bottomleft":
+ cr.arc(r, 0, r, Math.PI / 2, Math.PI);
+ cr.lineTo(0, r);
+ break;
+
+ case "bottomright":
+ cr.arc(0, 0, r, 0, Math.PI / 2);
+ cr.lineTo(r, r);
+ break;
+ }
+
+ cr.closePath();
+ cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
+ cr.fill();
+ cr.$dispose();
+ },
+ ],
+ ],
+ });
+
+const places = ["topleft", "topright", "bottomleft", "bottomright"];
+export default (monitor) =>
+ places.map((place) =>
+ Widget.Window({
+ name: `corner${monitor}${place}`,
+ monitor,
+ className: "corner",
+ anchor: [
+ place.includes("top") ? "top" : "bottom",
+ place.includes("right") ? "right" : "left",
+ ],
+ child: Corner(place),
+ }),
+ );
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/services/brightness.js b/home/isabel/programs/gui/confs/bars/ags/config/js/services/brightness.js
new file mode 100644
index 000000000..d66bd3b3f
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/services/brightness.js
@@ -0,0 +1,45 @@
+import { Service, Utils } from "../imports.js";
+
+class Brightness extends Service {
+ static {
+ Service.register(
+ this,
+ {},
+ {
+ screen: ["float", "rw"],
+ },
+ );
+ }
+
+ _screen = 0;
+
+ get screen() {
+ return this._screen;
+ }
+
+ set screen(percent) {
+ if (percent < 0) percent = 0;
+
+ if (percent > 1) percent = 1;
+
+ Utils.execAsync(`brightnessctl s ${percent * 100}% -q`)
+ .then(() => {
+ this._screen = percent;
+ this.changed("screen");
+ })
+ .catch(console.error);
+ }
+
+ constructor() {
+ super();
+ try {
+ this._screen =
+ Number(Utils.exec("brightnessctl g")) /
+ Number(Utils.exec("brightnessctl m"));
+ } catch (error) {
+ console.error("missing dependancy: brightnessctl");
+ }
+ }
+}
+
+export default new Brightness();
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/services/onScreenIndicator.js b/home/isabel/programs/gui/confs/bars/ags/config/js/services/onScreenIndicator.js
new file mode 100644
index 000000000..9b621d0b5
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/services/onScreenIndicator.js
@@ -0,0 +1,46 @@
+import { Service, Utils } from "../imports.js";
+import icons from "../icons.js";
+import { getAudioTypeIcon } from "../utils.js";
+import { Audio } from "../imports.js";
+import Brightness from "./brightness.js";
+
+class Indicator extends Service {
+ static {
+ Service.register(this, {
+ popup: ["double", "string"],
+ });
+ }
+
+ _delay = 1500;
+ _count = 0;
+
+ popup(value, icon) {
+ this.emit("popup", value, icon);
+ this._count++;
+ Utils.timeout(this._delay, () => {
+ this._count--;
+
+ if (this._count === 0) this.emit("popup", -1, icon);
+ });
+ }
+
+ speaker() {
+ this.popup(
+ Audio.speaker.volume,
+ getAudioTypeIcon(Audio.speaker.iconName),
+ );
+ }
+
+ display() {
+ // brightness is async, so lets wait a bit
+ Utils.timeout(10, () =>
+ this.popup(Brightness.screen, icons.brightness.screen),
+ );
+ }
+
+ connectWidget(widget, callback) {
+ Utils.connect(this, widget, callback, "popup");
+ }
+}
+
+export default new Indicator();
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/services/powermenu.js b/home/isabel/programs/gui/confs/bars/ags/config/js/services/powermenu.js
new file mode 100644
index 000000000..22ba327e9
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/services/powermenu.js
@@ -0,0 +1,38 @@
+import { App, Service } from "../imports.js";
+
+class PowerMenu extends Service {
+ static {
+ Service.register(
+ this,
+ {},
+ {
+ title: ["string"],
+ cmd: ["string"],
+ },
+ );
+ }
+
+ get title() {
+ return this._title || "";
+ }
+ get cmd() {
+ return this._cmd || "";
+ }
+
+ action(action) {
+ [this._cmd, this._title] = {
+ sleep: ["systemctl suspend", "Sleep"],
+ reboot: ["systemctl reboot", "Reboot"],
+ logout: ["pkill Hyprland", "Log Out"],
+ shutdown: ["shutdown now", "Shutdown"],
+ }[action];
+
+ this.notify("cmd");
+ this.notify("title");
+ this.emit("changed");
+ App.closeWindow("powermenu");
+ App.openWindow("verification");
+ }
+}
+
+export default new PowerMenu();
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/hyprland.js b/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/hyprland.js
new file mode 100644
index 000000000..acb782ee7
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/hyprland.js
@@ -0,0 +1,36 @@
+import { App, Utils } from "../../imports.js";
+
+const noAlphaignore = ["verification", "powermenu"];
+
+export default function () {
+ try {
+ App.connect("config-parsed", () => {
+ for (const [name] of App.windows) {
+ Utils.execAsync([
+ "hyprctl",
+ "keyword",
+ "layerrule",
+ `unset, ${name}`,
+ ]).then(() => {
+ Utils.execAsync([
+ "hyprctl",
+ "keyword",
+ "layerrule",
+ `blur, ${name}`,
+ ]);
+ if (!noAlphaignore.every((skip) => !name.includes(skip)))
+ return;
+
+ Utils.execAsync([
+ "hyprctl",
+ "keyword",
+ "layerrule",
+ `ignorealpha 0.6, ${name}`,
+ ]);
+ });
+ }
+ });
+ } catch (error) {
+ console.error(error);
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/theme/scss.js b/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/scss.js
similarity index 52%
rename from home/isabel/programs/gui/confs/bars/ags/config/theme/scss.js
rename to home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/scss.js
index fc7b479a9..eba10eeed 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/theme/scss.js
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/scss.js
@@ -1,9 +1,9 @@
-import { execAsync, writeFile } from 'resource:///com/github/Aylur/ags/utils.js';
+import { Utils, App } from "../../imports.js";
-const generated = str => `// THIS FILE IS GENERATED
+const generated = (str) => `// THIS FILE IS GENERATED
${str}`;
-const scss = t => `$theme: '${t.color_scheme}';
+const scss = (t) => `$theme: '${t.color_scheme}';
$red: ${t.red};
$green: ${t.green};
@@ -24,7 +24,10 @@ $spacing: ${t.spacing}px;
$accent: ${t.accent};
$accent_fg: ${t.accent_fg};
-$hover: transparentize(${t.widget_bg}, ${Math.max((t.widget_opacity * 0.90) / 100, 0)});
+$hover: transparentize(${t.widget_bg}, ${Math.max(
+ (t.widget_opacity * 0.9) / 100,
+ 0,
+)});
$widget_bg: transparentize(${t.widget_bg}, ${t.widget_opacity / 100});
$active_gradient: linear-gradient(${t.active_gradient});
@@ -37,30 +40,38 @@ $text_shadow: 2px 2px 2px $shadow;
$icon_shadow: 2px 2px $shadow;
$popover_radius: ${t.radii * 1.7}px;
-$popover_border_color: transparentize(${t.border_color}, ${Math.max((t.border_opacity - 1) / 100, 0)});
+$popover_border_color: transparentize(${t.border_color}, ${Math.max(
+ (t.border_opacity - 1) / 100,
+ 0,
+)});
$popover_padding: ${t.spacing * 1.8}px;
$drop_shadow: ${t.drop_shadow};
$transition: ${t.transition}ms;
-$font_size: 16px;
-$font: 'Ubuntu Nerd Font';
-$mono_font: 'Mononoki Nerd Font', monospace;
-$wallpaper_fg: white;
+$font_size: ${t.font_size}px;
+$font: '${t.font}';
+$mono_font: '${t.mono_font}', monospace;
+$wallpaper_fg: ${t.wallpaper_fg};
$shader_fg: white;
-$screen_corners: ${t.bar_style === 'normal' && t.screen_corners};
+$screen_corners: ${t.bar_style === "normal" && t.screen_corners};
$bar_style: ${t.bar_style};
$layout: ${t.layout};`;
-export async function setupScss(theme) {
- const path = ags.App.configDir;
+export default async function (theme) {
+ const tmp = "/tmp/ags/scss";
+ Utils.ensureDirectory(tmp);
try {
- await writeFile(generated(scss(theme)), `${path}/scss/generated.scss`);
- await execAsync(['sassc', `${path}/scss/main.scss`, `${path}/style.css`]);
- ags.App.resetCss();
- ags.App.applyCss(`${path}/style.css`);
+ await Utils.writeFile(generated(scss(theme)), `${tmp}/generated.scss`);
+ await Utils.writeFile(
+ generated(theme.additional_scss || ""),
+ `${tmp}/additional.scss`,
+ );
+ Utils.exec(`sassc ${App.configDir}/scss/main.scss ${tmp}/style.css`);
+ App.resetCss();
+ App.applyCss(`${tmp}/style.css`);
} catch (error) {
- logError(error);
+ console.error(error);
}
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/theme.js b/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/theme.js
new file mode 100755
index 000000000..fe7339729
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/services/theme/theme.js
@@ -0,0 +1,130 @@
+import themes from "../../themes.js";
+import setupScss from "./scss.js";
+import setupHyprland from "./hyprland.js";
+import SettingsDialog from "../../settingsdialog/SettingsDialog.js";
+import IconBrowser from "../../misc/IconBrowser.js";
+import { Service, Utils } from "../../imports.js";
+
+const THEME_CACHE = Utils.CACHE_DIR + "/theme-overrides.json";
+
+class ThemeService extends Service {
+ static {
+ Service.register(this);
+ }
+
+ get themes() {
+ return themes;
+ }
+
+ _defaultAvatar = `/home/${Utils.USER}/media/pictures/pfps/avatar`;
+ _defaultTheme = themes[0].name;
+
+ constructor() {
+ super();
+ try {
+ Utils.exec("swww init");
+ } catch (error) {
+ print("missing dependancy: swww");
+ }
+ this.setup();
+ }
+
+ openSettings() {
+ if (!this._dialog) this._dialog = SettingsDialog();
+
+ this._dialog.hide();
+ this._dialog.present();
+ }
+
+ iconBrowser() {
+ IconBrowser();
+ }
+
+ getTheme() {
+ return themes.find(({ name }) => name === this.getSetting("theme"));
+ }
+
+ setup() {
+ const theme = {
+ ...this.getTheme(),
+ ...this.settings,
+ };
+ setupScss(theme);
+ setupHyprland();
+ this.setupOther();
+ this.setupWallpaper();
+ }
+
+ reset() {
+ Utils.exec(`rm ${THEME_CACHE}`);
+ this._settings = null;
+ this.setup();
+ this.emit("changed");
+ }
+
+ setupOther() {
+ const darkmode = this.getSetting("color_scheme") === "dark";
+
+ if (Utils.exec("which gsettings")) {
+ const gsettings =
+ "gsettings set org.gnome.desktop.interface color-scheme";
+ Utils.execAsync(
+ `${gsettings} "prefer-${darkmode ? "dark" : "light"}"`,
+ ).catch(print);
+ }
+ }
+
+ setupWallpaper() {
+ Utils.execAsync(["swww", "img", this.getSetting("wallpaper")]).catch(
+ (err) => console.error(err),
+ );
+ }
+
+ get settings() {
+ if (this._settings) return this._settings;
+
+ try {
+ this._settings = JSON.parse(Utils.readFile(THEME_CACHE));
+ } catch (_) {
+ this._settings = {};
+ }
+
+ return this._settings;
+ }
+
+ setSetting(prop, value) {
+ const settings = this.settings;
+ settings[prop] = value;
+ Utils.writeFile(JSON.stringify(settings, null, 2), THEME_CACHE).catch(
+ (err) => console.error(err),
+ );
+ this._settings = settings;
+ this.emit("changed");
+
+ if (prop === "layout") {
+ if (!this._notiSent) {
+ this._notiSent = true;
+ Utils.execAsync([
+ "notify-send",
+ "Layout Change Needs a Reload",
+ ]);
+ }
+ return;
+ }
+
+ this.setup();
+ }
+
+ getSetting(prop) {
+ if (prop === "theme") return this.settings.theme || this._defaultTheme;
+
+ if (prop === "avatar")
+ return this.settings.avatar || this._defaultAvatar;
+
+ return this.settings[prop] !== undefined
+ ? this.settings[prop]
+ : this.getTheme()[prop];
+ }
+}
+
+export default new ThemeService();
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/settingsdialog/SettingsDialog.js b/home/isabel/programs/gui/confs/bars/ags/config/js/settingsdialog/SettingsDialog.js
new file mode 100644
index 000000000..8d36bea87
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/settingsdialog/SettingsDialog.js
@@ -0,0 +1,352 @@
+import Gtk from "gi://Gtk";
+import Theme from "../services/theme/theme.js";
+import themes from "../themes.js";
+import Wallpaper from "../misc/Wallpaper.js";
+import { Widget, Variable } from "../imports.js";
+
+const Row = (title, child) =>
+ Widget.Box({
+ className: "row",
+ children: [Widget.Label(`${title}: `), child],
+ });
+
+const Img = (title, prop) =>
+ Row(
+ title,
+ Widget({
+ title,
+ type: Gtk.FileChooserButton,
+ hexpand: true,
+ halign: "end",
+ connections: [
+ [
+ "selection-changed",
+ (w) =>
+ Theme.setSetting(
+ prop,
+ w.get_uri().replace("file://", ""),
+ ),
+ ],
+ ],
+ }),
+ );
+
+const SpinButton = (title, prop, max = 100, min = 0) =>
+ Row(
+ title,
+ Widget({
+ type: Gtk.SpinButton,
+ setup: (w) => {
+ w.set_range(min, max);
+ w.set_increments(1, 1);
+ },
+ hexpand: true,
+ halign: "end",
+ connections: [
+ [
+ "value-changed",
+ (b) => !b._block && Theme.setSetting(prop, b.value),
+ ],
+ [
+ Theme,
+ (b) => {
+ b._block = true;
+ b.value = Theme.getSetting(prop);
+ b._block = false;
+ },
+ ],
+ ],
+ }),
+ );
+
+const SwitchButton = (title, prop) =>
+ Row(
+ title,
+ Widget({
+ type: Gtk.Switch,
+ halign: "end",
+ hexpand: true,
+ connections: [
+ [
+ Theme,
+ (s) => {
+ s._block = true;
+ s.active = Theme.getSetting(prop);
+ s._block = false;
+ },
+ ],
+ [
+ "notify::active",
+ (s) => !s._block && Theme.setSetting(prop, s.active),
+ ],
+ ],
+ }),
+ );
+
+const Color = (title, prop) =>
+ Row(
+ title,
+ Widget.Box({
+ hexpand: true,
+ halign: "end",
+ className: "color",
+ children: [
+ Widget.Entry({
+ onAccept: ({ text }) => Theme.setSetting(prop, text),
+ valign: "center",
+ connections: [
+ [Theme, (w) => (w.text = Theme.getSetting(prop))],
+ ],
+ }),
+ Widget({
+ type: Gtk.ColorButton,
+ alpha: true,
+ valign: "center",
+ connections: [
+ [
+ "color-set",
+ (w) => {
+ w.get_parent().children[0].set_text(
+ w.rgba.to_string(),
+ );
+ Theme.setSetting(prop, w.rgba.to_string());
+ },
+ ],
+ ],
+ }),
+ ],
+ }),
+ );
+
+const Text = (title, prop) =>
+ Row(
+ title,
+ Widget.Entry({
+ className: "text",
+ hexpand: true,
+ halign: "end",
+ connections: [[Theme, (w) => (w.text = Theme.getSetting(prop))]],
+ onAccept: ({ text }) => Theme.setSetting(prop, text),
+ }),
+ );
+
+const TextSpinButton = (title, prop, list) =>
+ Row(
+ title,
+ Widget.Box({
+ className: "text-spin",
+ hexpand: true,
+ halign: "end",
+ properties: [
+ ["values", list],
+ [
+ "step",
+ (box, step) => {
+ const label = box.get_children()[0];
+ const max = box._values.length - 1;
+ let index = box._values.indexOf(label.label) + step;
+
+ if (index > max) index = 0;
+
+ if (index < 0) index = max;
+
+ const value = box._values[index];
+ label.label = value;
+ Theme.setSetting(prop, value);
+ },
+ ],
+ ],
+ children: [
+ Widget.Label({
+ connections: [
+ [
+ Theme,
+ (label) => (label.label = Theme.getSetting(prop)),
+ ],
+ ],
+ }),
+ Widget.Button({
+ child: Widget.Icon("pan-down-symbolic"),
+ onClicked: (btn) => {
+ const box = btn.get_parent();
+ box._step(box, -1);
+ },
+ }),
+ Widget.Button({
+ child: Widget.Icon("pan-up-symbolic"),
+ onClicked: (btn) => {
+ const box = btn.get_parent();
+ box._step(box, +1);
+ },
+ }),
+ ],
+ }),
+ );
+
+const FontButton = (title, prop) =>
+ Row(
+ title,
+ Widget({
+ type: Gtk.FontButton,
+ hexpand: true,
+ halign: "end",
+ useSize: false,
+ showSize: false,
+ fontName: Theme.getSetting(prop),
+ connections: [
+ [
+ "font-set",
+ ({ fontName }) => {
+ Theme.setSetting(prop, fontName);
+ },
+ ],
+ ],
+ }),
+ );
+
+const page = Variable(" General");
+const showPage = (p) => (page.value = p);
+
+const Tab = (name) =>
+ Widget.Button({
+ hexpand: true,
+ className: "tab",
+ onClicked: () => showPage(name),
+ child: Widget.Label(name),
+ connections: [
+ [page, (b) => b.toggleClassName("active", page.value === name)],
+ ],
+ });
+
+const Layout = (pages) =>
+ Widget.Box({
+ vertical: true,
+ className: "settings",
+ hexpand: false,
+ children: [
+ Widget.Box({
+ className: "headerbar",
+ valign: "start",
+ child: Widget.Box({
+ className: "tabs",
+ children: [
+ ...Object.keys(pages).map((page) => Tab(page)),
+ Widget.Button({
+ className: "tab",
+ onClicked: () => Theme.reset(),
+ child: Widget.Label(" Reset"),
+ hexpand: true,
+ }),
+ ],
+ }),
+ }),
+ Widget.Box({
+ className: "content",
+ child: Widget.Stack({
+ transition: "slide_left_right",
+ items: Object.keys(pages).map((page) => [
+ page,
+ pages[page],
+ ]),
+ binds: [["shown", page]],
+ }),
+ }),
+ Widget.Label({
+ wrap: true,
+ className: "disclaimer",
+ label:
+ "These settings override all preset themes. " +
+ "To make them permanent: edit ~/.config/ags/theme/themes.js",
+ }),
+ ],
+ });
+
+const Page = (children) =>
+ Widget.Scrollable({
+ child: Widget.Box({
+ vertical: true,
+ children,
+ }),
+ });
+
+export default () =>
+ Widget({
+ type: Gtk.Window,
+ name: "settings",
+ child: Layout({
+ " General": Page([
+ Wallpaper({
+ className: "row",
+ hexpand: true,
+ vexpand: true,
+ }),
+ Img("Wallpaper", "wallpaper"),
+ Img("Avatar", "avatar"),
+ SpinButton("Useless Gaps", "wm_gaps", 128),
+ SpinButton("Spacing", "spacing", 18),
+ SpinButton("Roundness", "radii", 36),
+ // TextSpinButton('Layout', 'layout', ['topbar', 'bottombar']),
+ TextSpinButton("Bar Style", "bar_style", [
+ "normal",
+ "floating",
+ "separated",
+ ]),
+ SwitchButton("Screen Corners", "screen_corners"),
+ ]),
+ " Colors": Page([
+ TextSpinButton("Color Theme", "color_scheme", [
+ "light",
+ "dark",
+ ]),
+ ...[
+ "Red",
+ "Green",
+ "Yellow",
+ "Blue",
+ "Magenta",
+ "Teal",
+ "Orange",
+ ].map((c) => Color(c, c.toLowerCase())),
+ ]),
+ " Theme": Page([
+ TextSpinButton(
+ "Theme",
+ "theme",
+ themes.map((t) => t.name),
+ ),
+ Color("Background Color", "bg_color"),
+ Color("Foreground Color", "fg_color"),
+ Color("Hovered Foreground Color", "hover_fg"),
+ Text("Hyprland Active Border Color", "hypr_active_border"),
+ Text("Hyprland Inactive Border Color", "hypr_inactive_border"),
+ Color("Accent Color", "accent"),
+ Color("Accent Foreground", "accent_fg"),
+ Text("Active Gradient", "active_gradient"),
+ Color("Widget Background", "widget_bg"),
+ SpinButton("Widget Opacity", "widget_opacity"),
+ Color("Border Color", "border_color"),
+ SpinButton("Border Width", "border_width"),
+ SpinButton("Border Opacity", "border_opacity"),
+ ]),
+ " Miscellaneous": Page([
+ Color("Shadow", "shadow"),
+ SwitchButton("Drop Shadow", "drop_shadow"),
+ SpinButton("Transition", "transition", 1000),
+ Text("Desktop Clock Position", "desktop_clock"),
+ Color("Wallpaper Foreground Color", "wallpaper_fg"),
+ FontButton("Font", "font"),
+ FontButton("Mono Font", "mono_font"),
+ SpinButton("Font Size", "font_size"),
+ ]),
+ }),
+ connections: [
+ [
+ "delete-event",
+ (win) => {
+ win.hide();
+ return true;
+ },
+ ],
+ ],
+ setup: (win) => win.set_default_size(700, 600),
+ });
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/themes.js b/home/isabel/programs/gui/confs/bars/ags/config/js/themes.js
new file mode 100644
index 000000000..0e6087e49
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/themes.js
@@ -0,0 +1,79 @@
+import { Utils } from "./imports.js";
+
+const WP = `/home/${Utils.USER}/media/pictures/wallpapers/`;
+
+const mocha_colors = {
+ bg_color: "#1e1e2e",
+ fg_color: "#cdd6f4",
+ hover_fg: "#cdd6f4",
+ red: "#f38ba8",
+ green: "#a6e3a1",
+ yellow: "#f9e2af",
+ blue: "#74c7ec",
+ magenta: "#cba6f7",
+ teal: "#94e2d5",
+ orange: "#fab387",
+};
+
+const latte_colors = {
+ bg_color: "#eff1f5",
+ fg_color: "#4c4f69",
+ hover_fg: "#4c4f69",
+ red: "#d20f39",
+ green: "#40a02b",
+ yellow: "#df8e1d",
+ blue: "#209fb5",
+ magenta: "#8839ef",
+ teal: "#179299",
+ orange: "#fe640b",
+};
+
+const settings = {
+ wm_gaps: 8,
+ radii: 9,
+ spacing: 9,
+ drop_shadow: true,
+ transition: 200,
+ screen_corners: false,
+ bar_style: "floating",
+ layout: "topbar",
+ border_opacity: 97,
+ border_width: 1,
+ widget_opacity: 94,
+ font: "Ubuntu Nerd Font",
+ mono_font: "Mononoki Nerd Font",
+ font_size: 16,
+};
+
+const misc_colors = {
+ wallpaper_fg: "white",
+ shadow: "rgba(0, 0, 0, .6)",
+ accent: "$blue",
+ accent_fg: "$bg_color",
+ widget_bg: "$fg_color",
+ active_gradient: "to right, $accent, lighten($accent, 6%)",
+ border_color: "$fg_color",
+};
+
+// themes
+const mocha = {
+ wallpaper: WP + "tempest.png",
+ name: "mocha",
+ color_scheme: "dark",
+ icon: "",
+ ...mocha_colors,
+ ...settings,
+ ...misc_colors,
+};
+
+const latte = {
+ wallpaper: WP + "coke.jpg",
+ name: "latte",
+ color_scheme: "light",
+ icon: "",
+ ...latte_colors,
+ ...settings,
+ ...misc_colors,
+};
+
+export default [mocha, latte];
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/utils.js b/home/isabel/programs/gui/confs/bars/ags/config/js/utils.js
new file mode 100644
index 000000000..b58d92adf
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/utils.js
@@ -0,0 +1,107 @@
+import Cairo from "cairo";
+import options from "./options.js";
+import icons from "./icons.js";
+import Theme from "./services/theme/theme.js";
+import { Utils, App, Battery, Mpris, Audio } from "./imports.js";
+
+/** @type {function((id: number) => typeof Gtk.Widget): typeof Gtk.Widget[]}*/
+export function forMonitors(widget) {
+ const ws = JSON.parse(Utils.exec("hyprctl -j monitors"));
+ return ws.map((/** @type {Record} */ mon) =>
+ widget(mon.id),
+ );
+}
+
+export function range(length, start = 1) {
+ return Array.from({ length }, (_, i) => i + start);
+}
+
+export function substitute(collection, item) {
+ return collection.find(([from]) => from === item)?.[1] || item;
+}
+
+export function createSurfaceFromWidget(widget) {
+ 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;
+}
+
+export function warnOnLowBattery() {
+ const { low } = options.battaryBar;
+ Battery.connect("notify::percent", () => {
+ if (Battery.percent === low || Battery.percent === low / 2) {
+ Utils.execAsync([
+ "notify-send",
+ `${Battery.percent}% Battery Percentage`,
+ "-i",
+ icons.battery.warning,
+ "-u",
+ "critical",
+ ]);
+ }
+ });
+}
+
+export function getAudioTypeIcon(icon) {
+ const substitues = [
+ ["audio-headset-bluetooth", icons.audio.type.headset],
+ ["audio-card-analog-usb", icons.audio.type.speaker],
+ ["audio-card-analog-pci", icons.audio.type.card],
+ ];
+
+ for (const [from, to] of substitues) {
+ if (from === icon) return to;
+ }
+
+ return icon;
+}
+
+export function scssWatcher() {
+ return Utils.subprocess(
+ [
+ "inotifywait",
+ "--recursive",
+ "--event",
+ "create,modify",
+ "-m",
+ App.configDir + "/scss",
+ ],
+ () => Theme.setup(),
+ () => print("missing dependancy for css hotreload: inotify-tools"),
+ );
+}
+
+export function activePlayer() {
+ let active;
+ globalThis.mpris = () => active || Mpris.players[0];
+ Mpris.connect("player-added", (mpris, bus) => {
+ mpris.getPlayer(bus)?.connect("changed", (player) => {
+ active = player;
+ });
+ });
+}
+
+export async function globalServices() {
+ globalThis.audio = Audio;
+ globalThis.ags = await import("./imports.js");
+ globalThis.brightness = (await import("./services/brightness.js")).default;
+ globalThis.indicator = (
+ await import("./services/onScreenIndicator.js")
+ ).default;
+ globalThis.theme = (await import("./services/theme/theme.js")).default;
+}
+
+export function launchApp(app) {
+ Utils.execAsync(`hyprctl dispatch exec ${app.executable}`);
+ app.frequency += 1;
+}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/js/variables.js b/home/isabel/programs/gui/confs/bars/ags/config/js/variables.js
new file mode 100755
index 000000000..31ccc7661
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/ags/config/js/variables.js
@@ -0,0 +1,81 @@
+import options from "./options.js";
+import { Variable, Utils } from "./imports.js";
+
+export const uptime = Variable("", {
+ poll: [
+ 60_000,
+ "cat /proc/uptime",
+ (line) => {
+ const uptime = Number.parseInt(line.split(".")[0]) / 60;
+ const h = Math.floor(uptime / 60);
+ const s = Math.floor(uptime % 60);
+ return `${h}:${s < 10 ? "0" + s : s}`;
+ },
+ ],
+});
+
+export const distro = Utils.exec("cat /etc/os-release")
+ .split("\n")
+ .find((line) => line.startsWith("ID"))
+ .split("=")[1];
+
+export const distroIcon = (() => {
+ switch (distro) {
+ case "fedora":
+ return "";
+ case "arch":
+ return "";
+ case "nixos":
+ return "";
+ case "debian":
+ return "";
+ case "opensuse-tumbleweed":
+ return "";
+ case "ubuntu":
+ return "";
+ case "endeavouros":
+ return "";
+ default:
+ return "";
+ }
+})();
+
+const divide = ([total, free]) => free / total;
+export const cpu = Variable(0, {
+ poll: [
+ options.systemFetchInterval,
+ "top -b -n 1",
+ (out) =>
+ divide([
+ 100,
+ out
+ .split("\n")
+ .find((line) => line.includes("Cpu(s)"))
+ ?.split(/\s+/)[1]
+ .replace(",", "."),
+ ]),
+ ],
+});
+
+export const ram = Variable(0, {
+ poll: [
+ options.systemFetchInterval,
+ "free",
+ (out) =>
+ divide(
+ out
+ .split("\n")
+ .find((line) => line.includes("Mem:"))
+ ?.split(/\s+/)
+ .splice(1, 2),
+ ),
+ ],
+});
+
+export const temp = Variable(0, {
+ poll: [
+ options.systemFetchInterval,
+ "cat " + options.temperature,
+ (n) => n / 100_000,
+ ],
+});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/leftbar.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/leftbar.js
deleted file mode 100644
index a0e00762f..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/leftbar.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as shared from './shared.js';
-import { Launcher } from './shared.js';
-import { Workspaces } from './widgets/hyprland.js';
-import { Separator } from '../modules/misc.js';
-import { PanelIndicator as MediaIndicator } from './widgets/media.js';
-import { PanelIndicator as NotificationIndicator } from './widgets/notifications.js';
-import { DistroIcon } from '../modules/misc.js';
-import { PanelButton as ColorPicker } from '../modules/colorpicker.js';
-import { PanelButton as PowerMenu } from './widgets/powermenu.js';
-import { PanelButton as DashBoard } from './widgets/dashboard.js';
-import { PanelButton as QuickSettings } from './widgets/quicksettings.js';
-
-const Bar = monitor => shared.Bar({
- anchor: 'top left bottom',
- vertical: true,
- monitor,
- start: [
- Launcher({ child: DistroIcon() }),
- Workspaces({ vertical: true }),
- // MediaIndicator({ hexpand: false, halign: 'end' }),
- ],
- center: [
- DashBoard({ format: '%I\n܅\n%M' }),
- ],
- end: [
- // NotificationIndicator({ direction: 'right', hexpand: false, halign: 'start' }),
- // ags.Widget.Box({ hexpand: true }),
- ColorPicker(),
- Separator({ valign: 'center' }),
- QuickSettings({ vertical: true }),
- Separator({ valign: 'center' }),
- PowerMenu(),
- ],
-});
-
-export default monitors => ([
- ...monitors.map(monitor => [
- Bar(monitor),
- shared.Notifications(monitor, 'slide_down', 'top'),
- shared.Desktop(monitor),
- ...shared.Corners(monitor),
- shared.OSDIndicator(monitor),
- ]),
- shared.Quicksettings({ position: 'bottom left' }),
- shared.Dashboard({ position: 'left' }),
-]).flat(2);
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/shared.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/shared.js
deleted file mode 100644
index 18d7748d2..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/shared.js
+++ /dev/null
@@ -1,113 +0,0 @@
-const { Window, CenterBox, Box, Button } = ags.Widget;
-import { Corner } from '../modules/corner.js';
-import { OnScreenIndicator } from '../modules/onscreenindicator.js';
-import { Applauncher } from '../modules/applauncher.js';
-import { PopupLayout } from './widgets/popuplayout.js';
-import { Desktop as DesktopWidget } from './widgets/desktop.js';
-import * as dashboard from './widgets/dashboard.js';
-import * as quicksettings from './widgets/quicksettings.js';
-import * as powermenu from './widgets/powermenu.js';
-import * as notifications from '../modules/notifications.js';
-
-// bar
-export const Launcher = ({ child }) => Button({
- className: 'launcher panel-button',
- connections: [[ags.App, (btn, win, visible) => {
- btn.toggleClassName('active', win === 'applauncher' && visible);
- }]],
- onClicked: () => ags.App.toggleWindow('applauncher'),
- child: Box({ children: [child] }),
-});
-
-export const Bar = ({ vertical, start, center, end, anchor, monitor }) => Window({
- name: `bar${monitor}`,
- exclusive: true,
- monitor,
- anchor,
- child: CenterBox({
- className: 'panel',
- vertical,
- startWidget: Box({ children: start, vertical, className: 'start' }),
- centerWidget: Box({ children: center, vertical, className: 'center' }),
- endWidget: Box({ children: end, vertical, className: 'end', valign: 'end' }),
- }),
-});
-
-// static
-export const Notifications = (monitor, transition, anchor) => Window({
- monitor,
- name: `notifications${monitor}`,
- anchor,
- child: notifications.PopupList({ transition }),
-});
-
-
-export const Desktop = monitor => Window({
- monitor,
- name: `desktop${monitor}`,
- className: 'desktop',
- anchor: ['top', 'bottom', 'left', 'right'],
- child: DesktopWidget(),
- layer: 'background',
-});
-
-export const Corners = (
- monitor,
- places = ['topleft', 'topright', 'bottomleft', 'bottomright'],
-) => places.map(place => Window({
- name: `corner${monitor}${place}`,
- monitor,
- className: 'corner',
- anchor: [place.includes('top') ? 'top' : 'bottom', place.includes('right') ? 'right' : 'left'],
- child: Corner(place),
-}));
-
-export const OSDIndicator = monitor => Window({
- name: `indicator${monitor}`,
- monitor,
- className: 'indicator',
- layer: 'overlay',
- anchor: ['right'],
- child: OnScreenIndicator(),
-});
-
-//popups
-const Popup = (name, child) => Window({
- name,
- popup: true,
- focusable: false,
- layer: 'overlay',
- child: PopupLayout({
- layout: 'center',
- window: name,
- child: child(),
- }),
-});
-
-export const ApplauncherPopup = () => Popup('applauncher', Applauncher);
-export const PowermenuPopup = () => Popup('powermenu', powermenu.PopupContent);
-export const VerificationPopup = () => Popup('verification', powermenu.Verification);
-
-export const Dashboard = ({ position }) => Window({
- name: 'dashboard',
- popup: true,
- focusable: false,
- anchor: position,
- child: PopupLayout({
- layout: position,
- window: 'dashboard',
- child: dashboard.PopupContent(),
- }),
-});
-
-export const Quicksettings = ({ position }) => Window({
- name: 'quicksettings',
- popup: true,
- focusable: false,
- anchor: position,
- child: PopupLayout({
- layout: position,
- window: 'quicksettings',
- child: quicksettings.PopupContent(),
- }),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/topbar.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/topbar.js
deleted file mode 100644
index 386b8f0bb..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/topbar.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import * as shared from './shared.js';
-import { Launcher } from './shared.js';
-import { Workspaces } from './widgets/hyprland.js';
-import { Separator } from '../modules/misc.js';
-import { PanelIndicator as MediaIndicator } from './widgets/media.js';
-import { PanelIndicator as NotificationIndicator } from './widgets/notifications.js';
-import { DistroIcon } from '../modules/misc.js';
-import { PanelButton as ColorPicker } from '../modules/colorpicker.js';
-import { PanelButton as PowerMenu } from './widgets/powermenu.js';
-import { PanelButton as DashBoard } from './widgets/dashboard.js';
-import { PanelButton as QuickSettings } from './widgets/quicksettings.js';
-
-const Bar = monitor => shared.Bar({
- anchor: 'top left right',
- monitor,
- start: [
- Launcher({ child: DistroIcon() }),
- Workspaces(),
- MediaIndicator({ hexpand: true, halign: 'end' }),
- ],
- center: [
- DashBoard(),
- ],
- end: [
- NotificationIndicator({ direction: 'right', hexpand: true, halign: 'start' }),
- ags.Widget.Box({ hexpand: true }),
- ColorPicker(),
- Separator({ valign: 'center' }),
- QuickSettings(),
- Separator({ valign: 'center' }),
- PowerMenu(),
- ],
-});
-
-export default monitors => ([
- ...monitors.map(monitor => [
- Bar(monitor),
- shared.Notifications(monitor, 'slide_down', 'top'),
- shared.Desktop(monitor),
- ...shared.Corners(monitor),
- shared.OSDIndicator(monitor),
- ]),
- shared.Quicksettings({ position: 'top right' }),
- shared.Dashboard({ position: 'top' }),
-]).flat(2);
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/dashboard.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/dashboard.js
deleted file mode 100644
index c972f7668..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/dashboard.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Clock } from '../../modules/clock.js';
-import { Separator } from '../../modules/misc.js';
-import { Wallpaper } from '../../modules/wallpaper.js';
-import * as datemenu from './datemenu.js';
-import * as notifications from './notifications.js';
-const { App } = ags;
-const { Button, Box } = ags.Widget;
-
-
-export const PanelButton = ({ format } = {}) => Button({
- className: 'dashboard panel-button',
- onClicked: () => App.toggleWindow('dashboard'),
- connections: [[App, (btn, win, visible) => {
- btn.toggleClassName('active', win === 'dashboard' && visible);
- }]],
- child: Clock({
- format,
- justification: 'center',
- }),
-});
-
-export const PopupContent = () => Box({
- className: 'dashboard',
- vexpand: false,
- children: [
- Box({
- vertical: true,
- children: [datemenu.PopupContent()],
- }),
- Separator({ vexpand: true }),
- Box({
- className: 'notifications',
- vertical: true,
- children: [
- notifications.Header(),
- Box({
- className: 'notification-list-box',
- children: [
- Wallpaper({
- children: [notifications.List()],
- }),
- ],
- }),
- ],
- }),
- ],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/datemenu.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/datemenu.js
deleted file mode 100644
index 754df6987..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/datemenu.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Clock, Uptime } from '../../modules/clock.js';
-const { Box, Label } = ags.Widget;
-
-export const PopupContent = props => Box({
- ...props,
- vertical: true,
- className: 'datemenu',
- children: [
- Clock({ format: '%I:%M' }),
- Box({
- className: 'uptime-box',
- halign: 'center',
- children: [
- Label('uptime'),
- Uptime(),
- ],
- }),
- Box({
- className: 'calendar',
- children: [
- ags.Widget({
- type: imports.gi.Gtk.Calendar,
- }),
- ],
- }),
- ],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/desktop.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/desktop.js
deleted file mode 100644
index dd123e1f9..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/desktop.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Separator } from '../../modules/misc.js';
-const { Theme, System } = ags.Service;
-const { MenuItem, Menu, Box, Label, Icon, EventBox, CenterBox } = ags.Widget;
-
-export const Desktop = props => EventBox({
- ...props,
- onSecondaryClick: (_, event) => Menu({
- className: 'desktop',
- children: [
- MenuItem({
- child: Box({
- children: [
- Icon('system-shutdown-symbolic'),
- Label({
- label: 'System',
- hexpand: true,
- xalign: 0,
- }),
- ],
- }),
- submenu: Menu({
- children: [
- Item('Shutdown', 'system-shutdown-symbolic', () => System.action('Shutdown')),
- Item('Log Out', 'system-log-out-symbolic', () => System.action('Log Out')),
- Item('Reboot', 'system-reboot-symbolic', () => System.action('Log Out')),
- Item('Sleep', 'weather-clear-night-symbolic', () => System.action('Log Out')),
- ],
- }),
- }),
- MenuItem({ className: 'separator' }),
- Item('Settings', 'org.gnome.Settings-symbolic', Theme.openSettings),
- ],
- }).popup_at_pointer(event),
- onMiddleClick: print,
- child: Box({
- vertical: true,
- vexpand: true,
- hexpand: true,
- connections: [[Theme, box => {
- const [halign = 'center', valign = 'center', offset = 64] =
- Theme.getSetting('desktop_clock')?.split(' ') || [];
-
- box.halign = imports.gi.Gtk.Align[halign.toUpperCase()];
- box.valign = imports.gi.Gtk.Align[valign.toUpperCase()];
- box.setStyle(`margin: ${Number(offset)}px;`);
- }]],
- }),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/hyprland.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/hyprland.js
deleted file mode 100644
index cb34418e9..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/hyprland.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import * as hyprland from '../../modules/hyprland.js';
-const { Box, EventBox, Button } = ags.Widget;
-const { execAsync } = ags.Utils;
-
-export const Workspaces = ({ props, vertical }) => Box({
- ...props,
- className: 'workspaces panel-button',
- children: [Box({
- children: [EventBox({
- className: 'eventbox',
- child: hyprland.Workspaces({
- vertical,
- indicator: () => Box({
- className: 'indicator',
- valign: 'center',
- children: [Box({ className: 'fill' })],
- }),
- }),
- })],
- })],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/media.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/media.js
deleted file mode 100644
index 964aafcc9..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/media.js
+++ /dev/null
@@ -1,149 +0,0 @@
-import { HoverRevealer } from '../../modules/misc.js';
-import * as mpris from '../../modules/mpris.js';
-const { Box, CenterBox, Label } = ags.Widget;
-const { Mpris } = ags.Service;
-const { timeout } = ags.Utils;
-
-export const MediaBox = ({ player = mpris.prefer, ...props }) => mpris.MprisBox({
- ...props,
- className: 'mediabox',
- player,
- children: [
- mpris.BlurredCoverArt({
- player,
- className: 'cover-art-bg',
- hexpand: true,
- children: [Box({
- className: 'shader',
- hexpand: true,
- vertical: true,
- children: [
- Box({
- children: [
- mpris.CoverArt({
- player,
- className: 'cover-art',
- halign: 'end',
- hexpand: false,
- }),
- Box({
- hexpand: true,
- vertical: true,
- className: 'labels',
- children: [
- mpris.TitleLabel({
- player,
- className: 'title',
- xalign: 0,
- justification: 'left',
- wrap: true,
- }),
- mpris.ArtistLabel({
- player,
- className: 'artist',
- xalign: 0,
- justification: 'left',
- wrap: true,
- }),
- ],
- }),
- ],
- }),
- mpris.PositionSlider({
- className: 'position-slider',
- player,
- }),
- CenterBox({
- className: 'footer-box',
- children: [
- Box({
- children: [
- mpris.PositionLabel({ player }),
- mpris.Slash({ player }),
- mpris.LengthLabel({ player }),
- ],
- }),
- Box({
- className: 'controls',
- children: [
- mpris.ShuffleButton({ player }),
- mpris.PreviousButton({ player }),
- mpris.PlayPauseButton({ player }),
- mpris.NextButton({ player }),
- mpris.LoopButton({ player }),
- ],
- }),
- mpris.PlayerIcon({
- player,
- hexpand: true,
- halign: 'end',
- }),
- ],
- }),
- ],
- })],
- }),
- ],
-});
-
-export const PopupContent = props => Box({
- vertical: true,
- className: 'media',
- ...props,
- properties: [['players', new Map()]],
- connections: [
- [Mpris, (box, busName) => {
- if (!busName || box._players.has(busName))
- return;
-
- const widget = MediaBox({ player: busName });
- box._players.set(busName, widget);
- box.add(widget);
- widget.show();
- }, 'player-added'],
- ],
-});
-
-export const PanelIndicator = ({
- player = mpris.prefer,
- direction = 'left',
- onPrimaryClick = () => Mpris.getPlayer(player)?.playPause(),
- ...props
-} = {}) => mpris.MprisBox({
- ...props,
- className: 'media panel-button',
- player,
- children: [HoverRevealer({
- direction,
- onPrimaryClick,
- onScrollUp: () => Mpris.getPlayer(player)?.next(),
- onScrollDown: () => Mpris.getPlayer(player)?.previous(),
- onSecondaryClick: () => Mpris.getPlayer(player)?.playPause(),
- indicator: mpris.PlayerIcon({
- player,
- className: 'icon',
- symbolic: true,
- }),
- child: Box({
- children: [
- mpris.ArtistLabel({ player }),
- Label(' - '),
- mpris.TitleLabel({ player }),
- ],
- }),
- connections: [[Mpris, revealer => {
- const mpris = Mpris.getPlayer(player);
- if (!mpris)
- return;
-
- if (revealer._current === mpris.trackTitle)
- return;
-
- revealer._current = mpris.trackTitle;
- revealer.reveal_child = true;
- timeout(3000, () => {
- revealer.reveal_child = false;
- });
- }]],
- })],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/notifications.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/notifications.js
deleted file mode 100644
index cbba68dce..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/notifications.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import { HoverRevealer } from '../../modules/misc.js';
-import * as notifications from '../../modules/notifications.js';
-const { Notifications } = ags.Service;
-const { timeout } = ags.Utils;
-const { Box, Scrollable, Label } = ags.Widget;
-
-export const Header = props => Box({
- ...props,
- className: 'header',
- children: [
- Label({ label: 'Notifications', hexpand: true, xalign: 0 }),
- notifications.ClearButton(),
- ],
-});
-
-export const List = props => Scrollable({
- ...props,
- hscroll: 'never',
- vscroll: 'automatic',
- child: Box({
- vertical: true,
- children: [
- notifications.NotificationList(),
- notifications.Placeholder(),
- ],
- }),
-});
-
-export const PanelIndicator = ({ direction = 'left', ...props } = {}) => Box({
- ...props,
- className: 'notifications panel-button',
- connections: [[Notifications, box => {
- box.visible =
- Notifications.notifications.size > 0 &&
- !Notifications.dnd;
- }]],
- children: [HoverRevealer({
- connections: [[Notifications, revealer => {
- const title = Array.from(Notifications.notifications)?.pop()?.[1].summary;
- if (revealer._title === title)
- return;
-
- revealer._title = title;
- revealer.reveal_child = true;
- timeout(3000, () => {
- revealer.reveal_child = false;
- });
- }]],
- direction,
- indicator: notifications.DNDIndicator(),
- child: Label({
- connections: [[Notifications, label => {
- label.label = Array.from(Notifications.notifications)?.pop()?.[1].summary || '';
- }]],
- }),
- })],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/popuplayout.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/popuplayout.js
deleted file mode 100644
index 10adc70f3..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/popuplayout.js
+++ /dev/null
@@ -1,121 +0,0 @@
-const { EventBox, CenterBox, Box, Revealer } = ags.Widget;
-const { App } = ags;
-
-const Padding = windowName => EventBox({
- className: 'padding',
- hexpand: true,
- vexpand: true,
- connections: [['button-press-event', () => App.toggleWindow(windowName)]],
-});
-
-const PopupRevealer = (windowName, transition, child) => Box({
- style: 'padding: 1px;',
- children: [Revealer({
- transition,
- child,
- transitionDuration: 350,
- connections: [[App, (revealer, name, visible) => {
- if (name === windowName)
- revealer.reveal_child = visible;
- }]],
- })],
-});
-
-const layouts = {
- 'center': (windowName, child) => CenterBox({
- className: 'shader',
- children: [
- Padding(windowName),
- CenterBox({
- vertical: true,
- children: [
- Padding(windowName),
- child,
- Padding(windowName),
- ],
- }),
- Padding(windowName),
- ],
- }),
- 'left': (windowName, child) => Box({
- children: [
- Padding(windowName),
- Box({
- hexpand: false,
- vertical: true,
- children: [
- Padding(windowName),
- PopupRevealer(windowName, 'slide_right', child),
- ],
- }),
- ],
- }),
- 'top': (windowName, child) => CenterBox({
- children: [
- Padding(windowName),
- Box({
- vertical: true,
- children: [
- PopupRevealer(windowName, 'slide_down', child),
- Padding(windowName),
- ],
- }),
- Padding(windowName),
- ],
- }),
- 'top right': (windowName, child) => Box({
- children: [
- Padding(windowName),
- Box({
- hexpand: false,
- vertical: true,
- children: [
- PopupRevealer(windowName, 'slide_down', child),
- Padding(windowName),
- ],
- }),
- ],
- }),
- 'bottom right': (windowName, child) => Box({
- children: [
- Padding(windowName),
- Box({
- hexpand: false,
- vertical: true,
- children: [
- Padding(windowName),
- PopupRevealer(windowName, 'slide_up', child),
- ],
- }),
- ],
- }),
- 'top left': (windowName, child) => Box({
- children: [
- Padding(windowName),
- Box({
- hexpand: false,
- vertical: true,
- children: [
- Padding(windowName),
- PopupRevealer(windowName, 'slide_right', child),
- ],
- }),
- ],
- }),
- 'bottom left': (windowName, child) => Box({
- children: [
- Padding(windowName),
- Box({
- hexpand: false,
- vertical: true,
- children: [
- Padding(windowName),
- PopupRevealer(windowName, 'slide_right', child),
- ],
- }),
- ],
- }),
-
-};
-
-export const PopupLayout = ({ layout, window, child }) => layouts[layout](window, child);
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/powermenu.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/powermenu.js
deleted file mode 100644
index cf6ead80f..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/powermenu.js
+++ /dev/null
@@ -1,94 +0,0 @@
-const { App, Service } = ags;
-const { exec, error } = ags.Utils;
-const { Icon, Label, Box, Button } = ags.Widget;
-
-class System extends Service {
- static {
- Service.register(this);
- Service.export(this, 'System');
- }
-
- static instance = new System();
-
- static action(action) {
- const cmd = {
- 'Sleep': 'systemctl suspend',
- 'Reboot': 'systemctl reboot',
- 'Log Out': 'pkill Hyprland',
- 'Shutdown': 'shutdown now',
- }[action];
-
- if (!cmd)
- error(`There is no ${action} system action`);
-
- App.getWindow('powermenu').hide();
- App.getWindow('verification').show();
- System.instance._action = { cmd, action };
- System.instance.emit('changed');
- }
-}
-
-const SysButton = (icon, action) => Button({
- onClicked: () => System.action(action),
- child: Box({
- vertical: true,
- children: [
- Icon({ icon, size: 42 }),
- Label(action),
- ],
- }),
-});
-
-export const PopupContent = () => Box({
- homogeneous: true,
- className: 'powermenu',
- children: [
- SysButton('weather-clear-night-symbolic', 'Sleep'),
- SysButton('system-reboot-symbolic', 'Reboot'),
- SysButton('system-log-out-symbolic', 'Log Out'),
- SysButton('system-shutdown-symbolic', 'Shutdown'),
- ],
-});
-
-export const Verification = () => Box({
- className: 'verification',
- vertical: true,
- children: [
- Label({
- className: 'title',
- connections: [[System, label => {
- label.label = System.instance._action?.action || '';
- }]],
- }),
- Label({
- className: 'desc',
- label: 'Are you sure?',
- }),
- Box({
- className: 'buttons',
- vexpand: true,
- valign: 'end',
- homogeneous: true,
- children: [
- Button({
- child: Label('No'),
- onClicked: () => App.toggleWindow('verification'),
- }),
- Button({
- child: Label('Yes'),
- onClicked: () => exec(System.instance._action.cmd),
- }),
- ],
- }),
- ],
-});
-
-export const PanelButton = () => Button({
- className: 'powermenu panel-button',
- onClicked: () => App.toggleWindow('powermenu'),
- connections: [[ags.App, (btn, win, visible) => {
- if (win === 'powermenu' || win === 'verification')
- btn.toggleClassName('active', visible);
- }]],
- child: Icon('system-shutdown-symbolic'),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/quicksettings.js b/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/quicksettings.js
deleted file mode 100644
index 863761d4e..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/layouts/widgets/quicksettings.js
+++ /dev/null
@@ -1,405 +0,0 @@
-import { Uptime } from '../../modules/clock.js';
-import { FontIcon, HoverRevealer, Separator } from '../../modules/misc.js';
-import * as battery from '../../modules/battery.js';
-import * as audio from '../../modules/audio.js';
-import * as brightness from '../../modules/brightness.js';
-import * as network from '../../modules/network.js';
-import * as bluetooth from '../../modules/bluetooth.js';
-import * as notifications from '../../modules/notifications.js';
-import * as theme from '../../theme/theme.js';
-import * as media from './media.js';
-const { Button, Box, Icon, Label, Revealer } = ags.Widget;
-const { Service, App } = ags;
-const { Bluetooth, Battery, Audio, Network, Theme } = Service;
-const { execAsync, timeout, USER } = ags.Utils;
-
-class QSMenu extends Service {
- static { Service.register(this); }
- static instance = new QSMenu();
- static opened = '';
- static toggle(menu) {
- QSMenu.opened = QSMenu.opened === menu ? '' : menu;
- QSMenu.instance.emit('changed');
- }
-
- constructor() {
- super();
- App.instance.connect('window-toggled', (_a, name, visible) => {
- if (name === 'quicksettings' && !visible) {
- QSMenu.opened = '';
- QSMenu.instance.emit('changed');
- }
- });
- }
-}
-
-const Arrow = (menu, toggleOn) => Button({
- className: 'arrow',
- onClicked: () => {
- QSMenu.toggle(menu);
- if (toggleOn)
- toggleOn();
- },
- connections: [[QSMenu, button => {
- button.toggleClassName('opened', QSMenu.opened === menu);
- }]],
- child: Icon({
- icon: 'pan-end-symbolic',
- properties: [
- ['deg', 0],
- ['opened', false],
- ],
- connections: [[QSMenu, icon => {
- if (QSMenu.opened === menu && !icon._opened || QSMenu.opened !== menu && icon._opened) {
- const step = QSMenu.opened === menu ? 10 : -10;
- icon._opened = !icon._opened;
- for (let i = 0; i < 9; ++i) {
- timeout(5 * i, () => {
- icon._deg += step;
- icon.setStyle(`-gtk-icon-transform: rotate(${icon._deg}deg);`);
- });
- }
- }
- }]],
- }),
-});
-
-const RevealerMenu = (name, child) => Box({
- children: [Revealer({
- transition: 'slide_down',
- connections: [[QSMenu, r => r.reveal_child = name === QSMenu.opened]],
- child,
- })],
-});
-
-const Avatar = () => Box({
- className: 'avatar',
- connections: [[Theme, box => {
- box.setStyle(`
- background-image: url('${Theme.getSetting('avatar')}');
- background-size: cover;
- `);
- }]],
- children: [Box({
- className: 'shader',
- hexpand: true,
- children: [Label({
- className: 'user',
- halign: 'start',
- valign: 'end',
- label: '@' + USER,
- })],
- })],
-});
-
-const SysButton = (icon, action, className = '') => Button({
- className,
- onClicked: () => Service.System.action(action),
- tooltipText: action,
- child: Icon(icon),
-});
-
-const SystemBox = () => Box({
- vertical: true,
- halign: 'end',
- valign: 'center',
- children: [
- Box({
- valign: 'center',
- className: 'system',
- children: [
- Button({
- className: 'settings',
- onClicked: () => { App.toggleWindow('quicksettings'); Theme.openSettings(); },
- tooltipText: 'Settings',
- child: Icon('org.gnome.Settings-symbolic'),
- }),
- Box({
- className: 'uptime',
- children: [
- Label('uptime: '),
- Uptime(),
- ],
- }),
- SysButton('system-log-out-symbolic', 'Log Out'),
- SysButton('system-shutdown-symbolic', 'Shutdown', 'shutdown'),
- ],
- }),
- battery.BatteryProgress(),
- ],
-});
-
-const VolumeBox = () => Box({
- vertical: true,
- className: 'volume-box',
- children: [
- Box({
- className: 'volume',
- children: [
- Button({
- child: audio.SpeakerTypeIndicator(),
- onClicked: 'pactl set-sink-mute @DEFAULT_SINK@ toggle',
- }),
- audio.SpeakerSlider({ hexpand: true }),
- audio.SpeakerPercentLabel(),
- Arrow('stream-selector'),
- ],
- }),
- RevealerMenu('stream-selector', Box({
- vertical: true,
- className: 'menu',
- children: [
- audio.StreamSelector(),
- Separator(),
- Button({
- onClicked: () => {
- execAsync('pavucontrol').catch(print);
- App.closeWindow('quicksettings');
- },
- child: Label({
- label: 'Settings',
- xalign: 0,
- }),
- }),
- ],
- })),
- ],
-});
-
-const BrightnessBox = () => Box({
- className: 'brightness',
- children: [
- Button({
- onClicked: () => {
- execAsync('wl-gammactl').catch(print);
- App.closeWindow('quicksettings');
- },
- child: brightness.Indicator(),
- }),
- brightness.BrightnessSlider(),
- brightness.PercentLabel(),
- ],
-});
-
-const ArrowToggle = ({ icon, label, connection, toggle, name, toggleOn }) => Box({
- connections: [[
- connection.service,
- w => w.toggleClassName('active', connection.callback()),
- ]],
- className: `arrow toggle ${name}`,
- children: [
- Button({
- hexpand: true,
- className: 'toggle',
- onClicked: toggle,
- child: Box({
- children: [
- icon,
- label,
- ],
- }),
- }),
- Arrow(name, toggleOn),
- ],
-});
-
-const NetworkToggle = () => ArrowToggle({
- icon: network.WifiIndicator(),
- label: network.SSIDLabel(),
- connection: {
- service: Network,
- callback: () => Network.wifi?.enabled,
- },
- toggle: Network.toggleWifi,
- toggleOn: () => {
- Network.wifi.enabled = true;
- Network.wifi.scan();
- },
- name: 'network',
-});
-
-const BluetoothToggle = () => ArrowToggle({
- icon: bluetooth.Indicator(),
- label: bluetooth.ConnectedLabel(),
- connection: {
- service: Bluetooth,
- callback: () => Bluetooth.enabled,
- },
- toggle: () => Bluetooth.enabled = !Bluetooth.enabled,
- toggleOn: () => {
- Bluetooth.enabled = QSMenu.opened === 'bluetooth'
- ? true : Bluetooth.enabled;
- },
- name: 'bluetooth',
-});
-
-const SmallToggle = (toggle, indicator) => toggle({
- className: 'toggle',
- halign: 'fill',
- hexpand: true,
- vexpand: true,
- child: indicator({ halign: 'center' }),
-});
-
-const DNDToggle = () => SmallToggle(
- notifications.DNDToggle,
- notifications.DNDIndicator,
-);
-
-const MuteToggle = () => SmallToggle(
- audio.MicrophoneMuteToggle,
- audio.MicrophoneMuteIndicator,
-);
-
-const AsusctlToggle = () => SmallToggle(
- asusctl.ProfileToggle,
- asusctl.ProfileIndicator,
-);
-
-const AsusmodeToggle = () => SmallToggle(
- asusctl.ModeToggle,
- asusctl.ModeIndicator,
-);
-
-const ThemeToggle = () => Button({
- className: 'toggle',
- onClicked: () => QSMenu.toggle('theme'),
- child: theme.Indicator(),
- connections: [[QSMenu, w => w.toggleClassName('on', QSMenu.opened === 'theme')]],
-});
-
-const AppmixerToggle = () => Button({
- className: 'toggle',
- onClicked: () => QSMenu.toggle('app-mixer'),
- child: FontIcon({ icon: '' }),
- tooltipText: 'App Mixer',
- connections: [[QSMenu, w => w.toggleClassName('on', QSMenu.opened === 'app-mixer')]],
-});
-
-const Submenu = ({ menuName, icon, title, contentType }) => RevealerMenu(menuName, Box({
- vertical: true,
- className: `submenu ${menuName}`,
- children: [
- Box({ className: 'title', children: [icon, Label(title)] }),
- contentType({ className: 'content', hexpand: true }),
- ],
-}));
-
-const Appmixer = () => Submenu({
- menuName: 'app-mixer',
- icon: FontIcon({ icon: '' }),
- title: 'App Mixer',
- contentType: audio.AppMixer,
-});
-
-const NetworkSelection = () => Submenu({
- menuName: 'network',
- icon: Icon('network-wireless-symbolic'),
- title: 'Wireless Networks',
- contentType: network.WifiSelection,
-});
-
-const BluetoothSelection = () => Submenu({
- menuName: 'bluetooth',
- icon: Icon('bluetooth-symbolic'),
- title: 'Bluetooth',
- contentType: bluetooth.Devices,
-});
-
-const ThemeSelection = () => Submenu({
- menuName: 'theme',
- icon: Icon('preferences-desktop-theme-symbolic'),
- title: 'Theme',
- contentType: theme.Selector,
-});
-
-export const PopupContent = () => Box({
- className: 'quicksettings',
- vertical: true,
- hexpand: false,
- children: [
- Box({
- className: 'header',
- children: [
- Avatar(),
- SystemBox(),
- ],
- }),
- VolumeBox(),
- BrightnessBox(),
- Box({
- className: 'toggles-box',
- children: [
- Box({
- vertical: true,
- className: 'arrow-toggles',
- children: [NetworkToggle(), BluetoothToggle()],
- }),
- Box({
- vertical: true,
- className: 'small-toggles',
- vexpand: true,
- hexpand: false,
- children: [
- Box({ children: [DNDToggle(), MuteToggle()] }),
- Box({ children: [AppmixerToggle(), ThemeToggle()] }),
- ],
- }),
- ],
- }),
- Appmixer(),
- NetworkSelection(),
- BluetoothSelection(),
- ThemeSelection(),
- media.PopupContent(),
- ],
-});
-
-const BluetoothIndicator = () => Box({
- connections: [[Bluetooth, box => {
- box.children = Array.from(Bluetooth.connectedDevices.values())
- .map(({ iconName, name }) => HoverRevealer({
- indicator: Icon(iconName + '-symbolic'),
- child: Label(name),
- }));
-
- box.visible = Bluetooth.connectedDevices.size > 0;
- }]],
-});
-
-const BatteryIndicator = () => HoverRevealer({
- direction: 'right',
- indicator: battery.Indicator(),
- child: battery.LevelLabel(),
- connections: [[Battery, revealer => {
- revealer.reveal_child = Battery.percent < 100;
- }]],
-});
-
-export const PanelButton = ({ vertical }) => Button({
- className: 'quicksettings panel-button',
- onClicked: () => App.toggleWindow('quicksettings'),
- onScrollUp: () => {
- Audio.speaker.volume += 0.02;
- Service.Indicator.speaker();
- },
- onScrollDown: () => {
- Audio.speaker.volume -= 0.02;
- Service.Indicator.speaker();
- },
- connections: [[App, (btn, win, visible) => {
- btn.toggleClassName('active', win === 'quicksettings' && visible);
- }]],
- child: Box({
- vertical,
- children: [
- audio.MicrophoneMuteIndicator({ unmuted: null }),
- notifications.DNDIndicator({ noisy: null }),
- BluetoothIndicator(),
- bluetooth.Indicator({ disabled: null }),
- network.Indicator(),
- audio.SpeakerIndicator(),
- BatteryIndicator(),
- ],
- }),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/applauncher.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/applauncher.js
deleted file mode 100644
index 3f9ade80f..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/applauncher.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const { App } = ags;
-const { Applications } = ags.Service;
-const { Label, Box, Icon, Button, Scrollable, Entry } = ags.Widget;
-import { Wallpaper } from './wallpaper.js';
-import { Separator } from './misc.js';
-
-const AppItem = (app, window) => Button({
- className: 'app',
- connections: [['clicked', () => {
- App.closeWindow(window);
- app.launch();
- }]],
- child: Box({
- children: [
- Icon({
- icon: app.iconName,
- size: 42,
- }),
- Box({
- vertical: true,
- children: [
- Label({
- className: 'title',
- label: app.name,
- xalign: 0,
- valign: 'center',
- ellipsize: 3,
- }),
- Label({
- className: 'description',
- label: app.description || '',
- wrap: true,
- xalign: 0,
- justification: 'left',
- valign: 'center',
- }),
- ],
- }),
- ],
- }),
-});
-
-export const Applauncher = ({ windowName = 'applauncher' } = {}) => {
- const list = Box({ vertical: true });
- const entry = Entry({
- hexpand: true,
- placeholderText: 'Search',
- onAccept: ({ text }) => {
- const list = Applications.query(text);
- if (list[0]) {
- App.toggleWindow(windowName);
- list[0].launch();
- }
- },
- onChange: ({ text }) => {
- list.children = Applications.query(text).map(app => [
- Separator(),
- AppItem(app, windowName),
- ]).flat();
- list.add(Separator());
- list.show_all();
- },
- });
-
- return Box({
- className: 'applauncher',
- properties: [['list', list]],
- vertical: true,
- children: [
- Wallpaper({
- children: [
- Icon('folder-saved-search-symbolic'),
- entry,
- ],
-
- }),
- Scrollable({
- hscroll: 'never',
- child: list,
- }),
- ],
- connections: [[App, (_b, name, visible) => {
- if (name !== windowName)
- return;
-
- entry.set_text('-'); // force onChange
- entry.set_text('');
- if (visible)
- entry.grab_focus();
- }]],
- });
-};
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/audio.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/audio.js
deleted file mode 100644
index 459fe1289..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/audio.js
+++ /dev/null
@@ -1,185 +0,0 @@
-const { Audio } = ags.Service;
-const { Label, Box, Icon, Stack, Button, Slider } = ags.Widget;
-
-const iconSubstitute = item => {
- const substitues = [
- { from: 'audio-headset-bluetooth', to: 'audio-headphones-symbolic' },
- { from: 'audio-card-analog-usb', to: 'audio-speakers-symbolic' },
- { from: 'audio-card-analog-pci', to: 'audio-card-symbolic' },
- ];
-
- for (const { from, to } of substitues) {
- if (from === item)
- return to;
- }
- return item;
-};
-
-export const SpeakerIndicator = ({
- items = [
- ['101', Icon('audio-volume-overamplified-symbolic')],
- ['67', Icon('audio-volume-high-symbolic')],
- ['34', Icon('audio-volume-medium-symbolic')],
- ['1', Icon('audio-volume-low-symbolic')],
- ['0', Icon('audio-volume-muted-symbolic')],
- ],
- ...props
-} = {}) => Stack({
- ...props,
- items,
- connections: [[Audio, stack => {
- if (!Audio.speaker)
- return;
-
- if (Audio.speaker.isMuted)
- return stack.shown = '0';
-
- const vol = Audio.speaker.volume * 100;
- for (const threshold of [100, 66, 33, 0, -1]) {
- if (vol > threshold + 1)
- return stack.shown = `${threshold + 1}`;
- }
- }, 'speaker-changed']],
-});
-
-export const SpeakerTypeIndicator = props => Icon({
- ...props,
- connections: [[Audio, icon => {
- if (Audio.speaker)
- icon.icon = iconSubstitute(Audio.speaker.iconName);
- }]],
-});
-
-export const SpeakerPercentLabel = props => Label({
- ...props,
- connections: [[Audio, label => {
- if (!Audio.speaker)
- return;
-
- label.label = `${Math.floor(Audio.speaker.volume * 100)}%`;
- }, 'speaker-changed']],
-});
-
-export const SpeakerSlider = props => Slider({
- ...props,
- drawValue: false,
- onChange: ({ value }) => Audio.speaker.volume = value,
- connections: [[Audio, slider => {
- if (!Audio.speaker)
- return;
-
- slider.sensitive = !Audio.speaker.isMuted;
- slider.value = Audio.speaker.volume;
- }, 'speaker-changed']],
-});
-
-export const MicrophoneMuteIndicator = ({
- muted = Icon('microphone-disabled-symbolic'),
- unmuted = Icon('microphone-sensitivity-high-symbolic'),
- ...props
-} = {}) => Stack({
- ...props,
- items: [
- ['true', muted],
- ['false', unmuted],
- ],
- connections: [[Audio, stack => {
- stack.shown = `${Audio.microphone?.isMuted}`;
- }, 'microphone-changed']],
-});
-
-export const MicrophoneMuteToggle = props => Button({
- ...props,
- onClicked: 'pamixer --default-source -t',
- connections: [[Audio, button => {
- if (!Audio.microphone)
- return;
-
- button.toggleClassName('on', Audio.microphone.isMuted);
- }, 'microphone-changed']],
-});
-
-export const AppMixer = props => {
- const AppItem = stream => {
- const icon = Icon();
- const label = Label({ xalign: 0, justify: 'left', wrap: true, ellipsize: 3 });
- const percent = Label({ xalign: 1 });
- const slider = Slider({
- hexpand: true,
- drawValue: false,
- onChange: ({ value }) => {
- stream.volume = value;
- },
- });
- const sync = () => {
- icon.icon = stream.iconName;
- icon.tooltipText = stream.name;
- slider.value = stream.volume;
- percent.label = `${Math.floor(stream.volume * 100)}%`;
- label.label = stream.description || '';
- };
- const id = stream.connect('changed', sync);
- return Box({
- hexpand: true,
- children: [
- icon,
- Box({
- children: [
- Box({
- vertical: true,
- children: [
- label,
- slider,
- ],
- }),
- percent,
- ],
- }),
- ],
- connections: [['destroy', () => stream.disconnect(id)]],
- setup: sync,
- });
- };
-
- return Box({
- ...props,
- vertical: true,
- connections: [[Audio, box => {
- box.children = Array.from(Audio.apps.values())
- .map(stream => AppItem(stream));
- }]],
- });
-};
-
-export const StreamSelector = ({ streams = 'speakers', ...props } = {}) => Box({
- ...props,
- vertical: true,
- connections: [[Audio, box => {
- box.children = Array.from(Audio[streams].values()).map(stream => Button({
- child: Box({
- children: [
- Icon({
- icon: iconSubstitute(stream.iconName),
- tooltipText: stream.iconName,
- }),
- Label(stream.description.split(' ').slice(0, 4).join(' ')),
- Icon({
- icon: 'object-select-symbolic',
- hexpand: true,
- halign: 'end',
- connections: [['draw', icon => {
- icon.visible = Audio.speaker === stream;
- }]],
- }),
- ],
- }),
- onClicked: () => {
- if (streams === 'speakers')
- Audio.speaker = stream;
-
- if (streams === 'microphones')
- Audio.microphone = stream;
- },
- }));
- }]],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/battery.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/battery.js
deleted file mode 100644
index 2ce1ccb20..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/battery.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const { Battery } = ags.Service;
-const { Label, Icon, Stack, ProgressBar, Overlay, Box } = ags.Widget;
-
-const icons = charging => ([
- ...Array.from({ length: 9 }, (_, i) => i * 10).map(i => ([
- `${i}`, Icon({
- className: `${i} ${charging ? 'charging' : 'discharging'}`,
- icon: `battery-level-${i}${charging ? '-charging' : ''}-symbolic`,
- }),
- ])),
- ['100', Icon({
- className: `100 ${charging ? 'charging' : 'discharging'}`,
- icon: `battery-level-100${charging ? '-charged' : ''}-symbolic`,
- })],
-]);
-
-const Indicators = charging => Stack({
- items: icons(charging),
- connections: [[Battery, stack => {
- stack.shown = `${Math.floor(Battery.percent / 10) * 10}`;
- }]],
-});
-
-export const Indicator = ({
- charging = Indicators(true),
- discharging = Indicators(false),
- ...props
-} = {}) => Stack({
- ...props,
- className: 'battery',
- items: [
- ['true', charging],
- ['false', discharging],
- ],
- connections: [[Battery, stack => {
- const { charging, charged } = Battery;
- stack.shown = `${charging || charged}`;
- stack.toggleClassName('charging', Battery.charging);
- stack.toggleClassName('charged', Battery.charged);
- stack.toggleClassName('low', Battery.percent < 30);
- }]],
-});
-
-export const LevelLabel = props => Label({
- ...props,
- connections: [[Battery, label => label.label = `${Battery.percent}%`]],
-});
-
-export const BatteryProgress = props => Box({
- ...props,
- className: 'battery-progress',
- connections: [[Battery, w => {
- w.toggleClassName('half', Battery.percent < 46);
- w.toggleClassName('charging', Battery.charging);
- w.toggleClassName('charged', Battery.charged);
- w.toggleClassName('low', Battery.percent < 30);
- }]],
- children: [Overlay({
- child: ProgressBar({
- hexpand: true,
- connections: [[Battery, progress => {
- progress.fraction = Battery.percent / 100;
- }]],
- }),
- overlays: [Label({
- connections: [[Battery, l => {
- l.label = Battery.charging || Battery.charged
- ? ''
- : `${Battery.percent}%`;
- }]],
- })],
- })],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/bluetooth.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/bluetooth.js
deleted file mode 100644
index d47dde269..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/bluetooth.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Spinner } from './misc.js';
-const { Bluetooth } = ags.Service;
-const { Icon, Label, Box, Button, Stack } = ags.Widget;
-
-export const Indicator = ({
- enabled = Icon({ icon: 'bluetooth-active-symbolic', className: 'enabled' }),
- disabled = Icon({ icon: 'bluetooth-disabled-symbolic', className: 'disabled' }),
- ...props
-} = {}) => Stack({
- ...props,
- items: [
- ['true', enabled],
- ['false', disabled],
- ],
- connections: [[Bluetooth, stack => {
- stack.shown = `${Bluetooth.enabled}`;
- }]],
-});
-
-export const Toggle = props => Button({
- ...props,
- onClicked: () => Bluetooth.enabled = !Bluetooth.enabled,
- connections: [[Bluetooth, button => button.toggleClassName('on', Bluetooth.enabled)]],
-});
-
-export const ConnectedLabel = props => Label({
- ...props,
- connections: [[Bluetooth, label => {
- if (!Bluetooth.enabled)
- return label.label = 'Disabled';
-
- if (Bluetooth.connectedDevices.size === 0)
- return label.label = 'Not Connected';
-
- if (Bluetooth.connectedDevices.size === 1)
- return label.label = Bluetooth.connectedDevices.entries().next().value[1].alias;
-
- label.label = `${Bluetooth.connectedDevices.size} Connected`;
- }]],
-});
-
-export const Devices = props => Box({
- ...props,
- vertical: true,
- connections: [[Bluetooth, box => {
- box.children = Array.from(Bluetooth.devices.values()).map(device => Box({
- hexpand: false,
- children: [
- Icon(device.iconName + '-symbolic'),
- Label(device.name),
- Box({ hexpand: true }),
- device._connecting ? Spinner() : ags.Widget({
- type: imports.gi.Gtk.Switch,
- active: device.connected,
- connections: [['activate', ({ active }) => {
- device.setConnection(active);
- }]],
- }),
- ],
- }));
- }]],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/brightness.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/brightness.js
deleted file mode 100644
index a024b2b73..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/brightness.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const { Service } = ags;
-const { exec, execAsync } = ags.Utils;
-const { Icon, Label, Slider } = ags.Widget;
-
-class BrightnessService extends Service {
- static { Service.register(this); }
-
- _screen = 0;
-
- get screen() { return this._screen; }
-
- set screen(percent) {
- if (percent < 0)
- percent = 0;
-
- if (percent > 1)
- percent = 1;
-
- execAsync(`brightnessctl s ${percent * 100}% -q`)
- .then(() => {
- this._screen = percent;
- this.emit('changed');
- })
- .catch(print);
- }
-
- constructor() {
- super();
- this._screen = Number(exec('brightnessctl g')) / Number(exec('brightnessctl m'));
- }
-}
-
-class Brightness {
- static { Service.export(this, 'Brightness'); }
- static instance = new BrightnessService();
-
- static get screen() { return Brightness.instance.screen; }
- static set screen(value) { Brightness.instance.screen = value; }
-}
-
-export const BrightnessSlider = props => Slider({
- ...props,
- drawValue: false,
- hexpand: true,
- connections: [
- [Brightness, slider => {
- slider.value = Brightness.screen;
- }],
- ],
- onChange: ({ value }) => Brightness.screen = value,
-});
-
-export const Indicator = props => Icon({
- ...props,
- icon: 'display-brightness-symbolic',
-});
-
-export const PercentLabel = props => Label({
- ...props,
- connections: [
- [Brightness, label => label.label = `${Math.floor(Brightness.screen * 100)}%`],
- ],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/clock.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/clock.js
deleted file mode 100644
index c03e1d2a1..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/clock.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const { Label } = ags.Widget;
-const { execAsync } = ags.Utils;
-const { DateTime } = imports.gi.GLib;
-
-export const Clock = ({
- format = '%I:%M:%S | %d/%m/%y',
- interval = 1000,
- ...props
-} = {}) => Label({
- className: 'clock',
- ...props,
- connections: [[interval, label =>
- label.label = DateTime.new_now_local().format(format),
- ]],
-});
-
-export const Uptime = ({
- interval = 100_000,
- ...props
-} = {}) => Label({
- ...props,
- connections: [[interval, label => {
- execAsync(['bash', '-c', "uptime | awk '{print $3}' | tr ',' ' '"])
- .then(time => label.label = time)
- .catch(print);
- }]],
-});
-
-
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/colorpicker.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/colorpicker.js
deleted file mode 100644
index 0f0f5ecbf..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/colorpicker.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const { Notifications } = ags.Service;
-const { execAsync } = ags.Utils;
-const { Gravity } = imports.gi.Gdk;
-const { Button, Icon, Menu, MenuItem, Label } = ags.Widget;
-
-const wlCopy = color => execAsync(['wl-copy', color]).catch(print);
-
-export const PanelButton = props => Button({
- ...props,
- className: 'panel-button colorpicker',
- child: Icon('color-select-symbolic'),
- properties: [['colors', []]],
- connections: [['clicked', btn => execAsync('hyprpicker').then(color => {
- wlCopy(color);
- if (!btn._colors.includes(color)) {
- btn._colors.push(color);
- if (btn._colors > 10)
- btn._colors.shift();
- }
-
- btn._id = Notifications.instance.Notify(
- 'Color Picker',
- btn._id || null,
- 'color-select-symbolic',
- color,
- '',
- [],
- {},
- );
- }).catch(print)]],
- onSecondaryClick: btn => btn._colors.length > 0 ? Menu({
- className: 'colorpicker',
- children: btn._colors.map(color => MenuItem({
- child: Label(color),
- style: `background-color: ${color}`,
- onActivate: () => wlCopy(color),
- })),
- }).popup_at_widget(btn, Gravity.WEST, Gravity.EAST, null) : false,
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/corner.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/corner.js
deleted file mode 100644
index 329a41b8a..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/corner.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const { Gtk } = imports.gi;
-
-export const Corner = place => ags.Widget({
- type: Gtk.DrawingArea,
- className: 'corner',
- hexpand: true,
- vexpand: true,
- halign: place.includes('left') ? 'start' : 'end',
- valign: place.includes('top') ? 'start' : 'end',
- setup: widget => { widget.set_size_request(0, 0); },
- connections: [['draw', (widget, cr) => {
- const context = widget.get_style_context();
- const c = context.get_property('background-color', Gtk.StateFlags.NORMAL);
- const r = context.get_property('border-radius', Gtk.StateFlags.NORMAL);
- widget.set_size_request(r, r);
-
- switch (place) {
- case 'topleft':
- cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
- cr.lineTo(0, 0);
- break;
-
- case 'topright':
- cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
- cr.lineTo(r, 0);
- break;
-
- case 'bottomleft':
- cr.arc(r, 0, r, Math.PI / 2, Math.PI);
- cr.lineTo(0, r);
- break;
-
- case 'bottomright':
- cr.arc(0, 0, r, 0, Math.PI / 2);
- cr.lineTo(r, r);
- break;
- }
-
- cr.closePath();
- cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
- cr.fill();
- }]],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/hyprland.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/hyprland.js
deleted file mode 100644
index e9a7614ef..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/hyprland.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const { App } = ags;
-const { Hyprland, Applications } = ags.Service;
-const { execAsync, lookUpIcon } = ags.Utils;
-const { Box, Button, Label, Icon } = ags.Widget;
-
-export const Workspaces = ({
- fixed = 7,
- vertical,
- indicator,
- ...props
-} = {}) => Box({
- ...props,
- vertical,
- children: Array.from({ length: fixed }, (_, i) => i + 1).map(i => Button({
- onClicked: () => execAsync(`hyprctl dispatch workspace ${i}`).catch(print),
- child: indicator ? indicator() : Label(`${i}`),
- connections: [[Hyprland, btn => {
- const { workspaces, active } = Hyprland;
- const occupied = workspaces.has(i) && workspaces.get(i).windows > 0;
- btn.toggleClassName('active', active.workspace.id === i);
- btn.toggleClassName('occupied', occupied);
- btn.toggleClassName('empty', !occupied);
- }]],
- })),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/misc.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/misc.js
deleted file mode 100644
index 410ea3085..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/misc.js
+++ /dev/null
@@ -1,152 +0,0 @@
-const { Box, Label, Overlay, Icon, Revealer, EventBox } = ags.Widget;
-const { timeout, exec } = ags.Utils;
-
-export const Separator = ({ className = '', ...props } = {}) => Box({
- hexpand: false,
- vexpand: false,
- ...props,
- className: [...className.split(' '), 'separator'].join(' '),
-});
-
-export const FontIcon = ({ icon = '', ...props }) => {
- const box = Box({
- style: 'min-width: 1px; min-height: 1px;',
- });
- const label = Label({
- label: icon,
- halign: 'center',
- valign: 'center',
- });
- return Box({
- ...props,
- setup: box => box.label = label,
- className: 'icon',
- children: [Overlay({
- child: box,
- overlays: [label],
- passThrough: true,
- connections: [['draw', overlay => {
- const size = overlay.get_style_context()
- .get_property('font-size', imports.gi.Gtk.StateFlags.NORMAL) || 11;
-
- box.setStyle(`min-width: ${size}px; min-height: ${size}px;`);
- }]],
- })],
- });
-};
-
-export const DistroIcon = props => FontIcon({
- ...props,
- className: 'distro-icon',
- icon: (() => {
- // eslint-disable-next-line quotes
- const distro = exec(`bash -c "cat /etc/os-release | grep '^ID' | head -n 1 | cut -d '=' -f2"`)
- .toLowerCase();
-
- switch (distro) {
- case 'fedora': return '';
- case 'arch': return '';
- case 'nixos': return '';
- case 'debian': return '';
- case 'opensuse-tumbleweed': return '';
- case 'ubuntu': return '';
- case 'endeavouros': return '';
- default: return '';
- }
- })(),
-});
-
-export const Spinner = ({ icon = 'process-working-symbolic' }) => Icon({
- icon,
- properties: [['deg', 0]],
- connections: [[10, w => {
- w.setStyle(`-gtk-icon-transform: rotate(${w._deg++ % 360}deg);`);
- }]],
-});
-
-export const Progress = ({ height = 18, width = 180, vertical = false, child, ...props }) => {
- const fill = Box({
- className: 'fill',
- hexpand: vertical,
- vexpand: !vertical,
- halign: vertical ? 'fill' : 'start',
- valign: vertical ? 'end' : 'fill',
- children: [child],
- });
- const progress = Box({
- ...props,
- className: 'progress',
- style: `
- min-width: ${width}px;
- min-height: ${height}px;
- `,
- children: [fill],
- });
- progress.setValue = value => {
- if (value < 0)
- return;
-
- const axis = vertical ? 'height' : 'width';
- const axisv = vertical ? height : width;
- const min = vertical ? width : height;
- const preferred = (axisv - min) * value + min;
-
- if (!fill._size) {
- fill._size = preferred;
- fill.setStyle(`min-${axis}: ${preferred}px;`);
- return;
- }
-
- const frames = 10;
- const goal = preferred - fill._size;
- const step = goal / frames;
-
- for (let i = 0; i < frames; ++i) {
- timeout(5 * i, () => {
- fill._size += step;
- fill.setStyle(`min-${axis}: ${fill._size}px`);
- });
- }
- };
- return progress;
-};
-
-export const HoverRevealer = ({
- indicator,
- child,
- direction = 'left',
- duration = 300,
- connections,
- ...rest
-}) => Box({
- children: [EventBox({
- ...rest,
- onHover: w => {
- if (w._open)
- return;
-
- w.get_child().get_children()[direction === 'down' || direction === 'right' ? 1 : 0].reveal_child = true;
- timeout(duration, () => w._open = true);
- },
- onHoverLost: w => {
- if (!w._open)
- return;
-
- w.get_child().get_children()[direction === 'down' || direction === 'right' ? 1 : 0].reveal_child = false;
- w._open = false;
- },
- child: Box({
- vertical: direction === 'down' || direction === 'up',
- children: [
- direction === 'down' || direction === 'right' ? indicator : null,
- Revealer({
- transition: `slide_${direction}`,
- connections,
- transitionDuration: duration,
- child,
- }),
- direction === 'up' || direction === 'left' ? indicator : null,
- ],
- }),
- })],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/mpris.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/mpris.js
deleted file mode 100644
index c9f08401c..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/mpris.js
+++ /dev/null
@@ -1,351 +0,0 @@
-const { CACHE_DIR, execAsync, ensureDirectory, lookUpIcon } = ags.Utils;
-const { Button, Icon, Label, Box, Stack, Slider } = ags.Widget;
-const { Mpris } = ags.Service;
-const { GLib } = imports.gi;
-
-const MEDIA_CACHE_PATH = CACHE_DIR + '/media';
-
-export const prefer = players => {
- const preferred = 'spotify';
- let last;
- for (const [name, mpris] of players) {
- if (name.includes(preferred))
- return mpris;
-
- last = mpris;
- }
-
- return last;
-};
-
-export const MprisBox = ({ player = prefer, ...props } = {}) => Box({
- ...props,
- connections: [[Mpris, box => {
- const mpris = Mpris.getPlayer(player);
- box.visible = mpris;
-
- if (!mpris)
- return;
-
- if (box._current)
- box.toggleClassName(box._current, false);
-
- box._current = mpris.name;
- box.toggleClassName(mpris.name);
- }]],
- setup: box => {
- const id = box.connect('draw', () => {
- box.visible = Mpris.getPlayer(player);
- box.disconnect(id);
- });
- },
-});
-
-export const CoverArt = ({ player = prefer, ...props } = {}) => Box({
- ...props,
- connections: [[Mpris, box => {
- const url = Mpris.getPlayer(player)?.coverPath;
- if (!url)
- return;
-
- box.setStyle(`background-image: url("${url}")`);
- }]],
-});
-
-export const BlurredCoverArt = ({ player = prefer, ...props } = {}) => Box({
- ...props,
- connections: [[Mpris, box => {
- const url = Mpris.getPlayer(player)?.coverPath;
- if (!url)
- return;
-
- const blurredPath = MEDIA_CACHE_PATH + '/blurred';
- const blurred = blurredPath +
- url.substring(MEDIA_CACHE_PATH.length);
-
- if (GLib.file_test(blurred, GLib.FileTest.EXISTS)) {
- box.setStyle(`background-image: url("${blurred}")`);
- return;
- }
-
- ensureDirectory(blurredPath);
- execAsync(['convert', url, '-blur', '0x22', blurred])
- .then(() => box.setStyle(`background-image: url("${blurred}")`))
- .catch(() => { });
- }]],
-});
-
-export const TitleLabel = ({ player = prefer, ...props } = {}) => Label({
- ...props,
- className: 'title',
- connections: [[Mpris, label => {
- label.label = Mpris.getPlayer(player)?.trackTitle || '';
- }]],
-});
-
-export const ArtistLabel = ({ player = prefer, ...props } = {}) => Label({
- ...props,
- className: 'artist',
- connections: [[Mpris, label => {
- label.label = Mpris.getPlayer(player)?.trackArtists.join(', ') || '';
- }]],
-});
-
-export const PlayerLabel = ({ player = prefer, ...props } = {}) => Label({
- ...props,
- connections: [[Mpris, label => {
- label.label = Mpris.getPlayer(player)?.identity || '';
- }]],
-});
-
-export const PlayerIcon = ({ symbolic = false, player = prefer, ...props } = {}) => Icon({
- ...props,
- connections: [[Mpris, icon => {
- const name = `${Mpris.getPlayer(player)?.entry}${symbolic ? '-symbolic' : ''}`;
- lookUpIcon(name)
- ? icon.icon_name = name
- : icon.icon_name = 'audio-x-generic-symbolic';
- }]],
-});
-
-export const VolumeSlider = ({ player = prefer, ...props } = {}) => Slider({
- ...props,
- drawValue: false,
- onChange: ({ value }) => {
- const mpris = Mpris.getPlayer(player);
- if (mpris && mpris.volume >= 0)
- Mpris.getPlayer(player).volume = value;
- },
- connections: [[Mpris, slider => {
- if (slider._dragging)
- return;
-
- const mpris = Mpris.getPlayer(player);
- slider.visible = mpris;
- if (mpris) {
- slider.visible = mpris.volume >= 0;
- slider.value = mpris.volume;
- }
- }]],
-});
-
-export const VolumeIcon = ({ player = prefer, items } = {}) => Stack({
- items: items || [
- ['67', Icon('audio-volume-high-symbolic')],
- ['34', Icon('audio-volume-medium-symbolic')],
- ['1', Icon('audio-volume-low-symbolic')],
- ['0', Icon('audio-volume-muted-symbolic')],
- ],
- connections: [[Mpris, stack => {
- const mpris = Mpris.getPlayer(player);
- stack.visible = mpris?.volume >= 0;
- const value = (mpris?.volume || 0) * 100;
- if (66 <= value)
- stack.shown = '67';
-
- if (34 <= value)
- stack.shown = '34';
-
- if (1 <= value)
- stack.shown = '1';
-
- stack.shown = '0';
- }]],
-});
-
-export const PositionSlider = ({ player = prefer, ...props } = {}) => {
- const update = slider => {
- if (slider._dragging)
- return;
-
- const mpris = Mpris.getPlayer(player);
- slider.visible = mpris?.length > 0;
- if (mpris && mpris.length > 0)
- slider.adjustment.value = mpris.position / mpris.length;
- };
- return Slider({
- ...props,
- drawValue: false,
- onChange: ({ adjustment: { value } }) => {
- const mpris = Mpris.getPlayer(player);
- if (mpris && mpris.length >= 0)
- Mpris.getPlayer(player).position = mpris.length * value;
- },
- connections: [
- [Mpris, update],
- [1000, update],
- ],
- });
-};
-
-function lengthStr(length) {
- const min = Math.floor(length / 60);
- const sec0 = Math.floor(length % 60) < 10 ? '0' : '';
- const sec = Math.floor(length % 60);
- return `${min}:${sec0}${sec}`;
-}
-
-export const PositionLabel = ({ player = prefer, ...props } = {}) => {
- const update = label => {
- const mpris = Mpris.getPlayer(player);
-
- if (mpris && !label._binding) {
- label._binding = mpris.connect('position', (_, time) => {
- label.label = lengthStr(time);
- });
- label.connect('destroy', () => {
- if (mpris)
- mpris.disconnect(label._binding);
-
- label._binding = null;
- });
- }
-
- mpris && mpris.length > 0
- ? label.label = lengthStr(mpris.position)
- : label.visible = mpris;
-
- return true;
- };
- return Label({
- ...props,
- connections: [
- [Mpris, update],
- [1000, update],
- ],
- });
-};
-
-export const LengthLabel = ({ player = prefer, ...props } = {}) => Label({
- ...props,
- connections: [[Mpris, label => {
- const mpris = Mpris.getPlayer(player);
- mpris && mpris.length > 0
- ? label.label = lengthStr(mpris.length)
- : label.visible = mpris;
- }]],
-});
-
-export const Slash = ({ player = prefer, ...props } = {}) => Label({
- ...props,
- label: '/',
- className: 'slash',
- connections: [
- [Mpris, label => {
- const mpris = Mpris.getPlayer(player);
- label.visible = mpris && mpris.length > 0;
- }],
- ],
-});
-
-const PlayerButton = ({
- player = prefer,
- items,
- onClick,
- prop,
- canProp,
- cantValue,
- ...rest
-} = {}) => Button({
- ...rest,
- child: Stack({ items }),
- onClicked: () => Mpris.getPlayer(player)?.[onClick](),
- connections: [[Mpris, button => {
- const mpris = Mpris.getPlayer(player);
- if (!mpris || mpris[canProp] === cantValue)
- return button.hide();
-
- button.show();
- button.child.shown = `${mpris[prop]}`;
- }]],
-});
-
-export const ShuffleButton = ({
- player,
- enabled = Label({ className: 'shuffle enabled', label: '' }),
- disabled = Label({ className: 'shuffle disabled', label: '' }),
- ...props
-} = {}) => PlayerButton({
- ...props,
- player,
- items: [
- ['true', enabled],
- ['false', disabled],
- ],
- onClick: 'shuffle',
- prop: 'shuffleStatus',
- canProp: 'shuffleStatus',
- cantValue: null,
-});
-
-export const LoopButton = ({
- player,
- none = Label({ className: 'loop none', label: '' }),
- track = Label({ className: 'loop track', label: '' }),
- playlist = Label({ className: 'loop playlist', label: '' }),
- ...props
-} = {}) => PlayerButton({
- ...props,
- player,
- items: [
- ['None', none],
- ['Track', track],
- ['Playlist', playlist],
- ],
- onClick: 'loop',
- prop: 'loopStatus',
- canProp: 'loopStatus',
- cantValue: null,
-});
-
-export const PlayPauseButton = ({
- player,
- playing = Label({ className: 'playing', label: '' }),
- paused = Label({ className: 'paused', label: '' }),
- stopped = Label({ className: 'stopped', label: '' }),
- ...props
-} = {}) => PlayerButton({
- ...props,
- player,
- items: [
- ['Playing', playing],
- ['Paused', paused],
- ['Stopped', stopped],
- ],
- onClick: 'playPause',
- prop: 'playBackStatus',
- canProp: 'canPlay',
- cantValue: false,
-});
-
-export const PreviousButton = ({
- player,
- child = Label({ className: 'previous', label: '' }),
- ...props
-} = {}) => PlayerButton({
- ...props,
- player,
- items: [
- ['true', child],
- ],
- onClick: 'previous',
- prop: 'canGoPrev',
- canProp: 'canGoPrev',
- cantValue: false,
-});
-
-export const NextButton = ({
- player,
- child = Label({ className: 'next', label: '' }),
- ...props
-} = {}) => PlayerButton({
- ...props,
- player,
- items: [
- ['true', child],
- ],
- onClick: 'next',
- prop: 'canGoNext',
- canProp: 'canGoNext',
- cantValue: false,
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/network.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/network.js
deleted file mode 100644
index f85321d50..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/network.js
+++ /dev/null
@@ -1,131 +0,0 @@
-const { Network } = ags.Service;
-const { Label, Icon, Box, Stack, Button } = ags.Widget;
-
-export const SSIDLabel = props => Label({
- ...props,
- connections: [[Network, label => label.label = Network.wifi?.ssid || 'Not Connected']],
-});
-
-export const WifiStrengthLabel = props => Label({
- ...props,
- connections: [[Network, label => label.label = `${Network.wifi?.strength || -1}`]],
-});
-
-export const WiredIndicator = ({
- connecting = Icon('network-wired-acquiring-symbolic'),
- disconnected = Icon('network-wired-no-route-symbolic'),
- disabled = Icon('network-wired-disconnected-symbolic'),
- connected = Icon('network-wired-symbolic'),
- unknown = Icon('content-loading-symbolic'),
-} = {}) => Stack({
- items: [
- ['unknown', unknown],
- ['disconnected', disconnected],
- ['disabled', disabled],
- ['connected', connected],
- ['connecting', connecting],
- ],
- connections: [[Network, stack => {
- if (!Network.wired)
- return;
-
- const { internet } = Network.wired;
- if (internet === 'connected' || internet === 'connecting')
- return stack.shown = internet;
-
- if (Network.connectivity !== 'full')
- return stack.shown = 'disconnected';
-
- return stack.shown = 'disabled';
- }]],
-});
-
-export const WifiIndicator = ({
- disabled = Icon('network-wireless-disabled-symbolic'),
- disconnected = Icon('network-wireless-offline-symbolic'),
- connecting = Icon('network-wireless-acquiring-symbolic'),
- connected = [
- ['80', Icon('network-wireless-signal-excellent-symbolic')],
- ['60', Icon('network-wireless-signal-good-symbolic')],
- ['40', Icon('network-wireless-signal-ok-symbolic')],
- ['20', Icon('network-wireless-signal-weak-symbolic')],
- ['0', Icon('network-wireless-signal-none-symbolic')],
- ],
-} = {}) => Stack({
- items: [
- ['disabled', disabled],
- ['disconnected', disconnected],
- ['connecting', connecting],
- ...connected,
- ],
- connections: [[Network, stack => {
- if (!Network.wifi)
- return;
-
- const { internet, enabled, strength } = Network.wifi;
- if (internet === 'connected') {
- for (const threshold of [80, 60, 40, 20, 0]) {
- if (strength >= threshold)
- return stack.shown = `${threshold}`;
- }
- }
-
- if (internet === 'connecting')
- return stack.shown = 'connecting';
-
- if (enabled)
- return stack.shown = 'disconnected';
-
- return stack.shown = 'disabled';
- }]],
-});
-
-export const Indicator = ({
- wifi = WifiIndicator(),
- wired = WifiIndicator(),
-} = {}) => Stack({
- items: [
- ['wired', wired],
- ['wifi', wifi],
- ],
- connections: [[Network, stack => {
- stack.shown = Network.primary || 'wifi';
- }]],
-});
-
-export const WifiToggle = props => Button({
- ...props,
- onClicked: Network.toggleWifi,
- connections: [[Network, button => {
- button.toggleClassName('on', Network.wifi?.enabled);
- }]],
-});
-
-const icons = [
- { value: 80, icon: 'network-wireless-signal-excellent-symbolic' },
- { value: 60, icon: 'network-wireless-signal-good-symbolic' },
- { value: 40, icon: 'network-wireless-signal-ok-symbolic' },
- { value: 20, icon: 'network-wireless-signal-weak-symbolic' },
- { value: 0, icon: 'network-wireless-signal-none-symbolic' },
-];
-
-export const WifiSelection = props => Box({
- ...props,
- vertical: true,
- connections: [[Network, box => box.children =
- Network.wifi?.accessPoints.map(ap => Button({
- onClicked: `nmcli device wifi connect ${ap.bssid}`,
- child: Box({
- children: [
- Icon(icons.find(({ value }) => value <= ap.strength).icon),
- Label(ap.ssid),
- ap.active && Icon({
- icon: 'object-select-symbolic',
- hexpand: true,
- halign: 'end',
- }),
- ],
- }),
- })),
- ]],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/notifications.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/notifications.js
deleted file mode 100644
index 130d076dd..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/notifications.js
+++ /dev/null
@@ -1,247 +0,0 @@
-const { GLib } = imports.gi;
-const { Notifications } = ags.Service;
-const { lookUpIcon, timeout } = ags.Utils;
-const { Box, Icon, Label, EventBox, Button, Stack, Revealer } = ags.Widget;
-
-const NotificationIcon = ({ appEntry, appIcon, image }) => {
- if (image) {
- return Box({
- valign: 'start',
- hexpand: false,
- className: 'icon img',
- style: `
- background-image: url("${image}");
- background-size: contain;
- background-repeat: no-repeat;
- background-position: center;
- min-width: 78px;
- min-height: 78px;
- `,
- });
- }
-
- let icon = 'dialog-information-symbolic';
- if (lookUpIcon(appIcon))
- icon = appIcon;
-
- if (lookUpIcon(appEntry))
- icon = appEntry;
-
- return Box({
- valign: 'start',
- hexpand: false,
- className: 'icon',
- style: `
- min-width: 78px;
- min-height: 78px;
- `,
- children: [Icon({
- icon, size: 58,
- halign: 'center', hexpand: true,
- valign: 'center', vexpand: true,
- })],
- });
-};
-
-const Notification = ({ id, summary, body, actions, urgency, time, ...icon }) => EventBox({
- className: `notification ${urgency}`,
- onPrimaryClick: () => Notifications.dismiss(id),
- properties: [['hovered', false]],
- onHover: w => {
- if (w._hovered)
- return;
-
- timeout(300, () => w._hovered = true);
- },
- onHoverLost: w => {
- if (!w._hovered)
- return;
-
- w._hovered = false;
- Notifications.dismiss(id);
- },
- vexpand: false,
- child: Box({
- vertical: true,
- children: [
- Box({
- children: [
- NotificationIcon(icon),
- Box({
- hexpand: true,
- vertical: true,
- children: [
- Box({
- children: [
- Label({
- className: 'title',
- xalign: 0,
- justification: 'left',
- hexpand: true,
- maxWidthChars: 24,
- ellipsize: 3,
- wrap: true,
- label: summary,
- useMarkup: summary.startsWith('<'),
- }),
- Label({
- className: 'time',
- valign: 'start',
- label: GLib.DateTime.new_from_unix_local(time).format('%H:%M'),
- }),
- Button({
- className: 'close-button',
- valign: 'start',
- child: Icon('window-close-symbolic'),
- onClicked: () => Notifications.close(id),
- }),
- ],
- }),
- Label({
- className: 'description',
- hexpand: true,
- useMarkup: true,
- xalign: 0,
- justification: 'left',
- label: body,
- wrap: true,
- }),
- ],
- }),
- ],
- }),
- Box({
- className: 'actions',
- children: actions.map(action => Button({
- className: 'action-button',
- onClicked: () => Notifications.invoke(id, action.id),
- hexpand: true,
- child: Label(action.label),
- })),
- }),
- ],
- }),
-});
-
-export const NotificationList = props => Box({
- ...props,
- vertical: true,
- vexpand: true,
- className: 'notification-list',
- connections: [[Notifications, box => {
- box.children = Array.from(Notifications.notifications.values())
- .map(n => Notification(n));
-
- box.visible = Notifications.notifications.size > 0;
- }]],
-});
-
-export const PopupList = ({ transition = 'slide_down' } = {}) => Box({
- className: 'notifications-popup-list',
- style: 'padding: 1px',
- children: [
- Revealer({
- transition,
- child: Box({
- vertical: true,
- properties: [
- ['map', new Map()],
- ['dismiss', (box, id, force = false) => {
- if (!id || !box._map.has(id))
- return;
-
- if (box._map.get(id)._hovered && !force)
- return;
-
- if (box._map.size - 1 === 0)
- box.get_parent().reveal_child = false;
-
- timeout(200, () => {
- box._map.get(id)?.destroy();
- box._map.delete(id);
- });
- }],
- ['notify', (box, id) => {
- if (!id)
- return;
-
- if (box._map.has(id))
- box._map.get(id).destroy();
-
- const widget = Notification(Notifications.notifications.get(id));
- box._map.set(id, widget);
- box.add(widget);
- box.show_all();
-
- timeout(10, () => {
- box.get_parent().reveal_child = true;
- });
- }],
- ],
- connections: [
- [Notifications, (box, id) => box._notify(box, id), 'notified'],
- [Notifications, (box, id) => box._dismiss(box, id), 'dismissed'],
- [Notifications, (box, id) => box._dismiss(box, id, true), 'closed'],
- ],
- }),
- }),
- ],
-});
-
-export const Placeholder = props => Box({
- className: 'placeholder',
- vertical: true,
- valign: 'center',
- vexpand: true,
- halign: 'center',
- hexpand: true,
- ...props,
- children: [
- Label({ label: '', className: 'icon' }),
- Label('Your inbox is empty'),
- ],
- connections: [
- [Notifications, box => box.visible = Notifications.notifications.size === 0],
- ],
-});
-
-export const ClearButton = props => Button({
- ...props,
- onClicked: Notifications.clear,
- connections: [[Notifications, button => button.sensitive = Notifications.notifications.size > 0]],
- child: Box({
- children: [
- Label('Clear '),
- Stack({
- items: [
- ['true', Icon('user-trash-full-symbolic')],
- ['false', Icon('user-trash-symbolic')],
- ],
- connections: [[Notifications, stack => {
- stack.shown = `${Notifications.notifications.size > 0}`;
- }]],
- }),
- ],
- }),
-});
-
-export const DNDIndicator = ({
- silent = Icon('notifications-disabled-symbolic'),
- noisy = Icon('preferences-system-notifications-symbolic'),
-} = {}) => Stack({
- items: [
- ['true', silent],
- ['false', noisy],
- ],
- connections: [[Notifications, stack => {
- stack.shown = `${Notifications.dnd}`;
- }]],
-});
-
-export const DNDToggle = props => Button({
- ...props,
- onClicked: () => { Notifications.dnd = !Notifications.dnd; },
- connections: [[Notifications, button => {
- button.toggleClassName('on', Notifications.dnd);
- }]],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/onscreenindicator.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/onscreenindicator.js
deleted file mode 100644
index 477fc7796..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/onscreenindicator.js
+++ /dev/null
@@ -1,114 +0,0 @@
-const { Service } = ags;
-const { timeout, lookUpIcon, connect } = ags.Utils;
-const { Box, Revealer, Stack, Icon } = ags.Widget;
-import { FontIcon, Progress } from './misc.js';
-
-class IndicatorService extends Service {
- static {
- Service.register(this, {
- 'popup': ['double', 'string'],
- });
- }
-
- _delay = 1500;
- _count = 0;
-
- popup(value, icon) {
- this.emit('popup', value, icon);
- this._count++;
- timeout(this._delay, () => {
- this._count--;
-
- if (this._count === 0)
- this.emit('popup', -1, icon);
- });
- }
-
- speaker() {
- const value = ags.Service.Audio.speaker.volume;
- const icon = value => {
- const icons = [];
- icons[0] = 'audio-volume-muted-symbolic';
- icons[1] = 'audio-volume-low-symbolic';
- icons[34] = 'audio-volume-medium-symbolic';
- icons[67] = 'audio-volume-high-symbolic';
- icons[101] = 'audio-volume-overamplified-symbolic';
- for (const i of [101, 67, 34, 1, 0]) {
- if (i <= value * 100)
- return icons[i];
- }
- };
- this.popup(value, icon(value));
- }
-
- display() {
- // brightness is async, so lets wait a bit
- timeout(10, () => {
- const value = ags.Service.Brightness.screen;
- const icon = value => {
- const icons = ['', '', '', '', '', '', '', '', '', '', ''];
- return icons[Math.ceil(value * 10)];
- };
- this.popup(value, icon(value));
- });
- }
-
- kbd() {
- // brightness is async, so lets wait a bit
- timeout(10, () => {
- const value = ags.Service.Brightness.kbd;
- this.popup((value * 33 + 1) / 100, 'keyboard-brightness-symbolic');
- });
- }
-
- connectWidget(widget, callback) {
- connect(this, widget, callback, 'popup');
- }
-}
-
-class Indicator {
- static { Service.export(this, 'Indicator'); }
- static instance = new IndicatorService();
- static popup(value, icon) { Indicator.instance.popup(value, icon); }
- static speaker() { Indicator.instance.speaker(); }
- static display() { Indicator.instance.display(); }
- static kbd() { Indicator.instance.kbd(); }
-}
-
-export const OnScreenIndicator = ({ height = 300, width = 48 } = {}) => Box({
- className: 'indicator',
- style: 'padding: 1px;',
- children: [Revealer({
- transition: 'slide_left',
- connections: [[Indicator, (revealer, value) => {
- revealer.revealChild = value > -1;
- }]],
- child: Progress({
- width,
- height,
- vertical: true,
- connections: [[Indicator, (progress, value) => progress.setValue(value)]],
- child: Stack({
- valign: 'start',
- halign: 'center',
- hexpand: false,
- items: [
- ['true', Icon({
- halign: 'center',
- size: width,
- connections: [[Indicator, (icon, _v, name) => icon.icon = name || '']],
- })],
- ['false', FontIcon({
- halign: 'center',
- hexpand: true,
- style: `font-size: ${width}px;`,
- connections: [[Indicator, ({ label }, _v, name) => label.label = name || '']],
- })],
- ],
- connections: [[Indicator, (stack, _v, name) => {
- stack.shown = `${!!lookUpIcon(name)}`;
- }]],
- }),
- }),
- })],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/modules/wallpaper.js b/home/isabel/programs/gui/confs/bars/ags/config/modules/wallpaper.js
deleted file mode 100644
index 05c7504a3..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/modules/wallpaper.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Theme } from '../theme/theme.js';
-const { Box } = ags.Widget;
-
-export const Wallpaper = props => Box({
- className: 'wallpaper',
- ...props,
- connections: [[Theme, box => {
- box.setStyle(`
- background-image: url('${Theme.getSetting('wallpaper')}');
- background-size: cover;
- `);
- }]],
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/common.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/common.scss
index ee2d8f4a2..96bca5e14 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/common.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/common.scss
@@ -1,316 +1,371 @@
window {
- background-color: transparent;
+ background-color: transparent;
}
-@mixin common{
- all: unset;
+@mixin common {
+ all: unset;
- * {
- font-size: $font_size;
- font-family: $font, sans-serif;
- }
+ * {
+ font-size: $font_size;
+ font-family: $font, sans-serif;
+ }
}
-@mixin widget{
- @include common;
- border-radius: $radii;
- color: $fg_color;
- background-color: $widget_bg;
- border: $border;
+@mixin widget {
+ @include common;
+ border-radius: $radii;
+ color: $fg_color;
+ background-color: $widget_bg;
+ border: $border;
}
@mixin button_focus() {
- box-shadow: inset 0 0 0 $border_width $accent;
- background-color: $hover;
- color: $hover_fg;
+ box-shadow: inset 0 0 0 $border_width $accent;
+ background-color: $hover;
+ color: $hover_fg;
}
@mixin button_hover() {
- box-shadow: inset 0 0 0 $border_width $border_color;
- background-color: $hover;
- color: $hover_fg;
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ background-color: $hover;
+ color: $hover_fg;
}
@mixin button_active() {
- box-shadow: inset 0 0 0 $border_width $border_color;
- background-image: $active_gradient;
- background-color: $accent;
- color: $accent_fg;
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ background-image: $active_gradient;
+ background-color: $accent;
+ color: $accent_fg;
}
@mixin button_disabled() {
- box-shadow: none;
- background-color: transparent;
- color: transparentize($fg_color, 0.7);
+ box-shadow: none;
+ background-color: transparent;
+ color: transparentize($fg_color, 0.7);
}
-@mixin button($flat: false, $reactive: true, $radii: $radii, $focusable: true){
- @include common;
- transition: $transition;
- border-radius: $radii;
- color: $fg_color;
-
- @if $flat{
- background-color: transparent;
- background-image: none;
- box-shadow: none;
- } @else{
- background-color: $widget_bg;
- box-shadow: inset 0 0 0 $border_width $border_color;
- }
-
- @if $reactive{
- @if $focusable {
- &:focus{
- @include button_focus;
- }
- }
-
- &:hover{
- @include button_hover;
- }
-
- &:active, &.on, &.active, &:checked {
- @include button_active;
-
- &:hover {
- box-shadow: inset 0 0 0 $border_width $border_color,
- inset 0 0 0 99px $hover;
- }
- }
- }
-
- &:disabled {
- @include button_disabled;
- }
+@mixin button($flat: false, $reactive: true, $radii: $radii, $focusable: true) {
+ @include common;
+ transition: $transition;
+ border-radius: $radii;
+ color: $fg_color;
+
+ @if $flat {
+ background-color: transparent;
+ background-image: none;
+ box-shadow: none;
+ } @else {
+ background-color: $widget_bg;
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ }
+
+ @if $reactive {
+ @if $focusable {
+ &:focus {
+ @include button_focus;
+ }
+ }
+
+ &:hover {
+ @include button_hover;
+ }
+
+ &:active,
+ &.on,
+ &.active,
+ &:checked {
+ @include button_active;
+
+ &:hover {
+ box-shadow:
+ inset 0 0 0 $border_width $border_color,
+ inset 0 0 0 99px $hover;
+ }
+ }
+ }
+
+ &:disabled {
+ @include button_disabled;
+ }
}
-@mixin accs_button($flat: false, $reactive: true){
- @include button($flat: true, $reactive: false, $focusable: false);
- color: $fg_color;
-
- > * {
- border-radius: $radii;
- transition: $transition;
-
- @if $flat{
- background-color: transparent;
- box-shadow: none;
- } @else{
- background-color: $widget_bg;
- box-shadow: inset 0 0 0 $border_width $border_color;
- }
- }
-
-
- @if $reactive{
- &:focus > *, &.focused > * {
- @include button_focus;
- }
-
- &:hover > * {
- @include button_hover;
- }
-
- &:active, &.active, &.on, &:checked {
- > * {
- @include button_active;
- }
-
- &:hover > * {
- box-shadow: inset 0 0 0 $border_width $border_color,
- inset 0 0 0 99px $hover;
- }
- }
- }
+@mixin accs_button($flat: false, $reactive: true) {
+ @include button($flat: true, $reactive: false, $focusable: false);
+ color: $fg_color;
+
+ > * {
+ border-radius: $radii;
+ transition: $transition;
+
+ @if $flat {
+ background-color: transparent;
+ box-shadow: none;
+ } @else {
+ background-color: $widget_bg;
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ }
+ }
+
+ @if $reactive {
+ &:focus > *,
+ &.focused > * {
+ @include button_focus;
+ }
+
+ &:hover > * {
+ @include button_hover;
+ }
+
+ &:active,
+ &.active,
+ &.on,
+ &:checked {
+ > * {
+ @include button_active;
+ }
+
+ &:hover > * {
+ box-shadow:
+ inset 0 0 0 $border_width $border_color,
+ inset 0 0 0 99px $hover;
+ }
+ }
+ }
}
@mixin floating_widget {
- @include common;
-
- @if $drop_shadow {
- box-shadow: 0 0 6px 0 $shadow;
- }
- margin: max($spacing, 8px);
- border: $border_width solid $popover_border_color;
- border-radius: $popover_radius;
- background-color: $bg_color;
- color: $fg_color;
- padding: $popover_padding;
+ @include common;
+
+ @if $drop_shadow {
+ box-shadow: 0 0 min(6px, $spacing/2) 0 $shadow;
+ }
+ margin: max($spacing, 8px);
+ border: $border_width solid $popover_border_color;
+ border-radius: $popover_radius;
+ background-color: $bg_color;
+ color: $fg_color;
+ padding: $popover_padding;
}
-@mixin slider($width: .7em, $slider_width: .5em, $gradient: $active_gradient, $slider: true, $focusable: true, $radii: $radii){
- @include common;
- * { all:unset; }
-
- trough{
- transition: $transition;
- border-radius: $radii;
- border: $border;
- background-color: $widget_bg;
- min-height: $width;
- min-width: $width;
-
- highlight, progress{
- border-radius: max($radii - $border_width, 0);
- background-image: $gradient;
- min-height: $width;
- min-width: $width;
- }
- }
-
- slider {
- box-shadow: none;
- background-color: transparent;
- border: $border_width solid transparent;
- transition: $transition;
- border-radius: $radii;
- min-height: $width;
- min-width: $width;
- margin: -$slider_width;
- }
-
- &:hover {
- trough {
- background-color: $hover;
- }
-
- slider {
- @if $slider{
- background-color: $fg_color;
- border-color: $border-color;
-
- @if $drop_shadow {
- box-shadow: 0 0 3px 0 $shadow;
- }
- }
- }
- }
-
- &:disabled {
- highlight, progress{
- background-color: transparentize($fg_color, 0.4);
- background-image: none;
- }
-
- slider {
- @if $slider {
- background-color: transparentize($fg_color, 0.5);
- }
- }
- }
-
- @if $focusable {
- trough:focus{
- background-color: $hover;
- box-shadow: inset 0 0 0 $border_width $accent;
-
- slider {
- @if $slider {
- background-color: $fg_color;
- box-shadow: inset 0 0 0 $border_width $accent;
- }
- }
- }
-
- }
+@mixin slider(
+ $width: 0.7em,
+ $slider_width: 0.5em,
+ $gradient: $active_gradient,
+ $slider: true,
+ $focusable: true,
+ $radii: $radii
+) {
+ @include common;
+ * {
+ all: unset;
+ }
+
+ trough {
+ transition: $transition;
+ border-radius: $radii;
+ border: $border;
+ background-color: $widget_bg;
+ min-height: $width;
+ min-width: $width;
+
+ highlight,
+ progress {
+ border-radius: max($radii - $border_width, 0);
+ background-image: $gradient;
+ min-height: $width;
+ min-width: $width;
+ }
+ }
+
+ slider {
+ box-shadow: none;
+ background-color: transparent;
+ border: $border_width solid transparent;
+ transition: $transition;
+ border-radius: $radii;
+ min-height: $width;
+ min-width: $width;
+ margin: -$slider_width;
+ }
+
+ &:hover {
+ trough {
+ background-color: $hover;
+ }
+
+ slider {
+ @if $slider {
+ background-color: $fg_color;
+ border-color: $border-color;
+
+ @if $drop_shadow {
+ box-shadow: 0 0 3px 0 $shadow;
+ }
+ }
+ }
+ }
+
+ &:disabled {
+ highlight,
+ progress {
+ background-color: transparentize($fg_color, 0.4);
+ background-image: none;
+ }
+ }
+
+ @if $focusable {
+ trough:focus {
+ background-color: $hover;
+ box-shadow: inset 0 0 0 $border_width $accent;
+
+ slider {
+ @if $slider {
+ background-color: $fg_color;
+ box-shadow: inset 0 0 0 $border_width $accent;
+ }
+ }
+ }
+ }
}
-@mixin shader($width: 3em){
- @include common;
+@mixin shader($width: 3em) {
+ @include common;
+ border-radius: max($radii - $border_width, 0);
- label {
- color: $shader_fg;
- text-shadow: $text_shadow;
- }
+ label {
+ color: $shader_fg;
+ text-shadow: $text_shadow;
+ }
- @if $theme == 'dark' {
- box-shadow: inset 0 0 $width $width/3 transparentize($bg_color, 0.3);
- }
+ @if $theme == "dark" {
+ box-shadow: inset 0 0 $width $width/3 transparentize($bg_color, 0.2);
+ }
- @if $theme == 'light' {
- background-color: transparentize($bg_color, 0.8);
- }
+ @if $theme == "light" {
+ background-color: transparentize($bg_color, 0.8);
+ }
}
-@mixin text_border{
- text-shadow:
- -1 * $border_width -1 * $border_width 0 $border_color,
- $border_width $border_width 0 $border_color,
- -1 * $border_width $border_width 0 $border_color,
- $border_width -1 * $border_width 0 $border_color;
+@mixin text_border {
+ text-shadow:
+ -1 * $border_width -1 * $border_width 0 $border_color,
+ $border_width $border_width 0 $border_color,
+ -1 * $border_width $border_width 0 $border_color,
+ $border_width -1 * $border_width 0 $border_color;
+
+ -gtk-icon-shadow:
+ -1 * $border_width -1 * $border_width 0 $border_color,
+ $border_width $border_width 0 $border_color,
+ -1 * $border_width $border_width 0 $border_color,
+ $border_width -1 * $border_width 0 $border_color;
}
-@mixin scrollbar{
- scrollbar, scrollbar * {
- all: unset;
- }
-
- scrollbar.vertical{
- slider{
- background: $widget_bg;
- border-radius: $radii;
- min-width: .6em;
- min-height: 2em;
- transition: $transition;
-
- &:hover {
- background-color: transparentize($fg_color, 0.6);
- min-width: .8em;
- }
- }
- }
+@mixin scrollbar {
+ scrollbar,
+ scrollbar * {
+ all: unset;
+ }
+
+ scrollbar.vertical {
+ transition: $transition;
+ background-color: transparentize($bg_color, 0.7);
+
+ &:hover {
+ background-color: transparentize($bg_color, 0.3);
+
+ slider {
+ background-color: transparentize($fg_color, 0.3);
+ min-width: 0.6em;
+ }
+ }
+ }
+
+ scrollbar.vertical slider {
+ background-color: transparentize($fg_color, 0.5);
+ border-radius: $radii;
+ min-width: 0.4em;
+ min-height: 2em;
+ transition: $transition;
+ }
}
-@mixin switch{
- @include button;
+@mixin switch {
+ @include button;
- slider {
- background-color: $fg_color;
- border-radius: $radii;
- min-width: 24px;
- min-height: 24px;
- }
+ slider {
+ background-color: $fg_color;
+ border-radius: $radii;
+ min-width: 24px;
+ min-height: 24px;
+ }
- image { color: transparent; }
+ image {
+ color: transparent;
+ }
}
+@mixin hidden {
+ background-color: transparent;
+ background-image: none;
+ border-color: transparent;
+ box-shadow: none;
+ -gtk-icon-transform: scale(0);
+
+ * {
+ background-color: transparent;
+ background-image: none;
+ border-color: transparent;
+ box-shadow: none;
+ -gtk-icon-transform: scale(0);
+ }
+}
tooltip {
- @include common;
- background-color: transparent;
- border: none;
-
- > * > *{
- background-color: $bg_color;
- border-radius: $radii;
- border: $border_width solid $popover_border_color;
- color: $fg_color;
- padding: 8px;
- margin: 4px;
- box-shadow: 0 0 3px 0 $shadow;
- }
+ @include common;
+ * {
+ all: unset;
+ }
+
+ background-color: transparent;
+ border: none;
+
+ > * > * {
+ background-color: $bg_color;
+ border-radius: $radii;
+ border: $border_width solid $popover_border_color;
+ color: $fg_color;
+ padding: 8px;
+ margin: 4px;
+ box-shadow: 0 0 3px 0 $shadow;
+ }
}
window.popup {
- > * {
- border: none;
- box-shadow: none;
- }
-
- menu {
- border-radius: $popover_radius;
- background-color: $bg_color;
- padding: $spacing;
- border: $border;
-
- menuitem {
- @include button;
- padding: $spacing/2;
- margin: $spacing/2 0;
- > * { margin-left: -30px; }
- &:first-child { margin-top: 0; }
- &:last-child { margin-bottom: 0; }
- }
- }
+ > * {
+ border: none;
+ box-shadow: none;
+ }
+
+ menu {
+ border-radius: $popover_radius;
+ background-color: $bg_color;
+ padding: $spacing;
+ border: $border;
+
+ separator {
+ background-color: $border_color;
+ }
+
+ menuitem {
+ @include button;
+ padding: $spacing/2;
+ margin: $spacing/2 0;
+ &:first-child {
+ margin-top: 0;
+ }
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/main.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/main.scss
index affcae47a..63779b627 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/main.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/main.scss
@@ -1,12 +1,12 @@
-@import './generated';
-@import './common';
-@import './widgets/notifications';
-@import './widgets/media';
-@import './widgets/datemenu';
-@import './widgets/applauncher';
-@import './widgets/quicksettings';
-@import './widgets/powermenu';
-@import './widgets/desktop';
-@import './widgets/dashboard';
-@import './widgets/bar';
-@import './widgets/settings';
+@import "/tmp/ags/scss/generated";
+@import "./common";
+@import "./widgets/notifications";
+@import "./widgets/media";
+@import "./widgets/applauncher";
+@import "./widgets/quicksettings";
+@import "./widgets/powermenu";
+@import "./widgets/desktop";
+@import "./widgets/dashboard";
+@import "./widgets/bar";
+@import "./widgets/settings";
+@import "/tmp/ags/scss/additional";
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/applauncher.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/applauncher.scss
index 589a4be0b..1dd4ba7c8 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/applauncher.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/applauncher.scss
@@ -1,93 +1,87 @@
window#applauncher .applauncher {
- @include floating_widget;
-
- .wallpaper {
- margin: $popover_padding;
- margin-bottom: 0;
- padding: 30px;
- border-radius: $radii;
-
- @if $drop_shadow {
- box-shadow: 0 0 0 $border_width $border_color,
- inset 0 0 $spacing 0 $shadow;
- }
-
- @else {
- box-shadow: 0 0 0 $border_width $border_color;
- }
-
- image {
- @include widget;
- border-radius: $radii/2;
- background-color: transparentize($bg_color, 0.4);
- padding: $spacing/2;
- margin-right: $spacing;
- -gtk-icon-transform: scale(0.8);
- }
-
- entry {
- @include widget;
- border-radius: $radii/2;
- background-color: transparentize($bg_color, 0.4);
- transition: $transition;
- padding: $spacing/2;
- }
- }
-
- .separator {
- min-height: 1px;
- background-color: $hover;
- margin: $spacing/2;
- }
-
- scrolledwindow {
- @include scrollbar;
- padding: $popover_padding;
- min-width: 500px;
- min-height: 350px;
- }
-
- .app {
- all: unset;
- transition: $transition;
- padding: $spacing;
-
- label {
- transition: $transition;
-
- &.title {
- color: $fg_color;
- }
-
- &.description {
- color: transparentize($fg_color, 0.3);
- }
- }
-
- image {
- transition: $transition;
- margin-right: $spacing;
- }
-
- &:hover,
- &:focus {
- .title {
- color: $accent;
- }
-
- image {
- -gtk-icon-shadow: 2px 2px $accent;
- }
- }
-
- &:active {
- background-color: transparentize($accent, 0.5);
- border-radius: $radii;
- box-shadow: inset 0 0 0 $border_width $border_color;
-
- .title {
- color: $fg_color;
- }
- }
- }
+ @include floating_widget;
+
+ .header {
+ margin: $popover_padding;
+ margin-bottom: $popover_padding/2;
+
+ image,
+ entry {
+ @include widget;
+ padding: $spacing/2;
+ }
+
+ entry {
+ padding-left: $spacing;
+ }
+
+ image {
+ margin-right: $spacing;
+ -gtk-icon-transform: scale(0.8);
+ font-size: $font-size * 1.6;
+ }
+ }
+
+ .separator {
+ min-height: 1px;
+ background-color: $hover;
+ margin: $spacing/2;
+ }
+
+ scrolledwindow {
+ @include scrollbar;
+ padding: $popover_padding;
+ min-width: 500px;
+ min-height: 350px;
+ }
+
+ .placeholder {
+ margin-top: $spacing;
+ color: $fg_color;
+ font-size: 1.2em;
+ }
+
+ .app {
+ all: unset;
+ transition: $transition;
+ padding: $spacing;
+
+ label {
+ transition: $transition;
+
+ &.title {
+ color: $fg_color;
+ }
+
+ &.description {
+ color: transparentize($fg_color, 0.3);
+ }
+ }
+
+ image {
+ transition: $transition;
+ margin-right: $spacing;
+ }
+
+ &:hover,
+ &:focus {
+ .title {
+ color: $accent;
+ }
+
+ image {
+ -gtk-icon-shadow: 2px 2px $accent;
+ }
+ }
+
+ &:active {
+ background-color: transparentize($accent, 0.5);
+ border-radius: $radii;
+ box-shadow: inset 0 0 0 $border_width $border_color;
+
+ .title {
+ color: $fg_color;
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/bar.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/bar.scss
index 7e59430af..bf07a7f97 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/bar.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/bar.scss
@@ -1,301 +1,293 @@
-$float: 5px;
+$float: $spacing * 0.7;
@mixin panel_button($flat: false, $reactive: true) {
- all: unset;
-
- @if $bar_style =='separated' {
- transition: $transition;
-
- >* {
- @include floating_widget;
- border-radius: $radii;
- margin: $wm_gaps $float;
- transition: $transition;
- }
-
- &:hover>* {
- color: $hover_fg;
-
- @if $drop_shadow {
- box-shadow: 0 0 $wm_gaps/2 0 $shadow,
- inset 0 0 0 99px $hover;
- }
-
- @else {
- box-shadow: inset 0 0 0 99px $hover;
- }
- }
-
- &:active>*,
- &.active>* {
-
- label,
- image {
- color: $accent_fg;
- }
-
- background-image: $active_gradient;
- background-color: $accent;
- }
- }
-
- @else {
- @include accs_button($flat, $reactive);
-
- >* {
- margin: $float;
- }
- }
-
- label {
- font-weight: bold;
- }
-
- image {
- font-size: $font-size * 1.2;
- }
-
- >* {
- padding: .3em .5em;
- }
+ all: unset;
+
+ @if $bar_style == "separated" {
+ transition: $transition;
+
+ > * {
+ @include floating_widget;
+ border-radius: $radii;
+ margin: $wm_gaps $float;
+ transition: $transition;
+ }
+
+ &:hover > * {
+ color: $hover_fg;
+
+ @if $drop_shadow {
+ box-shadow:
+ 0 0 min(6px, $spacing/2) 0 $shadow,
+ inset 0 0 0 99px $hover;
+ } @else {
+ box-shadow: inset 0 0 0 99px $hover;
+ }
+ }
+
+ &:active > *,
+ &.active > * {
+ label,
+ image {
+ color: $accent_fg;
+ }
+
+ background-image: $active_gradient;
+ background-color: $accent;
+ }
+ } @else {
+ @include accs_button($flat, $reactive);
+
+ > * {
+ margin: $float;
+ }
+ }
+
+ label {
+ font-size: $font-size;
+ font-weight: bold;
+ }
+
+ image {
+ font-size: $font-size * 1.2;
+ }
+
+ > * {
+ padding: 0.3em 0.5em;
+ }
}
.panel {
- @if $bar_style =='normal' {
- background-color: $bg_color;
- }
-
- @if not $screen_corners and $bar_style =='normal' {
- border-bottom: $border;
- }
-
- @if $bar_style =='floating' {
- @include floating_widget;
- margin: $wm_gaps;
- padding: 0;
- }
-
- @if $bar_style =='separated' {
- >.end button:last-child>* {
- margin-right: $wm_gaps;
- }
-
- >.start button:first-child>* {
- margin-left: $wm_gaps;
- }
- }
-
- .panel-button {
- @include panel_button($flat: true);
- }
-
- .quicksettings>box>* {
- @if $layout !='leftbar' {
- margin: 0 $spacing/2;
-
- &:last-child {
- margin-right: 0;
- }
-
- &:first-child {
- margin-left: 0;
- }
- }
-
- @else {
- margin: $spacing/2 0;
-
- &:last-child {
- margin-right: 0;
- }
-
- &:first-child {
- margin-left: 0;
- }
- }
- }
-
- .separator {
- @if $bar_style =='separated' {
- background-color: transparent;
- }
-
- @else {
- background-color: transparentize($fg_color, 0.7);
- }
-
- @if $layout =='leftbar' {
- min-height: 5px;
- min-width: 22px;
- }
-
- @else {
- min-height: 22px;
- min-width: 5px;
- }
-
- border-radius: $radii;
-
- }
-
- .launcher {
- label {
- color: transparentize($accent, 0.2);
- }
-
- &:hover label {
- color: $accent;
- }
-
- &:active label,
- &.active label {
- color: $accent_fg;
- }
- }
-
- .powermenu {
- image {
- color: transparentize($red, 0.3);
- }
-
- &:hover image {
- color: transparentize($red, 0.15);
- }
-
- &:active image {
- color: $red;
- }
- }
-
- .quicksettings:not(.active) .battery {
- &.low {
- color: $red;
- }
-
- &.charged,
- &.charging {
- color: $green;
- }
- }
-
- .workspaces {
- >* {
- padding: 0;
- }
-
- @if $layout =='leftbar' {
- padding-left: 4px;
- }
-
- .eventbox {
- transition: $transition;
-
- @if $bar_style =='separated' {
- border-radius: max($radii - $border_width, 0);
-
- &:hover {
- background-color: $hover;
- }
- }
-
- @else {
- @include button;
- }
- }
-
- button {
- all: unset;
-
- .indicator {
- min-width: 10px;
- min-height: 10px;
- border-radius: $radii*0.6;
- border: 2px solid transparent;
- transition: border-color $transition;
-
- @if $layout =='leftbar' {
- margin: $spacing/2 $spacing/1.5;
- }
-
- @else {
- margin: 0 $spacing/2;
- }
-
- .fill {
- transition: background-color $transition;
- margin: 2px;
- min-width: 6px;
- min-height: 6px;
- border-radius: max($radii*0.7 - 4px, 0);
- }
- }
-
- @if $layout !='leftbar' {
- &:last-child .indicator {
- margin-right: $spacing;
- }
-
- &:first-child .indicator {
- margin-left: $spacing;
- }
- }
-
- @else {
- &:last-child .indicator {
- margin-bottom: $spacing;
- }
-
- &:first-child .indicator {
- margin-top: $spacing;
- }
- }
-
- &.empty .indicator {
- border-color: transparentize($fg_color, 0.3);
- }
-
- &.occupied .indicator {
- border-color: transparentize($fg_color, 0.1);
-
- .fill {
- background-color: transparentize($fg_color, 0.1)
- }
- }
-
- &:hover .indicator {
- border-color: transparentize($accent, 0.2);
-
- .fill {
- background-color: transparentize($accent, 0.2)
- }
- }
-
- &.active .indicator,
- &:active .indicator {
- border-color: $accent;
-
- .fill {
- background-color: $accent
- }
- }
-
- &.empty .indicator .fill {
- background-color: transparent;
- }
- }
- }
-
- .media {
- &.spotify .icon {
- color: $green;
- }
-
- &.firefox .icon {
- color: $orange;
- }
-
- &.mpv .icon {
- color: $magenta;
- }
- }
+ @if $bar_style == "normal" {
+ background-color: $bg_color;
+ }
+
+ @if not $screen_corners and $bar_style == "normal" {
+ @if $layout == "bottombar" {
+ border-top: $border;
+ } @else {
+ border-bottom: $border;
+ }
+ }
+
+ @if $bar_style == "floating" {
+ @include floating_widget;
+ margin: $wm_gaps;
+ padding: 0;
+ }
+
+ @if $bar_style == "separated" {
+ > .end > button:last-child > * {
+ margin-right: $wm_gaps;
+ }
+
+ > .start > button:first-child > * {
+ margin-left: $wm_gaps;
+ }
+ }
+
+ .panel-button {
+ @include panel_button($flat: true);
+ }
+
+ separator {
+ background-color: transparentize($fg_color, 0.98);
+ border-radius: $radii;
+ min-height: 5px;
+ min-width: 5px;
+ }
+
+ .quicksettings > box > * {
+ margin: 0 $spacing/2;
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ &:first-child {
+ margin-left: 0;
+ }
+ }
+
+ .applauncher {
+ label {
+ color: transparentize($accent, 0.2);
+ }
+
+ &:hover label {
+ color: $accent;
+ }
+
+ &:active label,
+ &.active label {
+ color: $accent_fg;
+ }
+ }
+
+ .powermenu {
+ image {
+ color: transparentize($red, 0.3);
+ }
+
+ &:hover image {
+ color: transparentize($red, 0.15);
+ }
+
+ &:active image {
+ color: $red;
+ }
+ }
+
+ /* stylelint-disable-next-line selector-not-notation */
+ .quicksettings:not(.active):not(:active) {
+ .bluetooth {
+ color: $blue;
+ }
+
+ .battery {
+ &.low {
+ color: $red;
+ }
+
+ &.charged,
+ &.charging {
+ color: $green;
+ }
+ }
+ }
+
+ .media {
+ &.spotify image {
+ color: $green;
+ }
+
+ &.firefox image {
+ color: $orange;
+ }
+
+ &.mpv image {
+ color: $magenta;
+ }
+ }
+
+ .notifications {
+ image {
+ color: $yellow;
+ }
+ }
+
+ .battery-bar {
+ image {
+ margin-right: $spacing/2;
+ }
+
+ .font-icon {
+ font-size: 1.3em;
+ }
+
+ levelbar trough {
+ @include widget;
+ min-width: 60px;
+ min-height: 14px;
+
+ block.filled {
+ border-radius: max($radii - $border_width, 0);
+ background-image: $active_gradient;
+ }
+ }
+
+ @mixin color($color) {
+ image,
+ label {
+ color: $color;
+ }
+
+ block.filled {
+ background-image: linear-gradient(
+ to right,
+ $color,
+ lighten($color, 6%)
+ );
+ }
+ }
+
+ .medium {
+ @include color($yellow);
+ }
+
+ .low {
+ @include color($red);
+ }
+
+ .charging {
+ @include color($green);
+ }
+
+ &:active {
+ @include color($accent_fg);
+ }
+ }
+
+ .workspaces {
+ > * {
+ padding: 0;
+ }
+
+ .eventbox {
+ transition: $transition;
+
+ @if $bar_style == "separated" {
+ border-radius: max($radii - $border_width, 0);
+
+ &:hover {
+ background-color: $hover;
+ }
+ } @else {
+ @include button($flat: true);
+ }
+ }
+
+ button {
+ all: unset;
+
+ .indicator {
+ font-size: 0;
+ min-width: 6px;
+ min-height: 6px;
+ border-radius: $radii * 0.6;
+ border: $border;
+ margin: 0 $spacing/2;
+ transition: $transition/2;
+ background-color: transparentize($fg_color, 0.8);
+ }
+
+ &:last-child .indicator {
+ margin-right: $spacing;
+ }
+
+ &:first-child .indicator {
+ margin-left: $spacing;
+ }
+
+ &.occupied .indicator {
+ background-color: transparentize($fg_color, 0.2);
+ min-width: 8px;
+ min-height: 8px;
+ }
+
+ &:hover .indicator {
+ box-shadow: inset 0 0 0 10px transparentize($fg_color, 0.8);
+ }
+
+ &.active .indicator,
+ &:active .indicator {
+ background-color: $accent;
+ }
+
+ &.active .indicator {
+ min-width: 24px;
+ min-height: 12px;
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/dashboard.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/dashboard.scss
index 3cc20c456..6fce64cac 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/dashboard.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/dashboard.scss
@@ -1,68 +1,151 @@
+@mixin calendar {
+ @include widget;
+ padding: $spacing * 2 $spacing * 2 0;
+
+ calendar {
+ all: unset;
+
+ &.button {
+ @include button($flat: true);
+ margin: 1em;
+ }
+
+ &:selected {
+ @include button($flat: false);
+ }
+
+ &.header {
+ background-color: transparent;
+ border: none;
+ color: transparentize($fg_color, 0.5);
+ }
+
+ &.highlight {
+ background-color: transparent;
+ color: transparentize($accent, 0.5);
+ }
+
+ &:indeterminate {
+ color: transparentize($fg_color, 0.9);
+ }
+
+ font-size: 1.1em;
+ padding: 0.2em;
+ }
+}
+
window#dashboard .dashboard {
- @include floating_widget;
-
- .notifications {
- @include notifications;
- min-width: 450px;
-
- .header {
- padding-left: .3em;
- margin-bottom: $spacing;
- }
-
- .notification-list-box {
- @include widget;
-
- .wallpaper {
- border-radius: max($radii - $border_width, 0);
- background-position: bottom right;
-
- @if $drop_shadow {
- box-shadow: inset 0 0 $spacing 0 $shadow;
- }
- }
- }
-
- .notification-list {
- padding: $spacing/2;
-
- .notification>box {
- @include floating_widget;
- border-radius: $radii;
- padding: $spacing;
- margin: $spacing/2;
- }
- }
-
- .placeholder {
- color: $wallpaper_fg;
-
- .icon {
- font-size: 7em
- }
-
- label {
- @if $drop_shadow {
- text-shadow: $text_shadow;
- }
-
- @else {
- @include text_border;
- }
-
- }
- }
- }
-
- .separator {
- background-color: transparentize($fg_color, 0.94);
- min-width: 2px;
- border-radius: $radii;
- margin: 0 $spacing;
- }
-
- .datemenu {
- @include datemenu;
- }
+ @include floating_widget;
+
+ .notifications {
+ min-width: 450px;
+
+ .header {
+ padding-left: 0.3em;
+ margin-bottom: $spacing;
+
+ label {
+ font-size: 1.2em;
+ }
+
+ button {
+ @include button;
+ padding: $spacing/2 $spacing;
+
+ label {
+ font-size: 1.2em;
+ }
+ }
+ }
+
+ .notification-scrollable {
+ @include scrollbar;
+
+ scrollbar,
+ scrollbar:hover {
+ border-radius: max($radii - $border_width, 0);
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ .notification {
+ @include notification;
+
+ > box {
+ @include widget;
+ margin: $spacing/2 0;
+ padding: $spacing;
+ }
+ }
+ }
+
+ .placeholder {
+ color: $wallpaper_fg;
+
+ image {
+ font-size: 7em;
+ }
+
+ label {
+ font-size: 1.2em;
+ }
+
+ label,
+ image {
+ @if $drop_shadow {
+ text-shadow: $text_shadow;
+ -gtk-icon-shadow: $text_shadow;
+ } @else {
+ @include text_border;
+ }
+ }
+ }
+ }
+
+ separator {
+ background-color: $popover_border_color;
+ min-width: 2px;
+ border-radius: $radii;
+ margin: 0 $spacing;
+ }
+
+ .clock {
+ font-size: 5em;
+ }
+
+ .uptime {
+ font-size: 2em;
+ color: transparentize($fg_color, 0.2);
+ }
+
+ .calendar {
+ @include calendar;
+
+ margin-top: $spacing * 2;
+ }
+
+ .circular-progress-box {
+ @include widget;
+ margin-top: $spacing;
+ margin-right: $spacing;
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ padding: $spacing;
+
+ .circular-progress {
+ min-height: $spacing * 8;
+ min-width: $spacing * 8;
+ margin: $spacing/2;
+ font-size: $spacing;
+ background-color: $bg_color;
+ color: $accent;
+ image {
+ font-size: 1.8em;
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/datemenu.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/datemenu.scss
deleted file mode 100644
index b713a3fcb..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/datemenu.scss
+++ /dev/null
@@ -1,58 +0,0 @@
-@mixin calendar {
- @include widget;
- padding: $spacing*2 $spacing*2 0;
-
- calendar {
- all: unset;
-
- &.button {
- @include button($flat: true);
- margin: 1em;
- }
-
- &:selected {
- background-color: $hover;
- border-radius: $radii*0.6;
- }
-
- &.header {
- background-color: transparent;
- border: none;
- color: transparentize($fg_color, 0.5);
- }
-
- &.highlight {
- background-color: transparent;
- color: transparentize($accent, 0.5);
- }
-
- &:indeterminate {
- color: transparentize($fg_color, 0.9);
- }
-
- font-size: 1.1em;
- padding: .2em;
- }
-}
-
-@mixin datemenu {
- .clock {
- font-size: 5em;
- }
-
- .uptime {
- font-size: 2em;
- color: transparentize($fg_color, 0.2);
- }
-
- .calendar {
- @include calendar;
-
- margin-top: $spacing*2;
- }
-}
-
-window#datemenu .datemenu {
- @include floating_widget;
- @include datemenu;
-}
\ No newline at end of file
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/desktop.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/desktop.scss
index d2413853f..40ab31082 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/desktop.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/desktop.scss
@@ -1,51 +1,23 @@
window.corner .corner {
- background-color: if($screen_corners, $bg_color, transparent);
- border-radius: if($screen_corners, $radii*2, 0);
-}
-
-.desktop {
- @if $bar_style =='normal' {
- border-radius: if($screen_corners, $popover_radius, 0);
- box-shadow: inset 0 0 $spacing 0 $shadow;
- }
-
- @if $drop_shadow {
- label {
- text-shadow: $text_shadow;
- }
- }
-
- @else {
-
- .separator {
- border: $border;
- }
-
- label {
- @include text_border;
- }
- }
+ background-color: if($screen_corners, $bg_color, transparent);
+ border-radius: if($screen_corners, $radii * 2, 0);
}
window.indicator .progress {
- @include floating_widget;
- padding: $spacing/2;
-
- .fill {
- border-radius: max($popover_radius - $spacing/2, 0);
- background-color: $accent;
- color: $accent_fg;
-
- image {
- -gtk-icon-transform: scale(0.7);
- }
-
- .icon overlay {
- font-size: 34px;
-
- label {
- font-size: 34px;
- }
- }
- }
+ @include floating_widget;
+ padding: $spacing/2;
+
+ .fill {
+ border-radius: max($popover_radius - $spacing/2, 0);
+ background-color: $accent;
+ color: $accent_fg;
+
+ image {
+ -gtk-icon-transform: scale(0.7);
+ }
+
+ .font-icon {
+ font-size: 34px;
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/media.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/media.scss
index 318f998e0..4d525b5e1 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/media.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/media.scss
@@ -1,114 +1,130 @@
@mixin player_color($color) {
- button {
- .shuffle.enabled {
- color: $color;
- }
-
- .loop {
- &.playlist, &.track {
- color: $color;
- }
- }
-
- &:active label {
- color: $color;
- }
- }
-
- .position-slider:hover trough {
- background-color: transparentize($color, 0.5);
- }
+ button {
+ .shuffle.enabled {
+ color: $color;
+ }
+
+ .loop {
+ &.playlist,
+ &.track {
+ color: $color;
+ }
+ }
+
+ &:active label {
+ color: $color;
+ }
+ }
+
+ .position-slider:hover trough {
+ background-color: transparentize($color, 0.5);
+ }
+
+ .player-icon {
+ color: $color;
+ }
}
@mixin media() {
- label {
- color: $shader_fg;
- text-shadow: $text_shadow;
- }
-
- .shader {
- @include shader;
- }
-
- .cover-art {
- border-radius: $radii*0.8;
- min-height: 100px;
- min-width: 100px;
- box-shadow: 2px 2px 2px 0 $shadow;
- margin: $spacing;
- margin-bottom: 0;
-
- .shader {
- background-color: transparent;
- border-radius: max($radii*0.8 - 1px, 0);
- box-shadow: inset 0 0 0 999px transparentize($bg_color, 0.8);
- }
- }
-
- .cover-art-bg, .cover-art {
- background-size: cover;
- background-position: center;
- }
-
- .labels {
- margin-top: $spacing;
-
- label {
- font-size: 1.1em;
- text-shadow: $text_shadow;
-
- &.title {
- font-weight: bold;
- }
- }
- }
-
- .position-slider {
- @include slider($width: .4em, $slider: false, $gradient: linear-gradient($shader_fg, $shader_fg), $radii: 0);
- margin: $spacing 0;
-
- trough {
- border: none;
- background-color: transparentize($shader_fg, 0.7);
- }
- }
-
- .footer-box {
- margin: -$spacing/2 $spacing $spacing/2;
-
- image {
- -gtk-icon-shadow: $text_shadow;
- }
- }
-
- .controls button {
- all: unset;
-
- label {
- font-size: 2em;
- color: transparentize($shader_fg, 0.2);
- transition: $transition;
-
- &.shuffle, &.loop {
- font-size: 1.4em;
-
- }
- }
-
- &:hover label {
- color: transparentize($shader_fg, 0.1);
- }
-
- &:active label {
- color: $shader_fg;
- }
- }
-
- &.spotify { @include player_color($green); }
- &.firefox { @include player_color($orange); }
- &.mpv { @include player_color($magenta); }
-
- &.firefox .footer-box {
- margin-top: -$spacing*2;
- }
+ @include widget;
+
+ label {
+ color: $shader_fg;
+ text-shadow: $text_shadow;
+ }
+
+ .shader {
+ @include shader;
+ }
+
+ .cover {
+ border-radius: $radii * 0.8;
+ min-height: 100px;
+ min-width: 100px;
+ box-shadow: 2px 2px 2px 0 $shadow;
+ margin: $spacing;
+ margin-bottom: 0;
+
+ .shader {
+ background-color: transparent;
+ border-radius: max($radii * 0.8 - 1px, 0);
+ box-shadow: inset 0 0 0 999px transparentize($bg_color, 0.8);
+ }
+ }
+
+ .blurred-cover,
+ .cover {
+ background-size: cover;
+ background-position: center;
+ border-radius: max($radii - $border_width, 0);
+ }
+
+ .labels {
+ margin-top: $spacing;
+
+ label {
+ font-size: 1.1em;
+ text-shadow: $text_shadow;
+
+ &.title {
+ font-weight: bold;
+ }
+ }
+ }
+
+ .position-slider {
+ @include slider(
+ $width: 0.4em,
+ $slider: false,
+ $gradient: linear-gradient($shader_fg, $shader_fg),
+ $radii: 0
+ );
+ margin: $spacing 0;
+
+ trough {
+ border: none;
+ background-color: transparentize($shader_fg, 0.7);
+ }
+ }
+
+ .footer-box {
+ margin: -$spacing/2 $spacing $spacing/2;
+
+ image {
+ -gtk-icon-shadow: $text_shadow;
+ }
+ }
+
+ .controls button {
+ all: unset;
+
+ label {
+ font-size: 2em;
+ color: transparentize($shader_fg, 0.2);
+ transition: $transition;
+
+ &.shuffle,
+ &.loop {
+ font-size: 1.4em;
+ }
+ }
+
+ &:hover label {
+ color: transparentize($shader_fg, 0.1);
+ }
+
+ &:active label {
+ color: $shader_fg;
+ }
+ }
+
+ &.spotify {
+ @include player_color($green);
+ }
+ &.firefox {
+ @include player_color($orange);
+ }
+ &.mpv {
+ @include player_color($magenta);
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/notifications.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/notifications.scss
index 1dd84ada3..27b1a9e54 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/notifications.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/notifications.scss
@@ -1,113 +1,94 @@
@mixin notification() {
- &.critical > box {
- box-shadow: inset 0 0 .5em 0 $red;
- }
-
- > box {
- border-radius: $radii/2;
- padding: $spacing;
- }
-
- &:hover {
- .close-button{
- @include button_hover;
- background-color: transparentize($red, .5);
- }
- }
-
- .title {
- margin-right: $spacing;
- color: $fg_color;
- font-size: 1.1em;
- }
-
- .time {
- color: transparentize($fg_color, .2);
- }
-
- .description {
- font-size: .9em;
- color: transparentize($fg_color, .2);
- }
-
- .icon {
- border-radius: $radii*0.8;
- margin-right: $spacing;
-
- &.img {
- border: $border;
- }
- }
-
- .actions button {
- @include button;
- border-radius: $radii*0.8;
- font-size: 1.2em;
- padding: $spacing/2 $spacing;
- margin: $spacing $spacing/2 0;
-
- &:first-child {
- margin-left: 0;
- }
-
- &:last-child {
- margin-right: 0;
- }
- }
-
- button.close-button {
- @include button($flat: true);
- margin-left: $spacing;
- border-radius: $radii*0.8;
- min-width: 1.2em;
- min-height: 1.2em;
-
- &:hover {
- background-color: transparentize($red, .5);
- }
-
- &:active {
- background-image: linear-gradient($red, $red);
- }
- }
+ &.critical > box {
+ box-shadow: inset 0 0 0.5em 0 $red;
+ }
+
+ > box {
+ border-radius: $radii/2;
+ padding: $spacing;
+ }
+
+ &:hover {
+ .close-button {
+ @include button_hover;
+ background-color: transparentize($red, 0.5);
+ }
+ }
+
+ .content {
+ .title {
+ margin-right: $spacing;
+ color: $fg_color;
+ font-size: 1.1em;
+ }
+
+ .time {
+ color: transparentize($fg_color, 0.2);
+ }
+
+ .description {
+ font-size: 0.9em;
+ color: transparentize($fg_color, 0.2);
+ }
+
+ .icon {
+ border-radius: $radii * 0.8;
+ margin-right: $spacing;
+
+ &.img {
+ border: $border;
+ }
+ }
+ }
+
+ .actions {
+ padding-top: $spacing;
+
+ button {
+ @include button;
+ border-radius: $radii * 0.8;
+ font-size: 1.2em;
+ padding: $spacing/2 0;
+ margin: 0 $spacing/2 0;
+
+ &:first-child {
+ margin-left: 0;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+
+ button.close-button {
+ @include button($flat: true);
+ margin-left: $spacing;
+ border-radius: $radii * 0.8;
+ min-width: 1.2em;
+ min-height: 1.2em;
+
+ &:hover {
+ background-color: transparentize($red, 0.5);
+ }
+
+ &:active {
+ background-image: linear-gradient($red, $red);
+ }
+ }
}
-@mixin notifications {
- .header {
- label {
- font-size: 1.2em;
- }
-
- button {
- @include button;
- padding: $spacing/2 $spacing;
-
- label {
- font-size: 1.2em;
- }
- }
- }
-
- .notification-list {
- @include scrollbar;
-
- .notification {
- @include notification;
- }
- }
-}
-
-.notifications-popup-list{
- .notification {
- @include notification;
+.notifications-popup-list {
+ .notification {
+ @include notification;
- > box {
- @include floating_widget;
- border-radius: $radii;
- }
+ > box {
+ @include floating_widget;
+ border-radius: $radii;
+ }
- .description {
- min-width: 350px;
- }
- }
+ .description {
+ min-width: 350px;
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/powermenu.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/powermenu.scss
index 77d30db25..80a7018e4 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/powermenu.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/powermenu.scss
@@ -1,76 +1,88 @@
-window#powermenu, window#verification {
- .shader {
- min-width: 4000px;
- min-height: 4000px;
- background-color: rgba(0, 0, 0, 0.05);
- }
+window#powermenu,
+window#verification {
+ .shader {
+ background-color: rgba(0, 0, 0, 0.05);
+ }
}
window#verification .verification {
- @include floating_widget;
- padding: $popover_padding*1.2;
- min-width: 300px;
- min-height: 100px;
+ @include floating_widget;
+ padding: $popover_padding * 1.2;
+ min-width: 300px;
+ min-height: 100px;
- .title {
- font-size: 1.7em;
- }
+ .title {
+ font-size: 1.7em;
+ }
- .desc {
- color: transparentize($fg_color, 0.1);
- font-size: 1.2em;
- }
+ .desc {
+ color: transparentize($fg_color, 0.1);
+ font-size: 1.2em;
+ }
- .buttons {
- margin-top: $spacing*2;
+ .buttons {
+ margin-top: $spacing * 2;
- button {
- @include button;
- font-size: 1.6em;
- padding: $spacing;
- margin: 0 $popover_padding*1.2/2;
+ button {
+ @include button;
+ font-size: 1.6em;
+ padding: $spacing;
+ margin: 0 $popover_padding * 1.2/2;
- &:first-child {
- margin-left: 0;
- }
+ &:first-child {
+ margin-left: 0;
+ }
- &:last-child {
- margin-right: 0;
- }
- }
- }
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
}
window#powermenu .powermenu {
- @include floating_widget;
- padding: $popover_padding;
- border-radius: $radii*3;
+ @include floating_widget;
+ padding: $popover_padding;
+ border-radius: $radii * 3;
- button {
- @include common;
+ button {
+ @include common;
- image {
- @include button;
- margin: $popover_padding;
- margin-bottom: $popover_padding/2;
- border-radius: $radii*2;
- min-width: 120px;
- min-height: 120px;
- }
+ image {
+ @include button;
+ margin: $popover_padding;
+ margin-bottom: $popover_padding/2;
+ border-radius: $radii * 2;
+ min-width: 120px;
+ min-height: 120px;
+ font-size: 68px;
+ }
- label, image {
- color: transparentize($fg_color, 0.1);
- }
+ label,
+ image {
+ color: transparentize($fg_color, 0.1);
+ }
- &:hover {
- image { @include button_hover; }
- label{ color: $fg_color; }
- }
- &:focus image { @include button_focus; }
- &:active image { @include button_active; }
+ &:hover {
+ image {
+ @include button_hover;
+ }
+ label {
+ color: $fg_color;
+ }
+ }
+ &:focus image {
+ @include button_focus;
+ }
+ &:active image {
+ @include button_active;
+ }
- &:focus, &:active {
- label{ color: $accent; }
- }
- }
+ &:focus,
+ &:active {
+ label {
+ color: $accent;
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/quicksettings.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/quicksettings.scss
index 25d9b89b9..7150d78db 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/quicksettings.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/quicksettings.scss
@@ -1,243 +1,192 @@
window#quicksettings .quicksettings {
- @include floating_widget;
-
- .header {
- > box:last-child {
- @include widget;
- padding: $spacing;
- }
-
- .avatar {
- @include widget;
- margin-right: $spacing;
- min-width: $spacing*7 + 38px;
-
- .shader {
- @include shader;
- }
- }
-
- .user {
- font-size: 1.2em;
- color: transparentize($fg_color, 0.2);
- margin: $spacing/2;
- }
-
- .battery-progress {
- progressbar {
- @include slider($width: $spacing*3.4);
- margin-top: $spacing;
- }
-
- label {
- margin-top: $spacing;
- color: $accent_fg;
- font-size: $spacing*2;
- font-weight: bold;
- }
-
- &.half label { color: $fg_color; }
- }
-
- .system {
- button, .uptime {
- @include button;
- padding: $spacing;
- margin-left: $spacing;
- font-weight: bold;
- &:first-child { margin-left: 0; }
- }
- }
- }
-
- .volume-box {
- @include widget;
- margin-top: $spacing;
-
- scale {
- @include slider;
- margin-right: $spacing;
- }
-
- button {
- @include button($flat: true);
- padding: $spacing/2;
- margin: $spacing/2;
- }
-
- .menu {
- all: unset;
- border-top: 1px solid $widget_bg;
- padding: $spacing;
-
- .separator {
- min-height: 1px;
- margin: $spacing/2 0;
- background-color: $widget_bg;
- }
-
- button {
- @include button($flat: true);
- border-radius: $radii*.7;
- padding: $spacing/2;
- margin-top: $spacing / 2;
- &:first-child { margin-top: 0; }
-
- image {
- margin-right: $spacing/2;
- }
- }
- }
- }
-
- .brightness {
- @include widget;
- margin-top: $spacing;
- padding-right: $spacing;
-
- scale {
- @include slider;
- margin: 0 $spacing;
- margin-left: 0;
- }
-
- button {
- @include button($flat: true);
- padding: $spacing/2;
- margin: $spacing/2;
- }
- }
-
- .toggles-box {
- margin-top: $spacing;
-
- .small-toggles {
- @include widget;
- padding: $spacing/2;
-
- .toggle {
- @include button;
- margin: $spacing/2;
- padding: $spacing;
- }
- }
-
- .arrow-toggles {
- @include widget;
- padding: $spacing/2;
- margin-right: $spacing;
-
- .toggle.arrow {
- @include button;
- margin: $spacing/2;
-
- label {
- margin-left: $spacing/2;
- font-weight: bold;
- }
-
- button {
- @include button($flat: true);
- padding: $spacing;
-
- &:first-child {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- }
-
- &:last-child {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- }
- }
-
- &.active {
- background-color: $accent;
-
- label, image {
- color: $accent_fg;
- }
- }
- }
- }
- }
-
- .submenu {
- @include widget;
- margin-top: $spacing;
-
- .title {
- > *:first-child {
- margin: $spacing;
- }
-
- label {
- font-weight: bold;
- font-size: 1.2em;
- }
- }
-
- .content {
- border-top: 1px solid $widget_bg;
- padding: $spacing;
- }
-
- &.app-mixer .content {
- scale {
- @include slider;
- }
-
- > box {
- padding: $spacing;
- }
-
- label:last-child {
- min-width: 3em;
- }
-
- image {
- margin-right: $spacing;
- }
- }
-
- &.network .content, &.theme, .content {
- button {
- @include button($flat: true);
- border-radius: $radii*0.8;
- padding: $spacing/2;
- margin-top: $spacing / 2;
- &:first-child { margin-top: 0; }
- }
-
- image {
- margin-right: $spacing/2;
- }
- }
-
- &.bluetooth .content {
- > box {
- padding: $spacing/2;
- }
-
- switch {
- @include switch;
- }
- }
- }
-
- .media {
- .mediabox{
- @include widget;
- @include media;
- margin-top: $spacing;
-
- .cover-art-bg {
- border-radius: max($radii - $border_width, 0);
- }
-
- .shader {
- border-radius: max($radii - $border_width, 0);
- }
- }
- }
+ @include floating_widget;
+
+ .row {
+ margin-top: $spacing;
+ &:first-child {
+ margin-top: 0;
+ }
+ }
+
+ .header {
+ .avatar {
+ @include widget;
+ margin-right: $spacing;
+ min-width: $spacing * 7 + 38px;
+
+ .shader {
+ @include shader;
+ }
+ }
+
+ .battery-progress {
+ label {
+ margin-top: $spacing;
+ color: $accent_fg;
+ font-size: $spacing * 2;
+ font-weight: bold;
+ }
+
+ &.half label {
+ color: $fg_color;
+ }
+
+ progressbar {
+ @include slider($width: $spacing * 3.4);
+ margin-top: $spacing;
+ min-height: 20px;
+ }
+
+ &.low progressbar {
+ @include slider(
+ $width: $spacing * 3.4,
+ $gradient: linear-gradient(to right, $red, $red)
+ );
+ margin-top: $spacing;
+ min-height: 20px;
+ }
+ }
+
+ .system-box {
+ @include widget;
+ padding: $spacing;
+
+ button,
+ .uptime {
+ @include button;
+ padding: $spacing;
+ font-weight: bold;
+ margin-left: $spacing;
+ &:first-child {
+ margin-left: 0;
+ }
+ min-height: 20px;
+ min-width: 20px;
+
+ image {
+ font-size: 1.2em;
+ }
+ }
+ }
+ }
+
+ .slider-box {
+ @include widget;
+ padding: $spacing;
+
+ > box {
+ margin: 0;
+ }
+
+ .slider > * {
+ margin-left: $spacing;
+ &:first-child {
+ margin-left: 0;
+ }
+ }
+
+ button,
+ .icon {
+ @include button($flat: true);
+ padding: $spacing/2;
+ }
+
+ scale {
+ @include slider;
+
+ &:last-child {
+ margin-right: $spacing/2;
+ }
+ }
+
+ .menu {
+ background-color: $bg_color;
+ border: $border_width solid $popover_border_color;
+ border-radius: $radii;
+ }
+ }
+
+ .mixer-item {
+ margin: 0 $spacing;
+ scale {
+ @include slider($width: 7px);
+ }
+ > box {
+ padding: $spacing;
+ }
+ label:last-child {
+ min-width: 3em;
+ }
+ image {
+ font-size: 20px;
+ }
+ }
+
+ .menu {
+ @include widget;
+ margin-top: $spacing;
+ padding: $spacing;
+
+ separator {
+ background-color: $border_color;
+ margin: $spacing $spacing/2;
+ }
+
+ label {
+ margin-left: $spacing;
+ }
+
+ button {
+ @include button($flat: true);
+ padding: $spacing/2;
+ }
+
+ switch {
+ @include switch;
+ }
+ }
+
+ .toggle-button {
+ @include button;
+ margin-right: $spacing;
+ font-weight: bold;
+
+ label {
+ margin-left: $spacing/2;
+ }
+
+ button {
+ @include button($flat: true);
+ padding: $spacing;
+
+ &:first-child {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ &:last-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ }
+
+ &.active {
+ background-color: $accent;
+
+ label,
+ image {
+ color: $accent_fg;
+ }
+ }
+ }
+
+ .simple-toggle {
+ @include button;
+ padding: $spacing;
+ }
+
+ .media .player {
+ @include media;
+ margin-top: $spacing;
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/settings.scss b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/settings.scss
index 23ec629c2..f796b3332 100644
--- a/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/settings.scss
+++ b/home/isabel/programs/gui/confs/bars/ags/config/scss/widgets/settings.scss
@@ -1,99 +1,111 @@
window#settings {
- background-color: $bg_color;
- color: $fg_color;
-
- scrolledwindow {
- @include scrollbar;
- }
-
- .settings {
- .content {
- padding: $popover_padding;
- }
-
- .headerbar {
- background-color: $widget_bg;
- padding: $spacing/2;
- border-bottom: $border;
- }
-
- .tab {
- @include button($flat: true);
- margin: $spacing/2;
- padding: $spacing/2;
- }
-
- .wallpaper {
- border-radius: max($radii - 1px, 0);
- background-position: center;
- border: $border
- }
-
- button, entry {
- @include button;
- padding: $spacing*0.7;
- }
-
- spinbutton, spinbutton:focus {
- @include button;
-
- button, entry {
- all: unset;
- padding: $spacing*0.7;
-
- &:last-child {
- border-radius: 0 $radii $radii 0;
- }
-
- &:first-child {
- border-top: none;
- border-bottom: none;
- }
- }
- }
-
- switch {
- @include switch;
- }
-
- .row {
- margin-bottom: $spacing;
- &:last-child{ margin-bottom: 0; }
-
- label:first-child {
- margin-right: $spacing*5;
- }
-
- .color entry {
- margin-right: $spacing;
- min-width: 20em;
- }
-
- entry.text {
- min-width: 22em;
- }
-
- .text-spin {
- @include widget;
-
- button {
- @include button($flat: true);
- border-radius: 0;
- padding: $spacing/2;
- margin: -$border_width;
-
- &:last-child {
- border-radius: 0 $radii $radii 0;
- }
- }
- label { margin: 0 $spacing/2; }
- }
- }
-
- .disclaimer {
- padding: $spacing;
- padding-top: 0;
- color: transparentize($fg_color, 0.5);
- }
- }
+ background-color: $bg_color;
+ color: $fg_color;
+
+ scrolledwindow {
+ @include scrollbar;
+ }
+
+ .settings {
+ .content {
+ padding: $popover_padding;
+ }
+
+ .headerbar {
+ background-color: $widget_bg;
+ padding: $spacing/2;
+ border-bottom: $border;
+ }
+
+ .tab {
+ @include button($flat: true);
+ margin: $spacing/2;
+ padding: $spacing/2;
+ }
+
+ .wallpaper {
+ border-radius: max($radii - 1px, 0);
+ background-position: center;
+ border: $border;
+ }
+
+ button,
+ entry {
+ @include button;
+ padding: $spacing * 0.7;
+ }
+
+ spinbutton,
+ spinbutton:focus {
+ @include button;
+
+ button,
+ entry {
+ all: unset;
+ padding: $spacing * 0.7;
+
+ &:last-child {
+ border-radius: 0 $radii $radii 0;
+ }
+
+ &:first-child {
+ border-top: none;
+ border-bottom: none;
+ }
+ }
+ }
+
+ switch {
+ @include switch;
+ }
+
+ .row {
+ margin-bottom: $spacing;
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ label:first-child {
+ margin-right: $spacing * 5;
+ }
+
+ .color entry {
+ margin-right: $spacing;
+ min-width: 20em;
+ }
+
+ entry.text {
+ min-width: 22em;
+ }
+
+ .text-spin {
+ @include widget;
+
+ button {
+ @include button($flat: true);
+ border-radius: 0;
+ padding: $spacing/2;
+ margin: -$border_width;
+
+ &:last-child {
+ border-radius: 0 $radii $radii 0;
+ }
+ }
+ label {
+ margin: 0 $spacing/2;
+ }
+ }
+
+ label,
+ entry {
+ font-size: $font_size;
+ }
+ }
+
+ .disclaimer {
+ padding: $spacing;
+ padding-top: 0;
+ color: transparentize($fg_color, 0.5);
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/theme/dialog.js b/home/isabel/programs/gui/confs/bars/ags/config/theme/dialog.js
deleted file mode 100644
index aa1cac742..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/theme/dialog.js
+++ /dev/null
@@ -1,244 +0,0 @@
-import Gtk from 'gi://Gtk';
-import { Theme } from './theme.js';
-import themes from './themes.js';
-import { Wallpaper } from '../modules/wallpaper.js';
-const { Box, Stack, Label, Icon, Button, Scrollable, Entry, Widget } = ags.Widget;
-
-const Row = (title, child) => Box({
- className: 'row',
- children: [Label(`${title}: `), child],
-});
-
-const Img = (title, prop) => Row(title, Widget({
- title,
- type: Gtk.FileChooserButton,
- hexpand: true,
- halign: 'end',
- connections: [['selection-changed',
- w => Theme.setSetting(prop, w.get_uri().replace('file://', ''))]],
-}));
-
-const SpinButton = (title, prop, max = 100, min = 0) => Row(title, Widget({
- type: Gtk.SpinButton,
- setup: w => {
- w.set_range(min, max);
- w.set_increments(1, 1);
- },
- hexpand: true,
- halign: 'end',
- connections: [
- ['value-changed', b => !b._block && Theme.setSetting(prop, b.value)],
- [Theme, b => {
- b._block = true;
- b.value = Theme.getSetting(prop);
- b._block = false;
- }],
- ],
-}));
-
-const SwitchButton = (title, prop) => Row(title, Widget({
- type: Gtk.Switch,
- halign: 'end',
- hexpand: true,
- connections: [
- [Theme, s => {
- s._block = true;
- s.active = Theme.getSetting(prop);
- s._block = false;
- }],
- ['notify::active', s => !s._block && Theme.setSetting(prop, s.active)],
- ],
-}));
-
-const Color = (title, prop) => Row(title, Box({
- hexpand: true,
- halign: 'end',
- className: 'color',
- children: [
- Entry({
- onAccept: ({ text }) => Theme.setSetting(prop, text),
- valign: 'center',
- connections: [[Theme, w => w.text = Theme.getSetting(prop)]],
- }),
- Widget({
- type: Gtk.ColorButton,
- alpha: true,
- valign: 'center',
- connections: [
- ['color-set', w => {
- w.get_parent().children[0].set_text(w.rgba.to_string());
- Theme.setSetting(prop, w.rgba.to_string());
- }],
- ],
- }),
- ],
-}));
-
-const Text = (title, prop) => Row(title, Entry({
- className: 'text',
- hexpand: true,
- halign: 'end',
- connections: [[Theme, w => w.text = Theme.getSetting(prop)]],
- onAccept: ({ text }) => Theme.setSetting(prop, text),
-}));
-
-const TextSpinButton = (title, prop, list) => Row(title, Box({
- className: 'text-spin',
- hexpand: true,
- halign: 'end',
- properties: [
- ['values', list],
- ['step', (box, step) => {
- const label = box.get_children()[0];
- const max = box._values.length - 1;
- let index = box._values.indexOf(label.label) + step;
-
- if (index > max)
- index = 0;
-
- if (index < 0)
- index = max;
-
- const value = box._values[index];
- label.label = value;
- Theme.setSetting(prop, value);
- }],
- ],
- children: [
- Label({
- connections: [[Theme, label => label.label = Theme.getSetting(prop)]],
- }),
- Button({
- child: Icon('pan-down-symbolic'),
- onClicked: btn => {
- const box = btn.get_parent();
- box._step(box, -1);
- },
- }),
- Button({
- child: Icon('pan-up-symbolic'),
- onClicked: btn => {
- const box = btn.get_parent();
- box._step(box, +1);
- },
- }),
- ],
-}));
-
-class Pages extends ags.Service {
- static { ags.Service.register(this); }
- static instance = new Pages();
- static page = ' General';
- static show(page) {
- Pages.page = page;
- Pages.instance.emit('changed');
- }
-}
-
-const Tab = page => Button({
- hexpand: true,
- className: 'tab',
- onClicked: () => Pages.show(page),
- child: Label(page),
- connections: [[Pages, b => b.toggleClassName('active', Pages.page === page)]],
-});
-
-const Layout = pages => Box({
- vertical: true,
- className: 'settings',
- hexpand: false,
- children: [
- Box({
- className: 'headerbar',
- valign: 'start',
- children: [Box({
- className: 'tabs',
- children: [
- ...Object.keys(pages).map(page => Tab(page)),
- Button({
- className: 'tab',
- onClicked: Theme.reset,
- child: Label(' Reset'),
- hexpand: true,
- }),
- ],
- })],
- }),
- Box({
- className: 'content',
- children: [Stack({
- transition: 'slide_left_right',
- items: Object.keys(pages).map(page => [page, pages[page]]),
- connections: [[Pages, stack => {
- stack.shown = Pages.page;
- }]],
- })],
- }),
- Label({
- wrap: true,
- className: 'disclaimer',
- label: 'These settings override all preset themes. ' +
- 'To make them permanent: edit ~/.config/ags/theme/themes.js',
- }),
- ],
-});
-
-const Page = children => Scrollable({
- child: Box({
- vertical: true,
- children,
- }),
-});
-
-export const SettingsDialog = () => Widget({
- type: Gtk.Window,
- name: 'settings',
- child: Layout({
- ' General': Page([
- Wallpaper({
- className: 'row',
- hexpand: true,
- vexpand: true,
- }),
- Img('Wallpaper', 'wallpaper'),
- Img('Avatar', 'avatar'),
- SpinButton('Useless Gaps', 'wm_gaps', 128),
- SpinButton('Spacing', 'spacing', 18),
- SpinButton('Roundness', 'radii', 36),
- TextSpinButton('Layout', 'layout', ['topbar', 'leftbar']),
- TextSpinButton('Bar Style', 'bar_style', ['normal', 'floating', 'separated']),
- SwitchButton('Screen Corners', 'screen_corners'),
- ]),
- ' Colors': Page([
- Color('Background Color', 'bg_color'),
- Color('Foreground Color', 'fg_color'),
- Color('Hovered Foreground Color', 'hover_fg'),
- Color('Accent Color', 'accent'),
- Color('Accent Foreground', 'accent_fg'),
- Color('Widget Background', 'widget_bg'),
- TextSpinButton('Color Theme', 'color_scheme', ['light', 'dark']),
- ...['Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Teal', 'Orange']
- .map(c => Color(c, c.toLowerCase())),
- ]),
- ' Theme': Page([
- TextSpinButton('Theme', 'theme', themes.map(t => t.name)),
- Text('Active Gradient', 'active_gradient'),
- SpinButton('Widget Opacity', 'widget_opacity'),
- Color('Border Color', 'border_color'),
- SpinButton('Border Width', 'border_width'),
- SpinButton('Border Opacity', 'border_opacity'),
- ]),
- ' Miscellaneous': Page([
- Color('Shadow', 'shadow'),
- SwitchButton('Drop Shadow', 'drop_shadow'),
- SpinButton('Transition', 'transition', 1000),
- Text('Desktop Clock Position', 'desktop_clock'),
- Color('Wallpaper Foreground Color', 'wallpaper_fg'),
- ]),
- }),
- connections: [['delete-event', win => {
- win.hide();
- return true;
- }]],
- setup: win => win.set_default_size(700, 600),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/theme/hyprland.js b/home/isabel/programs/gui/confs/bars/ags/config/theme/hyprland.js
deleted file mode 100644
index f4f1b6841..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/theme/hyprland.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import App from 'resource:///com/github/Aylur/ags/app.js';
-import Service from 'resource:///com/github/Aylur/ags/service/service.js';
-import { execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
-
-export function setupHyprland() {
- try {
- App.instance.connect('config-parsed', () => {
- for (const [name] of App.windows) {
- if (!name.includes('desktop') && name !== 'verification' && name !== 'powermenu') {
- execAsync(['hyprctl', 'keyword', 'layerrule', `unset, ${name}`]).then(() => {
- execAsync(['hyprctl', 'keyword', 'layerrule', `blur, ${name}`]);
- execAsync(['hyprctl', 'keyword', 'layerrule', `ignorealpha 0.6, ${name}`]);
- });
- }
- }
-
- for (const name of ['verification', 'powermenu'])
- execAsync(['hyprctl', 'keyword', 'layerrule', `blur, ${name}`]);
- });
- } catch (error) {
- logError(error);
- }
-}
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/theme/theme.js b/home/isabel/programs/gui/confs/bars/ags/config/theme/theme.js
deleted file mode 100644
index ccec51cd8..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/theme/theme.js
+++ /dev/null
@@ -1,165 +0,0 @@
-import { FontIcon } from '../modules/misc.js';
-import { setupScss } from './scss.js';
-import { setupHyprland } from './hyprland.js';
-import themes from './themes.js';
-import App from 'resource:///com/github/Aylur/ags/app.js';
-import Service from 'resource:///com/github/Aylur/ags/service/service.js';
-import { USER, exec, execAsync, readFile, writeFile } from 'resource:///com/github/Aylur/ags/utils.js';
-import { Stack, Box, Icon, Label, Button } from 'resource:///com/github/Aylur/ags/widget.js';
-import { SettingsDialog } from './dialog.js';
-
-class ThemeService extends Service {
- static { Service.register(this); }
-
- _settingsPath = App.configDir + '/settings.json';
- _defaultAvatar = `/home/${USER}/media/pictures/pfps/avatar`;
- _defaultTheme = themes[0].name;
-
- constructor() {
- super();
- exec('swww init');
- this.setup();
- }
-
- openSettings() {
- if (!this._dialog)
- this._dialog = SettingsDialog();
-
- this._dialog.hide();
- this._dialog.show_all();
- }
-
- getTheme() {
- return themes.find(({ name }) => name === this.getSetting('theme'));
- }
-
- setup() {
- const theme = {
- ...this.getTheme(),
- ...this.settings,
- };
- setupScss(theme);
- setupHyprland();
- this.setupOther();
- this.setupWallpaper();
- }
-
- setupOther() {
- const darkmode = this.getSetting('color_scheme') === 'dark';
-
- execAsync(`gsettings set org.gnome.desktop.interface color-scheme "prefer-${darkmode ? 'dark' : 'light'}"`).catch(print);
- }
-
- setupWallpaper() {
- execAsync([
- 'swww', 'img',
- this.getSetting('wallpaper'),
- ]).catch(print);
- }
-
- reset() {
- exec(`rm ${this._settingsPath}`);
- this._settings = null;
- this.setup();
- this.emit('changed');
- }
-
- get settings() {
- if (this._settings)
- return this._settings;
-
- try {
- this._settings = JSON.parse(readFile(this._settingsPath));
- } catch (_) {
- this._settings = {};
- }
-
- return this._settings;
- }
-
- setSetting(prop, value) {
- const settings = this.settings;
- settings[prop] = value;
- writeFile(JSON.stringify(settings, null, 2), this._settingsPath).catch(print);
- this._settings = settings;
- this.emit('changed');
-
- if (prop === 'layout') {
- if (!this._notiSent) {
- this._notiSent = true;
- execAsync(['notify-send', 'Layout Change Needs a Reload']);
- }
- return;
- }
-
- this.setup();
- }
-
- getSetting(prop) {
- if (prop === 'theme')
- return this.settings.theme || this._defaultTheme;
-
- if (prop === 'avatar')
- return this.settings.avatar || this._defaultAvatar;
-
- return this.settings[prop] !== undefined
- ? this.settings[prop]
- : this.getTheme()[prop];
- }
-}
-
-export class Theme {
- static { Service.export(this, 'Theme'); }
- static instance = new ThemeService();
- static get themes() { return themes; }
-
- static reset() { Theme.instance.reset(); }
- static openSettings() { Theme.instance.openSettings(); }
- static getSetting(prop) { return Theme.instance.getSetting(prop); }
- static setSetting(prop, value) { return Theme.instance.setSetting(prop, value); }
-}
-
-export const Indicator = props => Stack({
- ...props,
- transition: 'crossfade',
- items: themes.map(({ name, icon }) =>
- [name, FontIcon({ icon })]),
- connections: [[Theme, stack => stack.shown = Theme.getSetting('theme')]],
-});
-
-export const Toggle = props => Button({
- ...props,
- className: 'active',
- properties: [
- ['list', themes],
- ['current', Theme.getSetting('theme')],
- ],
- onClicked: btn => {
- let index = btn._list.indexOf(btn._current) + 1;
- if (index > btn._list.length)
- index = 0;
-
- btn._current = btn._list[index];
- Theme.setSetting('theme', btn._current);
- },
-});
-
-export const Selector = props => Box({
- ...props,
- vertical: true,
- children: themes.map(({ name, icon }) => Button({
- onClicked: () => Theme.setSetting('theme', name),
- child: Box({
- children: [
- FontIcon({ icon }),
- Label(name.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')),
- Icon({
- icon: 'object-select-symbolic',
- hexpand: true,
- halign: 'end',
- connections: [[Theme, icon => icon.visible = Theme.getSetting('theme') === name]],
- }),
- ],
- }),
- })),
-});
diff --git a/home/isabel/programs/gui/confs/bars/ags/config/theme/themes.js b/home/isabel/programs/gui/confs/bars/ags/config/theme/themes.js
deleted file mode 100644
index a2d57ee26..000000000
--- a/home/isabel/programs/gui/confs/bars/ags/config/theme/themes.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// common
-const WP = `/home/${ags.Utils.USER}/media/pictures/wallpapers/`;
-
-const mocha_colors = {
- bg_color: '#1e1e2e',
- fg_color: '#cdd6f4',
- hover_fg: '#cdd6f4',
- red: '#f38ba8',
- green: '#a6e3a1',
- yellow: '#f9e2af',
- blue: '#74c7ec',
- magenta: '#cba6f7',
- teal: '#94e2d5',
- orange: '#fab387',
-};
-
-const latte_colors = {
- bg_color: '#eff1f5',
- fg_color: '#4c4f69',
- hover_fg: '#4c4f69',
- red: '#d20f39',
- green: '#40a02b',
- yellow: '#df8e1d',
- blue: '#209fb5',
- magenta: '#8839ef',
- teal: '#179299',
- orange: '#fe640b',
-};
-
-const settings = {
- wm_gaps: 8,
- radii: 9,
- spacing: 9,
- drop_shadow: true,
- transition: 200,
- screen_corners: false,
- bar_style: 'normal',
- layout: 'topbar',
- border_opacity: 97,
- border_width: 1,
- widget_opacity: 94,
-};
-
-const misc_colors = {
- shadow: 'rgba(0, 0, 0, .6)',
- accent: '$blue',
- accent_fg: '$bg_color',
- widget_bg: '$fg_color',
- active_gradient: 'to right, $accent, lighten($accent, 6%)',
- border_color: '$fg_color',
-};
-
-// themes
-const mocha = {
- wallpaper: WP + 'tempest.png',
- name: 'mocha',
- color_scheme: 'dark',
- icon: '',
- ...mocha_colors,
- ...settings,
- ...misc_colors,
-};
-
-const latte = {
- wallpaper: WP + 'coke.jpg',
- name: 'latte',
- color_scheme: 'light',
- icon: '',
- ...latte_colors,
- ...settings,
- ...misc_colors,
-};
-
-export default [
- mocha,
- latte,
-];
diff --git a/home/isabel/programs/gui/confs/bars/ags/default.nix b/home/isabel/programs/gui/confs/bars/ags/default.nix
index c4b488fbd..17b2faa3c 100644
--- a/home/isabel/programs/gui/confs/bars/ags/default.nix
+++ b/home/isabel/programs/gui/confs/bars/ags/default.nix
@@ -4,31 +4,30 @@
config,
osConfig,
defaults,
+ inputs',
...
}: let
- inherit (lib) mkIf;
- device = osConfig.modules.device;
+ inherit (osConfig.modules) system;
acceptedTypes = ["desktop" "laptop" "hybrid"];
- programs = osConfig.modules.programs;
- sys = osConfig.modules.system;
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable && defaults.bar == "ags") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && (lib.isWayland osConfig) && osConfig.modules.programs.gui.enable && defaults.bar == "ags") {
home = {
packages = with pkgs; [
- nur.repos.bella.ags
+ inputs'.ags.packages.default
socat
sassc
networkmanagerapplet
+ inotify-tools
swww
];
};
xdg.configFile = let
symlink = fileName: {recursive ? false}: {
- source = config.lib.file.mkOutOfStoreSymlink "${sys.flakePath}/${fileName}";
+ source = config.lib.file.mkOutOfStoreSymlink "${system.flakePath}/${fileName}";
inherit recursive;
};
in {
- "ags" = symlink "home/${sys.mainUser}/programs/gui/confs/bars/ags/config" {
+ "ags" = symlink "home/${system.mainUser}/programs/gui/confs/bars/ags/config" {
recursive = true;
};
};
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/eww.scss b/home/isabel/programs/gui/confs/bars/eww/config/eww.scss
index 2291604bf..5087cc383 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/eww.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/eww.scss
@@ -26,5 +26,5 @@
@import "./scss/windows/screenshot.scss";
tooltip {
- @include tooltip
-}
\ No newline at end of file
+ @include tooltip;
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/apps b/home/isabel/programs/gui/confs/bars/eww/config/scripts/apps
index a8a348a00..a729cacb9 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/apps
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/apps
@@ -1,11 +1,12 @@
#!/usr/bin/env bash
function query {
- dbus-send --session --type=method_call \
- --dest=com.github.isabel.host \
- /com/github/isabel/applications \
- com.github.isabel.applications.Query \
- string:$1
+ dbus-send --session --type=method_call \
+ --dest=com.github.isabel.host \
+ /com/github/isabel/applications \
+ com.github.isabel.applications.Query \
+ string:$1
}
if [[ $1 == 'query' ]]; then query $2; fi
+
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/bluetooth b/home/isabel/programs/gui/confs/bars/eww/config/scripts/bluetooth
index c0439eba3..e609f10d5 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/bluetooth
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/bluetooth
@@ -1,14 +1,15 @@
#!/usr/bin/env bash
function state {
- STATE=$(bluetoothctl show | grep 'Powered' | awk '{print $2}')
- if [[ $STATE == 'yes' ]]; then echo 'on'
- else echo 'off'; fi
+ STATE=$(bluetoothctl show | grep 'Powered' | awk '{print $2}')
+ if [[ $STATE == 'yes' ]]; then echo 'on'
+ else echo 'off'; fi
}
function toggle {
- if [[ $(state) = 'on' ]]; then bluetoothctl power off
- else bluetoothctl power on; fi
+ if [[ $(state) = 'on' ]]; then bluetoothctl power off
+ else bluetoothctl power on; fi
}
-if [[ $1 == 'toggle' ]]; then toggle; fi
\ No newline at end of file
+if [[ $1 == 'toggle' ]]; then toggle; fi
+
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/brightness b/home/isabel/programs/gui/confs/bars/eww/config/scripts/brightness
index 057057331..a2702791c 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/brightness
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/brightness
@@ -32,8 +32,8 @@ function set_screen {
function get {
echo "{
- \"screen\": { \"level\": \"$(screen_level)\", \"icon\": \"$(screen_icon)\" }
- }"
+ \"screen\": { \"level\": \"$(screen_level)\", \"icon\": \"$(screen_icon)\" }
+ }"
}
if [[ $1 == 'get' ]]; then get; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/events b/home/isabel/programs/gui/confs/bars/eww/config/scripts/events
index 3204f407a..c858478fb 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/events
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/events
@@ -1,14 +1,14 @@
#!/usr/bin/env bash
if [ ! -f "$HOME/.local/bin/todo" ]; then
- exit 0
+ exit 0
fi
if [[ $1 == 'get' ]]; then
- $HOME/.local/bin/todo -j | jq -c
+ $HOME/.local/bin/todo -j | jq -c
- while true; do
- inotifywait -q -e modify $HOME/Documents/todos.json
- $HOME/.local/bin/todo -j | jq -c
- done
+ while true; do
+ inotifywait -q -e modify $HOME/Documents/todos.json
+ $HOME/.local/bin/todo -j | jq -c
+ done
fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/apps.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/apps.js
index cd430279c..1f81d0f28 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/apps.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/apps.js
@@ -1,106 +1,119 @@
-import { ApplicationsIFace } from "./dbus.js"
-import { MkDirectory, APPICON_CACHE_PATH } from './main.js'
-import { Gio, GObject, Gtk } from './lib.js'
-
-export const Apps = GObject.registerClass({
- Signals: { 'sync': {} }
-},
- class Apps extends GObject.Object {
- constructor() {
- super();
-
- this._register();
- }
-
- get json() {
- return this._list;
- }
-
- _iconPath(icon) {
- return APPICON_CACHE_PATH + icon + '.png';
- }
-
- init() {
- this._initIcons();
- this.Query('');
- }
-
- _initIcons() {
- MkDirectory();
- let icons = [];
- Gio.AppInfo.get_all()
- .forEach(app => {
- if (!app.should_show() || !app.get_icon()) return;
- if (typeof app.get_icon().get_names !== 'function') return;
- app?.get_icon()?.get_names()
- .forEach(icon => icons.push(icon))
- });
-
- icons.forEach(icon => {
- if (icon.includes('-symbolic')) return;
- let iconInfo = Gtk.IconTheme.get_default()
- .lookup_by_gicon(
- Gio.Icon.new_for_string(icon), 128, null);
-
- if (!iconInfo) return;
-
- let output_stream =
- Gio.File.new_for_path(this._iconPath(icon))
- .replace(null, false, Gio.FileCreateFlags.NONE, null);
-
- iconInfo.load_icon()
- .save_to_streamv(output_stream, 'png', null, null, null);
-
- output_stream.close(null);
- })
- }
-
- _appIconName(app) {
- if (!app.get_icon())
- return '';
-
- if (typeof app.get_icon().get_names !== 'function')
- return '';
-
- let name = app.get_icon().get_names()[0];
- return name ? this._iconPath(name) : '';
- }
-
- Query(search) {
- let apps = Gio.AppInfo.get_all();
- let list = [];
- apps.forEach(app => {
- if (!app.should_show()) return;
- if (app.get_name()?.toLowerCase().includes(search)) list.push(app);
- else if (app.get_id()?.toLowerCase().includes(search)) list.push(app);
- else if (app.get_executable()?.toLowerCase().includes(search)) list.push(app);
- else if (app.get_description()?.toLowerCase().includes(search)) list.push(app);
- });
-
- let outList = [];
- list.forEach(app => {
- outList.push({
- name: app.get_name(),
- desktop: app.get_id(),
- description: app.get_description(),
- icon: this._appIconName(app),
- })
- })
- this._list = outList;
- this.emit('sync');
- }
-
- _register() {
- Gio.bus_own_name(
- Gio.BusType.SESSION,
- 'com.github.isabel.host',
- Gio.BusNameOwnerFlags.NONE,
- (connection, _) => {
- this._dbus = Gio.DBusExportedObject.wrapJSObject(ApplicationsIFace, this);
- this._dbus.export(connection, '/com/github/isabel/applications');
- },
- null,
- null,
- );
- }
- })
+import { ApplicationsIFace } from "./dbus.js";
+import { MkDirectory, APPICON_CACHE_PATH } from "./main.js";
+import { Gio, GObject, Gtk } from "./lib.js";
+
+export const Apps = GObject.registerClass(
+ {
+ Signals: { sync: {} },
+ },
+ class Apps extends GObject.Object {
+ constructor() {
+ super();
+
+ this._register();
+ }
+
+ get json() {
+ return this._list;
+ }
+
+ _iconPath(icon) {
+ return APPICON_CACHE_PATH + icon + ".png";
+ }
+
+ init() {
+ this._initIcons();
+ this.Query("");
+ }
+
+ _initIcons() {
+ MkDirectory();
+ let icons = [];
+ Gio.AppInfo.get_all().forEach((app) => {
+ if (!app.should_show() || !app.get_icon()) return;
+ if (typeof app.get_icon().get_names !== "function") return;
+ app?.get_icon()
+ ?.get_names()
+ .forEach((icon) => icons.push(icon));
+ });
+
+ icons.forEach((icon) => {
+ if (icon.includes("-symbolic")) return;
+ let iconInfo = Gtk.IconTheme.get_default().lookup_by_gicon(
+ Gio.Icon.new_for_string(icon),
+ 128,
+ null,
+ );
+
+ if (!iconInfo) return;
+
+ let output_stream = Gio.File.new_for_path(
+ this._iconPath(icon),
+ ).replace(null, false, Gio.FileCreateFlags.NONE, null);
+
+ iconInfo
+ .load_icon()
+ .save_to_streamv(output_stream, "png", null, null, null);
+
+ output_stream.close(null);
+ });
+ }
+
+ _appIconName(app) {
+ if (!app.get_icon()) return "";
+
+ if (typeof app.get_icon().get_names !== "function") return "";
+
+ let name = app.get_icon().get_names()[0];
+ return name ? this._iconPath(name) : "";
+ }
+
+ Query(search) {
+ let apps = Gio.AppInfo.get_all();
+ let list = [];
+ apps.forEach((app) => {
+ if (!app.should_show()) return;
+ if (app.get_name()?.toLowerCase().includes(search))
+ list.push(app);
+ else if (app.get_id()?.toLowerCase().includes(search))
+ list.push(app);
+ else if (app.get_executable()?.toLowerCase().includes(search))
+ list.push(app);
+ else if (app.get_description()?.toLowerCase().includes(search))
+ list.push(app);
+ });
+
+ let outList = [];
+ list.forEach((app) => {
+ outList.push({
+ name: app.get_name(),
+ desktop: app.get_id(),
+ description: app.get_description(),
+ icon: this._appIconName(app),
+ });
+ });
+ this._list = outList;
+ this.emit("sync");
+ }
+
+ _register() {
+ Gio.bus_own_name(
+ Gio.BusType.SESSION,
+ "com.github.isabel.host",
+ Gio.BusNameOwnerFlags.NONE,
+ (connection, _) => {
+ this._dbus = Gio.DBusExportedObject.wrapJSObject(
+ ApplicationsIFace,
+ this,
+ );
+ this._dbus.export(
+ connection,
+ "/com/github/isabel/applications",
+ );
+ },
+ null,
+ null,
+ );
+ }
+ },
+);
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/battery.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/battery.js
index 098e293f8..f1b66690d 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/battery.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/battery.js
@@ -1,62 +1,77 @@
-import { GObject, Gio, UPowerGlib } from './lib.js'
-import { PowerManagerProxy } from './dbus.js'
-
-export const Battery = GObject.registerClass({
- Signals: { 'sync': {} }
-},
-class Battery extends GObject.Object{
- constructor(){
- super();
-
- this._json = {};
- this._proxy = new PowerManagerProxy(
- Gio.DBus.system,
- 'org.freedesktop.UPower',
- '/org/freedesktop/UPower/devices/DisplayDevice',
- () => {
- this._proxy.connect(
- 'g-properties-changed', () => this._sync() );
- this._sync();
- }
- );
- }
-
- get json(){
- return this._json;
- }
-
- _sync(){
- if(!this._proxy.IsPresent) return { available: false };
-
- let percent = this._proxy.Percentage;
- let charging = this._proxy.State === UPowerGlib.DeviceState.CHARGING;
- let charged =
- this._proxy.State === UPowerGlib.DeviceState.FULLY_CHARGED ||
- (this._proxy.State === UPowerGlib.DeviceState.CHARGING && percent === 100);
-
-
- let icons = ['', '', '', '', '', '', '', '', '', ''];
- let charging_icons = ['', '', '', '', '', '', '', '', '', ''];
- let i = Math.round(percent / 10)-1;
- if(i < 0) i = 0;
-
- let icon;
- if(charged) icon = '';
- else if(charging) icon = charging_icons[i];
- else if(percent < 10) icon = '';
- else icon = icons[i];
-
- let state = '';
- if(charged) state = 'charged';
- else if(charging) state = 'charging';
- else if(percent < 30) state = 'low';
-
- this._json = {
- available: true,
- icon,
- percent,
- state
- };
- this.emit('sync');
- }
-});
+import { GObject, Gio, UPowerGlib } from "./lib.js";
+import { PowerManagerProxy } from "./dbus.js";
+
+export const Battery = GObject.registerClass(
+ {
+ Signals: { sync: {} },
+ },
+ class Battery extends GObject.Object {
+ constructor() {
+ super();
+
+ this._json = {};
+ this._proxy = new PowerManagerProxy(
+ Gio.DBus.system,
+ "org.freedesktop.UPower",
+ "/org/freedesktop/UPower/devices/DisplayDevice",
+ () => {
+ this._proxy.connect("g-properties-changed", () =>
+ this._sync(),
+ );
+ this._sync();
+ },
+ );
+ }
+
+ get json() {
+ return this._json;
+ }
+
+ _sync() {
+ if (!this._proxy.IsPresent) return { available: false };
+
+ let percent = this._proxy.Percentage;
+ let charging =
+ this._proxy.State === UPowerGlib.DeviceState.CHARGING;
+ let charged =
+ this._proxy.State === UPowerGlib.DeviceState.FULLY_CHARGED ||
+ (this._proxy.State === UPowerGlib.DeviceState.CHARGING &&
+ percent === 100);
+
+ let icons = ["", "", "", "", "", "", "", "", "", ""];
+ let charging_icons = [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ];
+ let i = Math.round(percent / 10) - 1;
+ if (i < 0) i = 0;
+
+ let icon;
+ if (charged) icon = "";
+ else if (charging) icon = charging_icons[i];
+ else if (percent < 10) icon = "";
+ else icon = icons[i];
+
+ let state = "";
+ if (charged) state = "charged";
+ else if (charging) state = "charging";
+ else if (percent < 30) state = "low";
+
+ this._json = {
+ available: true,
+ icon,
+ percent,
+ state,
+ };
+ this.emit("sync");
+ }
+ },
+);
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/bluetooth.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/bluetooth.js
index c5c7a6279..f1d7d5517 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/bluetooth.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/bluetooth.js
@@ -1,108 +1,122 @@
-import { GObject, GnomeBluetooth } from './lib.js'
+import { GObject, GnomeBluetooth } from "./lib.js";
const STATES = {
- [GnomeBluetooth.AdapterState.ABSENT]: 'absent',
- [GnomeBluetooth.AdapterState.ON]: 'on',
- [GnomeBluetooth.AdapterState.TURNING_ON]: 'on',
- [GnomeBluetooth.AdapterState.OFF]: 'off',
- [GnomeBluetooth.AdapterState.TURNING_OFF]: 'off',
-}
+ [GnomeBluetooth.AdapterState.ABSENT]: "absent",
+ [GnomeBluetooth.AdapterState.ON]: "on",
+ [GnomeBluetooth.AdapterState.TURNING_ON]: "on",
+ [GnomeBluetooth.AdapterState.OFF]: "off",
+ [GnomeBluetooth.AdapterState.TURNING_OFF]: "off",
+};
const ICONS = {
- absent: '',
- off: '',
- on: '',
- 'audio-headset': '',
-}
-
-export const Bluetooth = GObject.registerClass({
- Signals: { 'sync': {} }
-},
-class Bluetooth extends GObject.Object{
- constructor() {
- super();
-
- this._json = {};
- this._devices = new Map();
- this._connections = new Map();
- this._client = new GnomeBluetooth.Client();
- this._client.connect('notify::default-adapter-state', this._sync.bind(this));
- this._client.connect('device-added', this._deviceAdded.bind(this));
- this._client.connect('device-removed', this._deviceRemoved.bind(this));
- this._getDevices().forEach(device => this._deviceAdded(_, device));
- this._sync();
- }
-
- get json() { return this._json }
-
- _deviceAdded(_, device) {
- if(this._devices.has(device.address)) return;
-
- let connections = [];
- [
- 'address',
- 'alias',
- 'battery-level',
- 'battery-percentage',
- 'connected',
- 'icon',
- 'name',
- 'paired',
- 'truested'
- ]
- .forEach(prop => connections.push(
- device.connect(`notify::${prop}`, this._sync.bind(this))
- ));
- this._connections.set(device.address, connections);
-
- this._devices.set(device.address, device);
- this._sync();
- }
-
- _deviceRemoved(_, device) {
- if(!this._devices.has(device.address)) return;
-
- this._connections.get(device.address).forEach(id => device.disconnect(id));
- this._connections.delete(device.address);
- this._devices.delete(device.address);
- this._sync();
- }
-
- _getDevices() {
- let devices = [];
- const deviceStore = this._client.get_devices();
-
- for(let i=0; i
+ this._deviceAdded(_, device),
+ );
+ this._sync();
}
-
- return devices;
- }
-
- _sync() {
- this._json.state = STATES[this._client.default_adapter_state];
- this._json.icon = ICONS[this._json.state];
- this._json.connected_devices = [];
- this._json.devices = [];
- for (const [_, device] of this._devices) {
- let item = {
- address: device.address,
- alias: device.alias,
- battery_level: device.battery_level,
- battery_percentage: device.battery_percentage,
- connected: device.connected,
- icon: ICONS[device.icon],
- name: device.name,
- paired: device.paired,
- trusted: device.trusted
- };
- this._json.devices.push(item);
- if(device.connected) this._json.connected_devices.push(item);
+
+ get json() {
+ return this._json;
}
- this.emit('sync');
- }
-})
+ _deviceAdded(_, device) {
+ if (this._devices.has(device.address)) return;
+
+ let connections = [];
+ [
+ "address",
+ "alias",
+ "battery-level",
+ "battery-percentage",
+ "connected",
+ "icon",
+ "name",
+ "paired",
+ "truested",
+ ].forEach((prop) =>
+ connections.push(
+ device.connect(`notify::${prop}`, this._sync.bind(this)),
+ ),
+ );
+ this._connections.set(device.address, connections);
+
+ this._devices.set(device.address, device);
+ this._sync();
+ }
+
+ _deviceRemoved(_, device) {
+ if (!this._devices.has(device.address)) return;
+
+ this._connections
+ .get(device.address)
+ .forEach((id) => device.disconnect(id));
+ this._connections.delete(device.address);
+ this._devices.delete(device.address);
+ this._sync();
+ }
+
+ _getDevices() {
+ let devices = [];
+ const deviceStore = this._client.get_devices();
+
+ for (let i = 0; i < deviceStore.get_n_items(); ++i) {
+ const device = deviceStore.get_item(i);
+
+ if (device.paired || device.trusted) devices.push(device);
+ }
+
+ return devices;
+ }
+
+ _sync() {
+ this._json.state = STATES[this._client.default_adapter_state];
+ this._json.icon = ICONS[this._json.state];
+ this._json.connected_devices = [];
+ this._json.devices = [];
+ for (const [_, device] of this._devices) {
+ let item = {
+ address: device.address,
+ alias: device.alias,
+ battery_level: device.battery_level,
+ battery_percentage: device.battery_percentage,
+ connected: device.connected,
+ icon: ICONS[device.icon],
+ name: device.name,
+ paired: device.paired,
+ trusted: device.trusted,
+ };
+ this._json.devices.push(item);
+ if (device.connected) this._json.connected_devices.push(item);
+ }
+
+ this.emit("sync");
+ }
+ },
+);
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/dbus.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/dbus.js
index 4e01573fc..30c6bbe8a 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/dbus.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/dbus.js
@@ -1,7 +1,7 @@
-import { Gio } from './lib.js'
+import { Gio } from "./lib.js";
export const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(
- `
+ `
@@ -15,11 +15,11 @@ export const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(
-`
+`,
);
export const DBusProxy = Gio.DBusProxy.makeProxyWrapper(
- `
+ `
@@ -30,21 +30,20 @@ export const DBusProxy = Gio.DBusProxy.makeProxyWrapper(
-`
+`,
);
export const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(
- `
+ `
-`
+`,
);
-export const NotificationIFace =
- `
+export const NotificationIFace = `
@@ -92,18 +91,16 @@ export const NotificationIFace =
`;
-export const BluetoothIFace =
- `
+export const BluetoothIFace = `
-`
+`;
-export const ApplicationsIFace =
- `
+export const ApplicationsIFace = `
-`
+`;
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/host b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/host
index f407433fa..b61a4add4 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/host
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/host
@@ -13,15 +13,15 @@ imports.gi.versions.NM = '1.0'
imports.gi.versions.GdkPixbuf = '2.0'
imports.package.init({
- name: 'host',
- version: '0.1.0',
- prefix: '/usr/local',
- libdir: '/run/current-system/sw/lib',
+ name: 'host',
+ version: '0.1.0',
+ prefix: '/usr/local',
+ libdir: '/run/current-system/sw/lib',
});
imports.package.require({
- 'Gtk': '3.0',
- 'Gio': '2.0'
+ 'Gtk': '3.0',
+ 'Gio': '2.0'
});
main([programInvocationName, ...programArgs])
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/lib.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/lib.js
index 57babdb0e..3b8727d3d 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/lib.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/lib.js
@@ -1,19 +1,19 @@
-imports.gi.versions.Gtk = '3.0'
-imports.gi.versions.Gio = '2.0'
-imports.gi.versions.GLib = '2.0'
-imports.gi.versions.GObject = '2.0'
-imports.gi.versions.UPowerGlib = '1.0'
-imports.gi.versions.GnomeBluetooth = '3.0'
-imports.gi.versions.NM = '1.0'
-imports.gi.versions.GdkPixbuf = '2.0'
+imports.gi.versions.Gtk = "3.0";
+imports.gi.versions.Gio = "2.0";
+imports.gi.versions.GLib = "2.0";
+imports.gi.versions.GObject = "2.0";
+imports.gi.versions.UPowerGlib = "1.0";
+imports.gi.versions.GnomeBluetooth = "3.0";
+imports.gi.versions.NM = "1.0";
+imports.gi.versions.GdkPixbuf = "2.0";
export const {
- Gtk,
- Gio,
- GLib,
- GObject,
- UPowerGlib,
- GnomeBluetooth,
- NM,
- GdkPixbuf,
+ Gtk,
+ Gio,
+ GLib,
+ GObject,
+ UPowerGlib,
+ GnomeBluetooth,
+ NM,
+ GdkPixbuf,
} = imports.gi;
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/main.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/main.js
index ced915c50..9a09cb8ce 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/main.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/main.js
@@ -1,132 +1,164 @@
-import { Network } from './network.js'
-import { Media } from './media.js'
-import { Battery } from './battery.js'
-import { Bluetooth } from './bluetooth.js'
-import { Notifications } from './notifications.js'
-import { Apps } from './apps.js'
-import { GObject, Gio, GLib, Gtk } from './lib.js'
-
-const TICK_INTERVAL = 1000 //ms
-export const NOTIFICATIONS_BANNER_TIME_OUT = 5000
-export const PREFERRED_PLAYER = 'spotify'
-export const CACHE_PATH = GLib.get_user_cache_dir() + '/isabel/'
-export const MEDIA_CACHE_PATH = CACHE_PATH + 'media/'
-export const NOTIFICATIONS_CACHE_PATH = CACHE_PATH + 'notifications/'
-export const APPICON_CACHE_PATH = CACHE_PATH + 'apps/'
+import { Network } from "./network.js";
+import { Media } from "./media.js";
+import { Battery } from "./battery.js";
+import { Bluetooth } from "./bluetooth.js";
+import { Notifications } from "./notifications.js";
+import { Apps } from "./apps.js";
+import { GObject, Gio, GLib, Gtk } from "./lib.js";
+
+const TICK_INTERVAL = 1000; //ms
+export const NOTIFICATIONS_BANNER_TIME_OUT = 5000;
+export const PREFERRED_PLAYER = "spotify";
+export const CACHE_PATH = GLib.get_user_cache_dir() + "/isabel/";
+export const MEDIA_CACHE_PATH = CACHE_PATH + "media/";
+export const NOTIFICATIONS_CACHE_PATH = CACHE_PATH + "notifications/";
+export const APPICON_CACHE_PATH = CACHE_PATH + "apps/";
export const PlayerIcons = {
- 'deafult': '', //icon broken
- 'spotify': '',
- 'chromium': '',
- 'mpv': ''
-}
+ deafult: "", //icon broken
+ spotify: "",
+ chromium: "",
+ mpv: "",
+};
export function MkDirectory() {
- [
- CACHE_PATH,
- MEDIA_CACHE_PATH,
- NOTIFICATIONS_CACHE_PATH,
- APPICON_CACHE_PATH,
- ]
- .forEach(path => {
- if (!GLib.file_test(path, GLib.FileTest.EXISTS))
- Gio.File.new_for_path(path)
- .make_directory(null);
- })
+ [
+ CACHE_PATH,
+ MEDIA_CACHE_PATH,
+ NOTIFICATIONS_CACHE_PATH,
+ APPICON_CACHE_PATH,
+ ].forEach((path) => {
+ if (!GLib.file_test(path, GLib.FileTest.EXISTS))
+ Gio.File.new_for_path(path).make_directory(null);
+ });
}
const App = GObject.registerClass(
- class App extends Gtk.Application {
- constructor({ eww, file, stdout, fg_color }) {
- super({
- application_id: 'com.github.isabel.host',
- flags: Gio.ApplicationFlags.DEFAULT_FLAGS
- });
-
- MkDirectory();
-
- this._eww = eww;
- this._file = file;
- this._stdout = stdout;
- this._json = {};
-
- this._notifications = new Notifications(fg_color);
- this._battery = new Battery();
- this._network = new Network();
- this._bluetooth = new Bluetooth();
- this._media = new Media();
- this._apps = new Apps();
-
- this.run(null);
- }
-
- vfunc_activate() {
- this.hold();
-
- [
- 'notifications', 'battery', 'network',
- 'bluetooth', 'apps', 'media'
- ]
- .forEach(m => this._output(this[`_${m}`].json, m));
-
- this._notifications.connect('sync', o => this._output(o.json, 'notifications'));
- this._battery.connect('sync', o => this._output(o.json, 'battery'));
- this._network.connect('sync', o => this._output(o.json, 'network'));
- this._bluetooth.connect('sync', o => this._output(o.json, 'bluetooth'));
- this._apps.connect('sync', o => this._output(o.json, 'apps'));
- this._apps.init();
-
- this._media.connect('sync', o => this._output(o.json, 'media'));
- this._media.connect('positions', o => this._output(o.positions, 'media_positions'));
- GLib.timeout_add(GLib.PRIORITY_DEFAULT, TICK_INTERVAL, () => this._media.getPositions());
- }
-
- _output(json, name) {
- if (!json) return;
- if (this._file) {
- const file = Gio.File.new_for_path(CACHE_PATH + name + '.json');
-
- if (!GLib.file_test(file.get_path(), GLib.FileTest.EXISTS))
- file.create(Gio.FileCreateFlags.NONE, null);
-
- file.replace_contents(JSON.stringify(json, null, 2), null, false,
- Gio.FileCreateFlags.REPLACE_DESTINATION, null);
- }
-
- if (this._eww) {
- GLib.spawn_command_line_async(
- `eww update ${name}=${JSON.stringify(JSON.stringify(json))}`
- );
- }
-
- if (this._stdout) {
- this._json[name] = json;
- print(JSON.stringify(this._json, null, 2));
- }
- }
- })
+ class App extends Gtk.Application {
+ constructor({ eww, file, stdout, fg_color }) {
+ super({
+ application_id: "com.github.isabel.host",
+ flags: Gio.ApplicationFlags.DEFAULT_FLAGS,
+ });
+
+ MkDirectory();
+
+ this._eww = eww;
+ this._file = file;
+ this._stdout = stdout;
+ this._json = {};
+
+ this._notifications = new Notifications(fg_color);
+ this._battery = new Battery();
+ this._network = new Network();
+ this._bluetooth = new Bluetooth();
+ this._media = new Media();
+ this._apps = new Apps();
+
+ this.run(null);
+ }
+
+ vfunc_activate() {
+ this.hold();
+
+ [
+ "notifications",
+ "battery",
+ "network",
+ "bluetooth",
+ "apps",
+ "media",
+ ].forEach((m) => this._output(this[`_${m}`].json, m));
+
+ this._notifications.connect("sync", (o) =>
+ this._output(o.json, "notifications"),
+ );
+ this._battery.connect("sync", (o) =>
+ this._output(o.json, "battery"),
+ );
+ this._network.connect("sync", (o) =>
+ this._output(o.json, "network"),
+ );
+ this._bluetooth.connect("sync", (o) =>
+ this._output(o.json, "bluetooth"),
+ );
+ this._apps.connect("sync", (o) => this._output(o.json, "apps"));
+ this._apps.init();
+
+ this._media.connect("sync", (o) => this._output(o.json, "media"));
+ this._media.connect("positions", (o) =>
+ this._output(o.positions, "media_positions"),
+ );
+ GLib.timeout_add(GLib.PRIORITY_DEFAULT, TICK_INTERVAL, () =>
+ this._media.getPositions(),
+ );
+ }
+
+ _output(json, name) {
+ if (!json) return;
+ if (this._file) {
+ const file = Gio.File.new_for_path(CACHE_PATH + name + ".json");
+
+ if (!GLib.file_test(file.get_path(), GLib.FileTest.EXISTS))
+ file.create(Gio.FileCreateFlags.NONE, null);
+
+ file.replace_contents(
+ JSON.stringify(json, null, 2),
+ null,
+ false,
+ Gio.FileCreateFlags.REPLACE_DESTINATION,
+ null,
+ );
+ }
+
+ if (this._eww) {
+ GLib.spawn_command_line_async(
+ `eww update ${name}=${JSON.stringify(
+ JSON.stringify(json),
+ )}`,
+ );
+ }
+
+ if (this._stdout) {
+ this._json[name] = json;
+ print(JSON.stringify(this._json, null, 2));
+ }
+ }
+ },
+);
function parseArgs(argv) {
- let args = {};
- for (let i = 0; i < argv.length; ++i) {
- switch (argv[i]) {
- case '--help': args.help = true; break;
- case '--eww': args.eww = true; break;
- case '--file': args.file = true; break;
- case '--stdout': args.stdout = true; break;
- case '--fg-color': args.fg_color = argv[i++]; break;
- default: break;
+ let args = {};
+ for (let i = 0; i < argv.length; ++i) {
+ switch (argv[i]) {
+ case "--help":
+ args.help = true;
+ break;
+ case "--eww":
+ args.eww = true;
+ break;
+ case "--file":
+ args.file = true;
+ break;
+ case "--stdout":
+ args.stdout = true;
+ break;
+ case "--fg-color":
+ args.fg_color = argv[i++];
+ break;
+ default:
+ break;
+ }
}
- }
- return args;
+ return args;
}
export function main(argv) {
- let { help, eww, file, stdout, fg_color } = parseArgs(argv);
- if ((!eww && !file && !stdout) || help) {
- print('Usage:', argv[0], '[--eww] [--file] [--stdout]');
- return;
- }
- print('Cache directory:', CACHE_PATH);
- new App({ eww, file, stdout, fg_color });
+ let { help, eww, file, stdout, fg_color } = parseArgs(argv);
+ if ((!eww && !file && !stdout) || help) {
+ print("Usage:", argv[0], "[--eww] [--file] [--stdout]");
+ return;
+ }
+ print("Cache directory:", CACHE_PATH);
+ new App({ eww, file, stdout, fg_color });
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/media.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/media.js
index 847e28d4c..3dc7712e7 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/media.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/media.js
@@ -1,6 +1,11 @@
-import { MprisPlayerProxy, DBusProxy } from './dbus.js'
-import { PlayerIcons, PREFERRED_PLAYER, MEDIA_CACHE_PATH, MkDirectory } from "./main.js";
-import { GObject, Gio, GLib } from './lib.js'
+import { MprisPlayerProxy, DBusProxy } from "./dbus.js";
+import {
+ PlayerIcons,
+ PREFERRED_PLAYER,
+ MEDIA_CACHE_PATH,
+ MkDirectory,
+} from "./main.js";
+import { GObject, Gio, GLib } from "./lib.js";
function _lengthStr(length) {
let min = Math.floor(length / 60);
@@ -10,270 +15,287 @@ function _lengthStr(length) {
}
function _getName(busName) {
- return busName
- .substring(23)
- .split('.')
- [0];
+ return busName.substring(23).split(".")[0];
}
-const MprisPlayer = GObject.registerClass({
- Signals: { 'changed' : {}, 'closed': {}, 'ready': {} }
-},
-class MprisPlayer extends GObject.Object {
- constructor(busName) {
- super();
-
- this._proxy = new MprisPlayerProxy(Gio.DBus.session, busName,
- '/org/mpris/MediaPlayer2',
- this._onPlayerProxyReady.bind(this));
-
- this._busName = busName;
- this._name = _getName(busName);
- this._playerIcon = PlayerIcons?.[this._name] || PlayerIcons.deafult || '';
- this._trackArtists = [];
- this._trackTitle = '';
- this._trackCoverUrl = '';
- this._coverPath = '';
- this._playBackStatus = '';
- this._canGoNext = false;
- this._canGoPrev = false;
- this._canPlay = false;
- this._shuffle = false;
- this._loopStatus = '';
- this._volume = -1;
- this._length = -1;
- this._position = -1;
- }
-
- close() {
- this._proxy.disconnect(this._playerBinding1);
- this._proxy.disconnect(this._playerBinding2);
- this._proxy = null;
-
- this.emit('closed');
- }
-
- _onPlayerProxyReady() {
- this._playerBinding1 = this._proxy.connect('notify::g-name-owner', () => {
- if (!this._proxy.g_name_owner)
- this.close();
- })
- this._playerBinding2 = this._proxy.connect(
- 'g-properties-changed', () => {
- this._updateState();
- this._cacheCoverArt();
- this.emit('changed');
- }
- );
- if (!this._proxy.g_name_owner)
- this.close();
-
- this._updateState();
- this._cacheCoverArt();
- this.emit('ready');
- }
-
- _updateState() {
- let metadata = {};
- for (let prop in this._proxy.Metadata)
- metadata[prop] = this._proxy.Metadata[prop].deep_unpack();
-
- this._trackArtists = metadata['xesam:artist'];
- if (!Array.isArray(this._trackArtists) ||
- !this._trackArtists.every(artist => typeof artist === 'string'))
- this._trackArtists = ["Unknown artist"];
-
- this._trackTitle = metadata['xesam:title'];
- if (typeof this._trackTitle !== 'string')
- this._trackTitle = "Unknown title";
-
- this._trackCoverUrl = metadata['mpris:artUrl'];
- if (typeof this._trackCoverUrl !== 'string')
- this._trackCoverUrl = '';
-
- this._length = metadata['mpris:length'];
- if (typeof this._length !== 'number')
- this._length = -1;
- else
- this._length = Number.parseInt(`${this._length}`.substring(0, 3));
+const MprisPlayer = GObject.registerClass(
+ {
+ Signals: { changed: {}, closed: {}, ready: {} },
+ },
+ class MprisPlayer extends GObject.Object {
+ constructor(busName) {
+ super();
+
+ this._proxy = new MprisPlayerProxy(
+ Gio.DBus.session,
+ busName,
+ "/org/mpris/MediaPlayer2",
+ this._onPlayerProxyReady.bind(this),
+ );
- this._position = this._proxy.Position;
- if (typeof this._position !== 'number')
+ this._busName = busName;
+ this._name = _getName(busName);
+ this._playerIcon =
+ PlayerIcons?.[this._name] || PlayerIcons.deafult || "";
+ this._trackArtists = [];
+ this._trackTitle = "";
+ this._trackCoverUrl = "";
+ this._coverPath = "";
+ this._playBackStatus = "";
+ this._canGoNext = false;
+ this._canGoPrev = false;
+ this._canPlay = false;
+ this._shuffle = false;
+ this._loopStatus = "";
+ this._volume = -1;
+ this._length = -1;
this._position = -1;
- else
- this._position = this._position/1000000;
-
- this._playBackStatus = this._proxy.PlaybackStatus;
- this._canGoNext = this._proxy.CanGoNext;
- this._canGoPrev = this._proxy.CanGoPrevious;
- this._canPlay = this._proxy.CanPlay;
-
- this._shuffle = this._proxy.Shuffle;
- if (typeof this._shuffle !== 'boolean') {
- this._shuffle = null;
}
- this._loopStatus = this._proxy.LoopStatus;
- if (typeof this._loopStatus !== 'string') {
- this._loopStatus = null;
+
+ close() {
+ this._proxy.disconnect(this._playerBinding1);
+ this._proxy.disconnect(this._playerBinding2);
+ this._proxy = null;
+
+ this.emit("closed");
}
- this._volume = this._proxy.Volume;
- if(typeof this._volume !== 'number'){
- this._volume = -1;
+
+ _onPlayerProxyReady() {
+ this._playerBinding1 = this._proxy.connect(
+ "notify::g-name-owner",
+ () => {
+ if (!this._proxy.g_name_owner) this.close();
+ },
+ );
+ this._playerBinding2 = this._proxy.connect(
+ "g-properties-changed",
+ () => {
+ this._updateState();
+ this._cacheCoverArt();
+ this.emit("changed");
+ },
+ );
+ if (!this._proxy.g_name_owner) this.close();
+
+ this._updateState();
+ this._cacheCoverArt();
+ this.emit("ready");
+ }
+
+ _updateState() {
+ let metadata = {};
+ for (let prop in this._proxy.Metadata)
+ metadata[prop] = this._proxy.Metadata[prop].deep_unpack();
+
+ this._trackArtists = metadata["xesam:artist"];
+ if (
+ !Array.isArray(this._trackArtists) ||
+ !this._trackArtists.every(
+ (artist) => typeof artist === "string",
+ )
+ )
+ this._trackArtists = ["Unknown artist"];
+
+ this._trackTitle = metadata["xesam:title"];
+ if (typeof this._trackTitle !== "string")
+ this._trackTitle = "Unknown title";
+
+ this._trackCoverUrl = metadata["mpris:artUrl"];
+ if (typeof this._trackCoverUrl !== "string")
+ this._trackCoverUrl = "";
+
+ this._length = metadata["mpris:length"];
+ if (typeof this._length !== "number") this._length = -1;
+ else
+ this._length = Number.parseInt(
+ `${this._length}`.substring(0, 3),
+ );
+
+ this._position = this._proxy.Position;
+ if (typeof this._position !== "number") this._position = -1;
+ else this._position = this._position / 1000000;
+
+ this._playBackStatus = this._proxy.PlaybackStatus;
+ this._canGoNext = this._proxy.CanGoNext;
+ this._canGoPrev = this._proxy.CanGoPrevious;
+ this._canPlay = this._proxy.CanPlay;
+
+ this._shuffle = this._proxy.Shuffle;
+ if (typeof this._shuffle !== "boolean") {
+ this._shuffle = null;
+ }
+ this._loopStatus = this._proxy.LoopStatus;
+ if (typeof this._loopStatus !== "string") {
+ this._loopStatus = null;
+ }
+ this._volume = this._proxy.Volume;
+ if (typeof this._volume !== "number") {
+ this._volume = -1;
+ }
+ }
+
+ _cacheCoverArt() {
+ this._coverPath =
+ MEDIA_CACHE_PATH +
+ `${this._trackArtists.join(", ")}_${this._trackTitle}`.replace(
+ /[\,\*\?\"\<\>\|\#\:\?\/\']/g,
+ "",
+ );
+
+ if (this._trackCoverUrl === "") return;
+ if (this._coverPath === "_") return;
+ if (GLib.file_test(this._coverPath, GLib.FileTest.EXISTS)) return;
+
+ MkDirectory();
+
+ // Gio.File.new_for_uri(this._trackCoverUrl).copy_async(
+ // Gio.File.new_for_path(this._coverPath),
+ // Gio.FileCopyFlags.OVERWRITE,
+ // GLib.PRIORITY_DEFAULT,
+ // null,
+ // null,
+ // (source, result) => {
+ // try { source.copy_finish(result) }
+ // catch (e) { log(`failed to cache ${this._coverPath}`, e) }
+ // }
+ // );
+
+ try {
+ Gio.File.new_for_uri(this._trackCoverUrl).copy(
+ Gio.File.new_for_path(this._coverPath),
+ Gio.FileCopyFlags.OVERWRITE,
+ null,
+ null,
+ );
+ } catch (e) {
+ log(`failed to cache ${this._coverPath}`, e);
+ }
+ }
+
+ get json() {
+ return {
+ busName: this._busName, //busName
+ name: _getName(this._busName),
+ icon: this._playerIcon,
+ artist: this._trackArtists.join(", "),
+ title: this._trackTitle,
+ cover: this._coverPath,
+ status: this._playBackStatus,
+ canNext: this._canGoNext,
+ canPrev: this._canGoPrev,
+ canPlay: this._canPlay,
+ shuffle: this._shuffle,
+ loop: this._loopStatus,
+ volume: this._volume * 100,
+ length: this._length,
+ lengthStr: _lengthStr(this._length),
+ position: this._position,
+ };
}
- }
-
- _cacheCoverArt(){
- this._coverPath = MEDIA_CACHE_PATH + `${this._trackArtists.join(', ')}_${this._trackTitle}`
- .replace(/[\,\*\?\"\<\>\|\#\:\?\/\']/g, '');
-
- if(this._trackCoverUrl === '') return;
- if(this._coverPath === '_') return;
- if(GLib.file_test(this._coverPath, GLib.FileTest.EXISTS)) return;
-
- MkDirectory();
-
- // Gio.File.new_for_uri(this._trackCoverUrl).copy_async(
- // Gio.File.new_for_path(this._coverPath),
- // Gio.FileCopyFlags.OVERWRITE,
- // GLib.PRIORITY_DEFAULT,
- // null,
- // null,
- // (source, result) => {
- // try { source.copy_finish(result) }
- // catch (e) { log(`failed to cache ${this._coverPath}`, e) }
- // }
- // );
-
- try {
- Gio.File.new_for_uri(this._trackCoverUrl).copy(
- Gio.File.new_for_path(this._coverPath),
- Gio.FileCopyFlags.OVERWRITE,
- null, null
+ },
+);
+
+export const Media = GObject.registerClass(
+ {
+ Signals: { sync: {}, positions: {} },
+ },
+ class Media extends GObject.Object {
+ _init() {
+ super._init();
+
+ this._json = {};
+ this._positions = {};
+ this._players = new Map();
+ this._proxy = new DBusProxy(
+ Gio.DBus.session,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ this._onProxyReady.bind(this),
);
- } catch(e) {
- log(`failed to cache ${this._coverPath}`, e);
- };
- }
-
- get json() {
- return {
- busName: this._busName, //busName
- name: _getName(this._busName),
- icon: this._playerIcon,
- artist: this._trackArtists.join(', '),
- title: this._trackTitle,
- cover: this._coverPath,
- status: this._playBackStatus,
- canNext: this._canGoNext,
- canPrev: this._canGoPrev,
- canPlay: this._canPlay,
- shuffle: this._shuffle,
- loop: this._loopStatus,
- volume: this._volume*100,
- length: this._length,
- lengthStr: _lengthStr(this._length),
- position: this._position,
- };
- }
-});
-
-export const Media = GObject.registerClass({
- Signals: { 'sync': {}, 'positions': {} }
-},
-class Media extends GObject.Object{
- _init() {
- super._init();
-
- this._json = {};
- this._positions = {};
- this._players = new Map();
- this._proxy = new DBusProxy(Gio.DBus.session,
- 'org.freedesktop.DBus',
- '/org/freedesktop/DBus',
- this._onProxyReady.bind(this));
- }
-
- get json() { return this._json }
- get positions() { return this._positions }
-
- _addPlayer(busName) {
- if (this._players.get(busName))
- return;
-
- let player = new MprisPlayer(busName);
- player.connect('closed', () => {
- this._players.delete(busName);
- this._sync();
- });
- player.connect('changed', this._sync.bind(this));
- player.connect('ready', this._sync.bind(this));
- this._players.set(busName, player);
- }
-
- _onProxyReady() {
- this._proxy.ListNamesRemote(([names]) => {
- names.forEach(name => {
- if (name.startsWith('org.mpris.MediaPlayer2.'))
- this._addPlayer(name);
+ }
+
+ get json() {
+ return this._json;
+ }
+ get positions() {
+ return this._positions;
+ }
+
+ _addPlayer(busName) {
+ if (this._players.get(busName)) return;
+
+ let player = new MprisPlayer(busName);
+ player.connect("closed", () => {
+ this._players.delete(busName);
+ this._sync();
});
- });
- this._proxy.connectSignal(
- 'NameOwnerChanged',
- this._onNameOwnerChanged.bind(this)
- );
- this._sync();
- }
-
- _onNameOwnerChanged(proxy, sender, [name, oldOwner, newOwner]) {
- if (!name.startsWith('org.mpris.MediaPlayer2.'))
- return;
-
- if (newOwner && !oldOwner)
- this._addPlayer(name);
- }
-
- _sync(){
- let preferred = null;
- let players = [];
- for (const [_, player] of this._players) {
- if(player.json.busName.includes(PREFERRED_PLAYER))
- preferred = player.json
-
- players.push(player.json);
+ player.connect("changed", this._sync.bind(this));
+ player.connect("ready", this._sync.bind(this));
+ this._players.set(busName, player);
}
- if(this._players.size === 1)
- preferred = players[0];
+ _onProxyReady() {
+ this._proxy.ListNamesRemote(([names]) => {
+ names.forEach((name) => {
+ if (name.startsWith("org.mpris.MediaPlayer2."))
+ this._addPlayer(name);
+ });
+ });
+ this._proxy.connectSignal(
+ "NameOwnerChanged",
+ this._onNameOwnerChanged.bind(this),
+ );
+ this._sync();
+ }
+
+ _onNameOwnerChanged(proxy, sender, [name, oldOwner, newOwner]) {
+ if (!name.startsWith("org.mpris.MediaPlayer2.")) return;
+
+ if (newOwner && !oldOwner) this._addPlayer(name);
+ }
+
+ _sync() {
+ let preferred = null;
+ let players = [];
+ for (const [_, player] of this._players) {
+ if (player.json.busName.includes(PREFERRED_PLAYER))
+ preferred = player.json;
- this._json = {
- preferred,
- players
+ players.push(player.json);
+ }
+
+ if (this._players.size === 1) preferred = players[0];
+
+ this._json = {
+ preferred,
+ players,
+ };
+ this.emit("sync");
}
- this.emit('sync');
- }
-
- getPositions(){
- if(this._players.size === 0) return;
- let playersReady = 0;
- let positions = {};
- for (const [busName, _] of this._players) {
- new MprisPlayer(busName).connect('ready', mpris => {
- positions[mpris.json.name] = {
- length: mpris.json.length,
- lengthStr: _lengthStr(mpris.json.length),
- position: mpris.json.position,
- positionStr: _lengthStr(mpris.json.position)
- };
- playersReady++
-
- if(playersReady === this._players.size) {
- this._positions = positions;
- this.emit('positions');
- }
-
- mpris.close();
- })
+
+ getPositions() {
+ if (this._players.size === 0) return;
+ let playersReady = 0;
+ let positions = {};
+ for (const [busName, _] of this._players) {
+ new MprisPlayer(busName).connect("ready", (mpris) => {
+ positions[mpris.json.name] = {
+ length: mpris.json.length,
+ lengthStr: _lengthStr(mpris.json.length),
+ position: mpris.json.position,
+ positionStr: _lengthStr(mpris.json.position),
+ };
+ playersReady++;
+
+ if (playersReady === this._players.size) {
+ this._positions = positions;
+ this.emit("positions");
+ }
+
+ mpris.close();
+ });
+ }
+ return true;
}
- return true;
- }
-})
+ },
+);
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/network.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/network.js
index dd6579c14..7d150c304 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/network.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/network.js
@@ -1,123 +1,154 @@
-import { NM, Gio, GObject } from './lib.js'
+import { NM, Gio, GObject } from "./lib.js";
function showNotification(title, message) {
- let notification = new Gio.Notification();
- notification.set_title(title);
- notification.set_body(message);
- notification.set_priority(Gio.NotificationPriority.NORMAL);
- application.register(null);
- application.send_notification(null, notification);
- GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => {
- application.quit();
- return GLib.SOURCE_REMOVE;
- });
+ let notification = new Gio.Notification();
+ notification.set_title(title);
+ notification.set_body(message);
+ notification.set_priority(Gio.NotificationPriority.NORMAL);
+ application.register(null);
+ application.send_notification(null, notification);
+ GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => {
+ application.quit();
+ return GLib.SOURCE_REMOVE;
+ });
}
-Gio._promisify(NM.Client, 'new_async');
-Gio._promisify(NM.DeviceWifi.prototype, 'request_scan_async');
+Gio._promisify(NM.Client, "new_async");
+Gio._promisify(NM.DeviceWifi.prototype, "request_scan_async");
const WifiStyles = {
- '': 'none',
- '': 'low',
- '': 'low',
- '': 'low',
- '': 'medium',
- '': 'medium',
- '': 'high'
-}
-
-export const Network = GObject.registerClass({
- Signals: { 'sync': {} }
-},
- class Network extends GObject.Object {
- constructor() {
- super();
-
- this._json = {};
- this._getClient();
- }
-
- get json() { return this._json }
-
- _getDevice(devType) {
- return this._client
- .get_devices()
- .find(device => device.get_device_type() === devType);
- }
-
- async _getClient() {
- this._client = await NM.Client.new_async(null);
- this._client.connect('notify::wireless-enabled', this._sync.bind(this));
- this._client.connect('notify::connectivity', this._sync.bind(this));
- this._client.connect('notify::primary-connection', this._sync.bind(this));
- this._client.connect('notify::activating-connection', this._sync.bind(this));
-
- this._wifi = this._getDevice(NM.DeviceType.WIFI);
- if (this._wifi) {
- this._wifi.connect('notify::active-access-point', this._activeAp.bind(this));
- //this._wifi.connect('access-point-added', (_, ap) => this._apAdded(ap));
- //this._wifi.connect('access-point-removed', (_, ap) => this._apRemoved(ap));
- }
-
- this._activeAp();
- this._sync();
- }
-
- //_apAdded(ap) {
- // let ssid = NM.utils_ssid_to_utf8(ap.get_ssid().get_data());
- // showNotification('Access Point Added', `The access point "${ssid}" has been added.`);
- // this._sync();
- //}
-
- //_apRemoved(ap) {
- // let ssid = NM.utils_ssid_to_utf8(ap.get_ssid().get_data());
- // showNotification('Access Point Removed', `The access point "${ssid}" has been removed.`);
- // this._sync();
- //}
-
- _activeAp() {
- if (this._ap) this._ap.disconnect(this._apBind);
- this._ap = this._wifi?.get_active_access_point();
- if (!this._ap) return;
- this._apBind = this._ap.connect('notify::strength', this._sync.bind(this));
- this._sync();
- }
-
- _sync() {
- const mainConnection =
- this._client.get_primary_connection() ||
- this._client.get_activating_connection();
-
- const primary_type = mainConnection?.type || null; // 802-11-wireless ; 802-3-ethernet
- const internet = this._client.connectivity === NM.ConnectivityState.FULL;
-
- let wifi = {
- primary: primary_type === '802-11-wireless',
- enabled: this._client.wireless_enabled,
- state: this._client.wireless_enabled ? 'on' : 'off',
- ssid: this._ap && NM.utils_ssid_to_utf8(
- this._ap.get_ssid().get_data()) || 'Unknown',
- strength: this._client.wireless_enabled && mainConnection ? `${this._ap?.strength}%` : '',
- icon: ['', '', '', '', '', ''][Math.ceil(this._ap?.strength / 20)]
- };
- if (!internet) {
- wifi.strength = ''
- wifi.icon = ''
- }
- wifi.style = WifiStyles[wifi.icon];
-
- let wired = {
- primary: primary_type === '802-3-ethernet',
- icon: internet ? '' : ''
- }
-
- this._json = {
- primary: { '802-3-ethernet': 'wired', '802-11-wireless': 'wifi' }[primary_type] || 'none',
- none: { icon: '' },
- wifi,
- wired,
- };
- this.emit('sync')
- }
-
- })
+ "": "none",
+ "": "low",
+ "": "low",
+ "": "low",
+ "": "medium",
+ "": "medium",
+ "": "high",
+};
+
+export const Network = GObject.registerClass(
+ {
+ Signals: { sync: {} },
+ },
+ class Network extends GObject.Object {
+ constructor() {
+ super();
+
+ this._json = {};
+ this._getClient();
+ }
+
+ get json() {
+ return this._json;
+ }
+
+ _getDevice(devType) {
+ return this._client
+ .get_devices()
+ .find((device) => device.get_device_type() === devType);
+ }
+
+ async _getClient() {
+ this._client = await NM.Client.new_async(null);
+ this._client.connect(
+ "notify::wireless-enabled",
+ this._sync.bind(this),
+ );
+ this._client.connect("notify::connectivity", this._sync.bind(this));
+ this._client.connect(
+ "notify::primary-connection",
+ this._sync.bind(this),
+ );
+ this._client.connect(
+ "notify::activating-connection",
+ this._sync.bind(this),
+ );
+
+ this._wifi = this._getDevice(NM.DeviceType.WIFI);
+ if (this._wifi) {
+ this._wifi.connect(
+ "notify::active-access-point",
+ this._activeAp.bind(this),
+ );
+ //this._wifi.connect('access-point-added', (_, ap) => this._apAdded(ap));
+ //this._wifi.connect('access-point-removed', (_, ap) => this._apRemoved(ap));
+ }
+
+ this._activeAp();
+ this._sync();
+ }
+
+ //_apAdded(ap) {
+ // let ssid = NM.utils_ssid_to_utf8(ap.get_ssid().get_data());
+ // showNotification('Access Point Added', `The access point "${ssid}" has been added.`);
+ // this._sync();
+ //}
+
+ //_apRemoved(ap) {
+ // let ssid = NM.utils_ssid_to_utf8(ap.get_ssid().get_data());
+ // showNotification('Access Point Removed', `The access point "${ssid}" has been removed.`);
+ // this._sync();
+ //}
+
+ _activeAp() {
+ if (this._ap) this._ap.disconnect(this._apBind);
+ this._ap = this._wifi?.get_active_access_point();
+ if (!this._ap) return;
+ this._apBind = this._ap.connect(
+ "notify::strength",
+ this._sync.bind(this),
+ );
+ this._sync();
+ }
+
+ _sync() {
+ const mainConnection =
+ this._client.get_primary_connection() ||
+ this._client.get_activating_connection();
+
+ const primary_type = mainConnection?.type || null; // 802-11-wireless ; 802-3-ethernet
+ const internet =
+ this._client.connectivity === NM.ConnectivityState.FULL;
+
+ let wifi = {
+ primary: primary_type === "802-11-wireless",
+ enabled: this._client.wireless_enabled,
+ state: this._client.wireless_enabled ? "on" : "off",
+ ssid:
+ (this._ap &&
+ NM.utils_ssid_to_utf8(
+ this._ap.get_ssid().get_data(),
+ )) ||
+ "Unknown",
+ strength:
+ this._client.wireless_enabled && mainConnection
+ ? `${this._ap?.strength}%`
+ : "",
+ icon: ["", "", "", "", "", ""][
+ Math.ceil(this._ap?.strength / 20)
+ ],
+ };
+ if (!internet) {
+ wifi.strength = "";
+ wifi.icon = "";
+ }
+ wifi.style = WifiStyles[wifi.icon];
+
+ let wired = {
+ primary: primary_type === "802-3-ethernet",
+ icon: internet ? "" : "",
+ };
+
+ this._json = {
+ primary:
+ { "802-3-ethernet": "wired", "802-11-wireless": "wifi" }[
+ primary_type
+ ] || "none",
+ none: { icon: "" },
+ wifi,
+ wired,
+ };
+ this.emit("sync");
+ }
+ },
+);
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/notifications.js b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/notifications.js
index c66d512ce..b4de8c87b 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/notifications.js
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/host/notifications.js
@@ -1,235 +1,286 @@
-import { NotificationIFace } from "./dbus.js"
-import { NOTIFICATIONS_CACHE_PATH, NOTIFICATIONS_BANNER_TIME_OUT, MkDirectory, CACHE_PATH } from './main.js'
-import { GObject, Gio, Gtk, GdkPixbuf, GLib } from './lib.js'
-
-export const Notifications = GObject.registerClass({
- Signals: { 'sync': {} }
-},
- class Notifications extends GObject.Object {
- constructor(fg_color = 'white') {
- super();
-
- this._fgColor = fg_color;
- this._json = {};
- this._dnd = false;
- this._idCound = 1;
- this._notifications = new Map();
- this._popups = new Map();
- this._readFromFile();
- this._register();
- this._sync();
- }
-
- get json() { return this._json }
-
- get DoNotDisturb() {
- return this._dnd;
- }
-
- Clear() {
- for (const [_, notification] of this._notifications) {
- this.CloseNotification(notification.id);
- }
- }
-
- Notify(app_name, replaces_id, app_icon, summary, body, actions, hints, time_out) {
- let acts = [];
- for (let i = 0; i < actions.length; i += 2) {
- if (actions[i + 1] !== '')
- acts.push({
- label: actions[i + 1],
- id: actions[i]
- })
- }
- let id = replaces_id || this._idCound++;
- let date = new Date();
- let notification = {
- id,
- app_name,
- app_icon,
- summary,
- body,
- actions: acts,
- time: { hour: date.getHours(), minute: date.getMinutes() > 9 ? date.getMinutes() : `0${date.getMinutes()}` },
- image:
- this._parseImage(hints['image-data'], `${summary}${id}`) ||
- this._parseIcon(app_icon, `${summary}${id}`) ||
- this._parseIcon(app_name, `${summary}${id}`)
- }
- this._notifications.set(notification.id, notification);
- if (!this._dnd) {
- this._popups.set(notification.id, notification);
- GLib.timeout_add(GLib.PRIORITY_DEFAULT,
- time_out > 0 ? time_out : NOTIFICATIONS_BANNER_TIME_OUT,
- () => {
- if (!this._popups.has(id)) return;
- this._popups.delete(notification.id);
+import { NotificationIFace } from "./dbus.js";
+import {
+ NOTIFICATIONS_CACHE_PATH,
+ NOTIFICATIONS_BANNER_TIME_OUT,
+ MkDirectory,
+ CACHE_PATH,
+} from "./main.js";
+import { GObject, Gio, Gtk, GdkPixbuf, GLib } from "./lib.js";
+
+export const Notifications = GObject.registerClass(
+ {
+ Signals: { sync: {} },
+ },
+ class Notifications extends GObject.Object {
+ constructor(fg_color = "white") {
+ super();
+
+ this._fgColor = fg_color;
+ this._json = {};
+ this._dnd = false;
+ this._idCound = 1;
+ this._notifications = new Map();
+ this._popups = new Map();
+ this._readFromFile();
+ this._register();
this._sync();
- }
- );
- }
- this._sync();
- return notification.id;
- }
-
- ToggleDND() {
- this._dnd = !this._dnd;
- this._sync();
- }
-
- DismissNotification(id) {
- this._popups.delete(id);
- this._sync();
- }
-
- DismissLatestNotification() {
- this._popups.delete([...this._popups.keys()].pop());
- this._sync();
- }
-
- CloseNotification(id) {
- if (!this._notifications.has(id)) return;
- this._dbus.emit_signal('NotificationClosed', GLib.Variant.new('(uu)', [id, 2]));
- this._notifications.delete(id);
- this._popups.delete(id);
- this._sync();
- }
-
- CloseLatestNotification() {
- const latestNotificationId = [...this._notifications.keys()].pop();
- if (latestNotificationId) {
- this.CloseNotification(latestNotificationId);
- }
- }
-
- InvokeAction(id, action) {
- if (!this._notifications.has(id)) return;
- this._dbus.emit_signal('ActionInvoked', GLib.Variant.new('(us)', [id, action]));
- this._notifications.delete(id);
- this._popups.delete(id);
- this._sync();
- }
-
- GetCapabilities() {
- return ['actions', 'body', 'icon-static', 'persistence'];
- }
-
- GetServerInformation() {
- return new GLib.Variant('(ssss)', [
- "host",
- "isabel",
- "0.1",
- "1.2",
- ])
- }
-
- _register() {
- Gio.bus_own_name(
- Gio.BusType.SESSION,
- 'org.freedesktop.Notifications',
- Gio.BusNameOwnerFlags.NONE,
- (connection, _) => {
- this._dbus = Gio.DBusExportedObject.wrapJSObject(NotificationIFace, this);
- this._dbus.export(connection, '/org/freedesktop/Notifications');
- },
- null,
- () => {
- print('Another Notification Daemon is already running!')
- }
- );
- }
-
- _filterName(name) {
- return NOTIFICATIONS_CACHE_PATH + name.replace(/[\ \,\*\?\"\<\>\|\#\:\?\/\!\']/g, '') + '.png';
- }
-
- _parseIcon(icon_name, name) {
- if (!icon_name) return;
-
- MkDirectory();
- let fileName = this._filterName(name);
- let iconInfo = Gtk.IconTheme.get_default()
- .lookup_by_gicon(
- Gio.Icon.new_for_string(icon_name),
- 128, null);
-
- if (!iconInfo) return null;
-
- let output_stream =
- Gio.File.new_for_path(fileName)
- .replace(null, false, Gio.FileCreateFlags.NONE, null);
-
- iconInfo.load_icon()
- .save_to_streamv(output_stream, 'png', null, null, null);
-
- output_stream.close(null);
-
- if (icon_name.includes('-symbolic'))
- GLib.spawn_command_line_sync(`convert ${fileName} -alpha on
+ }
+
+ get json() {
+ return this._json;
+ }
+
+ get DoNotDisturb() {
+ return this._dnd;
+ }
+
+ Clear() {
+ for (const [_, notification] of this._notifications) {
+ this.CloseNotification(notification.id);
+ }
+ }
+
+ Notify(
+ app_name,
+ replaces_id,
+ app_icon,
+ summary,
+ body,
+ actions,
+ hints,
+ time_out,
+ ) {
+ let acts = [];
+ for (let i = 0; i < actions.length; i += 2) {
+ if (actions[i + 1] !== "")
+ acts.push({
+ label: actions[i + 1],
+ id: actions[i],
+ });
+ }
+ let id = replaces_id || this._idCound++;
+ let date = new Date();
+ let notification = {
+ id,
+ app_name,
+ app_icon,
+ summary,
+ body,
+ actions: acts,
+ time: {
+ hour: date.getHours(),
+ minute:
+ date.getMinutes() > 9
+ ? date.getMinutes()
+ : `0${date.getMinutes()}`,
+ },
+ image:
+ this._parseImage(hints["image-data"], `${summary}${id}`) ||
+ this._parseIcon(app_icon, `${summary}${id}`) ||
+ this._parseIcon(app_name, `${summary}${id}`),
+ };
+ this._notifications.set(notification.id, notification);
+ if (!this._dnd) {
+ this._popups.set(notification.id, notification);
+ GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT,
+ time_out > 0 ? time_out : NOTIFICATIONS_BANNER_TIME_OUT,
+ () => {
+ if (!this._popups.has(id)) return;
+ this._popups.delete(notification.id);
+ this._sync();
+ },
+ );
+ }
+ this._sync();
+ return notification.id;
+ }
+
+ ToggleDND() {
+ this._dnd = !this._dnd;
+ this._sync();
+ }
+
+ DismissNotification(id) {
+ this._popups.delete(id);
+ this._sync();
+ }
+
+ DismissLatestNotification() {
+ this._popups.delete([...this._popups.keys()].pop());
+ this._sync();
+ }
+
+ CloseNotification(id) {
+ if (!this._notifications.has(id)) return;
+ this._dbus.emit_signal(
+ "NotificationClosed",
+ GLib.Variant.new("(uu)", [id, 2]),
+ );
+ this._notifications.delete(id);
+ this._popups.delete(id);
+ this._sync();
+ }
+
+ CloseLatestNotification() {
+ const latestNotificationId = [...this._notifications.keys()].pop();
+ if (latestNotificationId) {
+ this.CloseNotification(latestNotificationId);
+ }
+ }
+
+ InvokeAction(id, action) {
+ if (!this._notifications.has(id)) return;
+ this._dbus.emit_signal(
+ "ActionInvoked",
+ GLib.Variant.new("(us)", [id, action]),
+ );
+ this._notifications.delete(id);
+ this._popups.delete(id);
+ this._sync();
+ }
+
+ GetCapabilities() {
+ return ["actions", "body", "icon-static", "persistence"];
+ }
+
+ GetServerInformation() {
+ return new GLib.Variant("(ssss)", ["host", "isabel", "0.1", "1.2"]);
+ }
+
+ _register() {
+ Gio.bus_own_name(
+ Gio.BusType.SESSION,
+ "org.freedesktop.Notifications",
+ Gio.BusNameOwnerFlags.NONE,
+ (connection, _) => {
+ this._dbus = Gio.DBusExportedObject.wrapJSObject(
+ NotificationIFace,
+ this,
+ );
+ this._dbus.export(
+ connection,
+ "/org/freedesktop/Notifications",
+ );
+ },
+ null,
+ () => {
+ print("Another Notification Daemon is already running!");
+ },
+ );
+ }
+
+ _filterName(name) {
+ return (
+ NOTIFICATIONS_CACHE_PATH +
+ name.replace(/[\ \,\*\?\"\<\>\|\#\:\?\/\!\']/g, "") +
+ ".png"
+ );
+ }
+
+ _parseIcon(icon_name, name) {
+ if (!icon_name) return;
+
+ MkDirectory();
+ let fileName = this._filterName(name);
+ let iconInfo = Gtk.IconTheme.get_default().lookup_by_gicon(
+ Gio.Icon.new_for_string(icon_name),
+ 128,
+ null,
+ );
+
+ if (!iconInfo) return null;
+
+ let output_stream = Gio.File.new_for_path(fileName).replace(
+ null,
+ false,
+ Gio.FileCreateFlags.NONE,
+ null,
+ );
+
+ iconInfo
+ .load_icon()
+ .save_to_streamv(output_stream, "png", null, null, null);
+
+ output_stream.close(null);
+
+ if (icon_name.includes("-symbolic"))
+ GLib.spawn_command_line_sync(`convert ${fileName} -alpha on
-fill ${this._fgColor} -colorize 100% -bordercolor transparent -border 16 ${fileName}`);
- return fileName;
- }
-
- _readFromFile() {
- try {
- const file = Gio.File.new_for_path(CACHE_PATH + 'notifications.json');
- const [, contents, etag] = file.load_contents(null);
- const json = JSON.parse(new TextDecoder('utf-8').decode(contents))
- json.notifications.forEach(n => {
- if (n.id > this._idCound) this._idCound = n.id + 1;
- this._notifications.set(n.id, n);
- })
- } catch (error) {
- print('There were no cached notifications found!')
- print('If you want your notifications to be cached run with --file flag');
- }
- }
-
- _parseImage(image_data, name) {
- if (!image_data) return;
- MkDirectory();
- let fileName = this._filterName(name);
- let image = image_data.recursiveUnpack();
- let pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(
- image[6],
- GdkPixbuf.Colorspace.RGB,
- image[3],
- image[4],
- image[0],
- image[1],
- image[2]
- );
-
- let output_stream =
- Gio.File.new_for_path(fileName)
- .replace(null, false, Gio.FileCreateFlags.NONE, null);
-
- pixbuf.save_to_streamv(output_stream, "png", null, null, null);
- output_stream.close(null);
-
- return fileName;
- }
-
- _sync() {
- let notifications = [], popups = [];
- for (const [_, notification] of this._notifications)
- notifications.push(notification);
-
- for (const [_, notification] of this._popups)
- popups.push(notification);
-
- this._json = {
- dnd: {
- enabled: this._dnd,
- state: this._dnd ? 'on' : 'off',
- icon: this._dnd ? '' : '',
- },
- count: notifications.length,
- icon: this._dnd ? '' : (notifications.length > 0 ? '' : ''),
- notifications,
- popups
- }
- this.emit('sync');
- }
- })
+ return fileName;
+ }
+
+ _readFromFile() {
+ try {
+ const file = Gio.File.new_for_path(
+ CACHE_PATH + "notifications.json",
+ );
+ const [, contents, etag] = file.load_contents(null);
+ const json = JSON.parse(
+ new TextDecoder("utf-8").decode(contents),
+ );
+ json.notifications.forEach((n) => {
+ if (n.id > this._idCound) this._idCound = n.id + 1;
+ this._notifications.set(n.id, n);
+ });
+ } catch (error) {
+ print("There were no cached notifications found!");
+ print(
+ "If you want your notifications to be cached run with --file flag",
+ );
+ }
+ }
+
+ _parseImage(image_data, name) {
+ if (!image_data) return;
+ MkDirectory();
+ let fileName = this._filterName(name);
+ let image = image_data.recursiveUnpack();
+ let pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(
+ image[6],
+ GdkPixbuf.Colorspace.RGB,
+ image[3],
+ image[4],
+ image[0],
+ image[1],
+ image[2],
+ );
+
+ let output_stream = Gio.File.new_for_path(fileName).replace(
+ null,
+ false,
+ Gio.FileCreateFlags.NONE,
+ null,
+ );
+
+ pixbuf.save_to_streamv(output_stream, "png", null, null, null);
+ output_stream.close(null);
+
+ return fileName;
+ }
+
+ _sync() {
+ let notifications = [],
+ popups = [];
+ for (const [_, notification] of this._notifications)
+ notifications.push(notification);
+
+ for (const [_, notification] of this._popups)
+ popups.push(notification);
+
+ this._json = {
+ dnd: {
+ enabled: this._dnd,
+ state: this._dnd ? "on" : "off",
+ icon: this._dnd ? "" : "",
+ },
+ count: notifications.length,
+ icon: this._dnd ? "" : notifications.length > 0 ? "" : "",
+ notifications,
+ popups,
+ };
+ this.emit("sync");
+ }
+ },
+);
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/launcher b/home/isabel/programs/gui/confs/bars/eww/config/scripts/launcher
index 47721b7c1..1d8b2130a 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/launcher
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/launcher
@@ -1,44 +1,44 @@
#!/usr/bin/env bash
function toggle_menu {
- hyprctl keyword blurls "remove,gtk-layer-shell"
- STATE=$(eww windows | grep $1 | awk '{print substr ($0, 0, 1)}')
- if [[ $STATE == '*' ]]; then
- # if [[ $1 == 'powermenu' ]]; then hyprctl keyword blurls "remove,gtk-layer-shell"; fi
- eww close $1
- else
- if [[ $1 == 'powermenu' ]]; then hyprctl keyword blurls "gtk-layer-shell"; fi
- if [[ $1 == 'app_launcher' ]]; then $HOME/.config/eww/scripts/apps query ""; fi
- eww open $1
- fi
+ hyprctl keyword blurls "remove,gtk-layer-shell"
+ STATE=$(eww windows | grep $1 | awk '{print substr ($0, 0, 1)}')
+ if [[ $STATE == '*' ]]; then
+ # if [[ $1 == 'powermenu' ]]; then hyprctl keyword blurls "remove,gtk-layer-shell"; fi
+ eww close $1
+ else
+ if [[ $1 == 'powermenu' ]]; then hyprctl keyword blurls "gtk-layer-shell"; fi
+ if [[ $1 == 'app_launcher' ]]; then $HOME/.config/eww/scripts/apps query ""; fi
+ eww open $1
+ fi
}
function colorpicker {
- pkill hyprpicker
- hyprpicker -n -a
+ pkill hyprpicker
+ hyprpicker -n -a
}
function network {
- nm-connection-editor
+ nm-connection-editor
}
function screenlock {
- STATE=$(eww windows | grep powermenu | awk '{print substr ($0, 0, 1)}')
- if [[ $STATE == '*' ]]; then eww close powermenu; fi
- swaylock
+ STATE=$(eww windows | grep powermenu | awk '{print substr ($0, 0, 1)}')
+ if [[ $STATE == '*' ]]; then eww close powermenu; fi
+ swaylock
}
function clipboard {
- cliphist list | rofi -dmenu -p "Clipboard" | cliphist decode | wl-copy
+ cliphist list | rofi -dmenu -p "Clipboard" | cliphist decode | wl-copy
}
function config {
- $VISUAL $HOME/.config/hypr
+ $VISUAL $HOME/.config/hypr
}
function powersettings {
- alacritty --class Power --title Power --hold \
- --command auto-cpufreq --stats
+ alacritty --class Power --title Power --hold \
+ --command auto-cpufreq --stats
}
if [[ $1 == 'applauncher' ]]; then rofi -show drun; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/network b/home/isabel/programs/gui/confs/bars/eww/config/scripts/network
index 8aa6b8be2..180522457 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/network
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/network
@@ -1,9 +1,9 @@
#!/usr/bin/env bash
function toggle {
- STATE=$(nmcli radio wifi)
- if [[ $STATE == 'enabled' ]]; then nmcli radio wifi off
- else nmcli radio wifi on; fi
+ STATE=$(nmcli radio wifi)
+ if [[ $STATE == 'enabled' ]]; then nmcli radio wifi off
+ else nmcli radio wifi on; fi
}
if [[ $1 == 'toggle' ]]; then toggle; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/night_light b/home/isabel/programs/gui/confs/bars/eww/config/scripts/night_light
index 2216fecae..134b484cd 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/night_light
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/night_light
@@ -1,31 +1,31 @@
#!/usr/bin/env bash
function state {
- STATE=$(pgrep wlsunset)
- if [[ -z $STATE ]]; then echo 'off'
- else echo 'on'; fi
+ STATE=$(pgrep wlsunset)
+ if [[ -z $STATE ]]; then echo 'off'
+ else echo 'on'; fi
}
function icon {
- echo ''
+ echo ''
}
function toggle {
- STATE=$(state)
- if [[ $STATE == 'on' ]]; then
- eww update night_light_state="{ \"state\": \"off\", \"icon\": \"$(icon)\"}"
- pkill wlsunset
- else
- eww update night_light_state="{ \"state\": \"on\", \"icon\": \"$(icon)\"}"
- wlsunset -t 3400
- fi
+ STATE=$(state)
+ if [[ $STATE == 'on' ]]; then
+ eww update night_light_state="{ \"state\": \"off\", \"icon\": \"$(icon)\"}"
+ pkill wlsunset
+ else
+ eww update night_light_state="{ \"state\": \"on\", \"icon\": \"$(icon)\"}"
+ wlsunset -t 3400
+ fi
}
function get {
- echo "{
- \"state\": \"$(state)\",
- \"icon\": \"$(icon)\"
- }"
+ echo "{
+ \"state\": \"$(state)\",
+ \"icon\": \"$(icon)\"
+ }"
}
if [[ $1 == 'toggle' ]]; then toggle; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/osd b/home/isabel/programs/gui/confs/bars/eww/config/scripts/osd
index e9c468eac..eda244cc9 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/osd
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/osd
@@ -3,10 +3,10 @@
STATE=$(eww windows | grep osd | awk '{print substr ($0, 0, 1)}')
if [[ $1 == 'close' ]]; then
- if [[ $STATE == '*' ]]; then eww close osd; fi
+ if [[ $STATE == '*' ]]; then eww close osd; fi
else
- eww update osd="{ \"icon\": \"$1\", \"value\": \"$2\" }"
- if [[ $STATE != '*' ]]; then eww open osd; fi
- sleep 4
- if [[ $STATE == '*' ]]; then eww close osd; fi
-fi
\ No newline at end of file
+ eww update osd="{ \"icon\": \"$1\", \"value\": \"$2\" }"
+ if [[ $STATE != '*' ]]; then eww open osd; fi
+ sleep 4
+ if [[ $STATE == '*' ]]; then eww close osd; fi
+fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/player b/home/isabel/programs/gui/confs/bars/eww/config/scripts/player
index 53368cdda..b4359bfa2 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/player
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/player
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
function loop {
- LOOPSTATUS=$(playerctl -p $1 loop)
- if [[ $LOOPSTATUS == 'None' ]]; then playerctl -p $1 loop Track; fi
- if [[ $LOOPSTATUS == 'Track' ]]; then playerctl -p $1 loop Playlist; fi
- if [[ $LOOPSTATUS == 'Playlist' ]]; then playerctl -p $1 loop None; fi
+ LOOPSTATUS=$(playerctl -p $1 loop)
+ if [[ $LOOPSTATUS == 'None' ]]; then playerctl -p $1 loop Track; fi
+ if [[ $LOOPSTATUS == 'Track' ]]; then playerctl -p $1 loop Playlist; fi
+ if [[ $LOOPSTATUS == 'Playlist' ]]; then playerctl -p $1 loop None; fi
}
if [[ $2 == 'up' ]]; then playerctl -p $1 next; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/power b/home/isabel/programs/gui/confs/bars/eww/config/scripts/power
index 8c468eabc..d995ae843 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/power
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/power
@@ -36,9 +36,9 @@ function toggle {
function get {
echo "{
- \"state\": \"$(state)\",
- \"icon\": \"$(icon)\"
-}"
+ \"state\": \"$(state)\",
+ \"icon\": \"$(icon)\"
+ }"
}
if [[ $1 == 'get' ]]; then get; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/screenshot b/home/isabel/programs/gui/confs/bars/eww/config/scripts/screenshot
index 4fae01841..25470ae9c 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/screenshot
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/screenshot
@@ -4,35 +4,35 @@ screenshot=/tmp/screenshot.png
path=~/media/pictures/screenshots
window() {
- grimblast save active $screenshot
+ grimblast save active $screenshot
}
area() {
- grim -g "$(slurp)" $screenshot
+ grim -g "$(slurp)" $screenshot
}
screen() {
- grim $screenshot
+ grim $screenshot
}
preview() {
- $HOME/.config/eww/scripts/launcher toggle_menu previewshot
+ $HOME/.config/eww/scripts/launcher toggle_menu previewshot
}
discard() {
- rm "${screenshot}"
+ rm "${screenshot}"
}
save() {
- name="screenshot-$(date +%h-%m-%s_%d-%m-%y).png"
- mkdir -p $path
- cp $screenshot $path/$name
- notify-send "screenshot saved!" "saved to ${path}/${name}" -i $screenshot
+ name="screenshot-$(date +%h-%m-%s_%d-%m-%y).png"
+ mkdir -p $path
+ cp $screenshot $path/$name
+ notify-send "screenshot saved!" "saved to ${path}/${name}" -i $screenshot
}
copy() {
- wl-copy <$screenshot
- notify-send "screenshot copied!" -i $screenshot
+ wl-copy <$screenshot
+ notify-send "screenshot copied!" -i $screenshot
}
case $1 in
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/theme b/home/isabel/programs/gui/confs/bars/eww/config/scripts/theme
index ce77467d8..8e2dfee14 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/theme
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/theme
@@ -23,9 +23,9 @@ function get {
icon=''
if [[ $(state) == 'on' ]]; then icon=''; fi
echo "{
- \"state\": \"$(state)\",
- \"icon\": \"$icon\"
- }"
+ \"state\": \"$(state)\",
+ \"icon\": \"$icon\"
+ }"
}
if [[ $1 == 'toggle' ]]; then toggle; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/todo b/home/isabel/programs/gui/confs/bars/eww/config/scripts/todo
index 54c33d433..26ee77125 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/todo
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/todo
@@ -1,367 +1,434 @@
#!/usr/bin/env gjs
-'use strict'
+"use strict";
const { Gio, GLib } = imports.gi;
-const SUBSTITUTES_PATH = GLib.get_home_dir() + '/.local/share/todo/substitutes.json';
-const TASKS_PATH = GLib.get_home_dir() + '/Documents/tasks.json';
+const SUBSTITUTES_PATH =
+ GLib.get_home_dir() + "/.local/share/todo/substitutes.json";
+const TASKS_PATH = GLib.get_home_dir() + "/Documents/tasks.json";
const TERMINAL_WIDTH = 50;
function getSubstitutes() {
- try {
- let file = Gio.File.new_for_path(SUBSTITUTES_PATH);
- let [, contents,] = file.load_contents(null);
- return JSON.parse(new TextDecoder().decode(contents));
- }
- catch {
- return { days: [], months: [] };
- }
+ try {
+ let file = Gio.File.new_for_path(SUBSTITUTES_PATH);
+ let [, contents] = file.load_contents(null);
+ return JSON.parse(new TextDecoder().decode(contents));
+ } catch {
+ return { days: [], months: [] };
+ }
}
function getTasks() {
- try {
- let file = Gio.File.new_for_path(TASKS_PATH);
- let [, contents,] = file.load_contents(null);
- let list = JSON.parse(new TextDecoder().decode(contents));
- let tasks = [];
- list.forEach(t => tasks.push(new Task(t)));
- return tasks;
- }
- catch {
- return [];
- }
+ try {
+ let file = Gio.File.new_for_path(TASKS_PATH);
+ let [, contents] = file.load_contents(null);
+ let list = JSON.parse(new TextDecoder().decode(contents));
+ let tasks = [];
+ list.forEach((t) => tasks.push(new Task(t)));
+ return tasks;
+ } catch {
+ return [];
+ }
}
function writeFile(tasks) {
- let file = Gio.File.new_for_path(TASKS_PATH);
- if (!GLib.file_test(TASKS_PATH, GLib.FileTest.EXISTS))
- file.create(Gio.FileCreateFlags.NONE, null);
-
- file.replace_contents(
- JSON.stringify(tasks, null, 4),
- null, false,
- Gio.FileCreateFlags.REPLACE_DESTINATION, null
- );
+ let file = Gio.File.new_for_path(TASKS_PATH);
+ if (!GLib.file_test(TASKS_PATH, GLib.FileTest.EXISTS))
+ file.create(Gio.FileCreateFlags.NONE, null);
+
+ file.replace_contents(
+ JSON.stringify(tasks, null, 4),
+ null,
+ false,
+ Gio.FileCreateFlags.REPLACE_DESTINATION,
+ null,
+ );
}
class Date {
- constructor(p) {
- this.year = p?.year;
- this.month = p?.month;
- this.day = p?.day;
- this.hour = p?.hour;
- this.minutes = p?.minutes;
- this.asap = p?.asap || false;
-
- if (typeof p === 'string')
- this.fromString(p);
- }
-
- isEmpty() {
- return !this.year && !this.month && !this.day && !this.hour && !this.minutes
- }
-
- isLate() {
- let d = GLib.DateTime.new_now_local();
- if (this.compare(new Date({
- year: d.get_year(),
- month: d.get_month(),
- day: d.get_day_of_month(),
- hour: d.get_hour(),
- minutes: d.get_minute()
- })) < 0) {
- return true;
- }
- return false;
- }
-
- isToday() {
- let now = GLib.DateTime.new_now_local();
- return this.month === now.get_month() &&
- this.day === now.get_day_of_month();
- }
-
- toString() {
- if (this.asap)
- return ' asap! ';
-
- let m, d, h, min, md, hm;
- if (this.month)
- m = `${this.month < 10 ? `0${this.month}` : this.month}`
- else m = '--';
-
- if (this.day)
- d = `${this.day < 10 ? `0${this.day}` : this.day}`;
- else d = '--';
-
- if (this.hour)
- h = `${this.hour < 10 ? `0${this.hour}` : this.hour}`
- else h = '--';
-
- if (this.minutes)
- min = `${this.minutes < 10 ? `0${this.minutes}` : this.minutes}`
- else min = '00';
-
- md = `${m}/${d}`;
- hm = `${h}:${min}`
- if (!this.month && !this.day) md = ' ';
- if (!this.hour && !this.minutes) hm = ' ';
- if (md === ' ' && (this.hour || this.minutes)) md = 'today';
- if (this.isToday()) md = 'today';
-
- return `${md} ${hm}`;
- }
-
- valid() {
- let now = GLib.DateTime.new_now_local();
- let year = this?.year || now.get_year();
- let month = this?.month || now.get_month();
- let day = this?.day || now.get_day_of_month();
- let hour = this?.hour || now.get_hour();
- let minutes = this?.minutes || now.get_minute();
- return GLib.DateTime.new_local(year, month, day, hour, minutes, 0);
- }
-
- compare(d2) {
- if (this.asap) return -1;
- if (d2.asap) return 1;
- if (this.isEmpty() && d2.isEmpty()) return 0;
- if (this.isEmpty()) return 1;
- if (d2.isEmpty()) return -1;
-
- if (this.year > d2.year)
- return 1;
- else if (this.year < d2.year)
- return -1
- else if (this.month > d2.month)
- return 1;
- else if (this.month < d2.month)
- return -1
- else if (this.day > d2.day)
- return 1;
- else if (this.day < d2.day)
- return -1;
- else if (this.hour > d2.hour)
- return 1;
- else if (this.hour < d2.hour)
- return -1;
- else if (this.minutes > d2.minutes)
- return 1;
- else if (this.minutes < d2.minutes)
- return -1;
-
- return 0;
- }
-
- fromString(str) {
- let substitutes = getSubstitutes();
- let days = substitutes.days;
- let months = substitutes.months;
-
- str.split(' ').forEach(e => {
- if (e.toLowerCase() === 'asap') this.asap = true;
- if (days[e]) this.day = days[e];
- if (months[e]) this.month = months[e];
- let md = e.split('/');
- if (md.length === 2) {
- this.month = Number(md[0]);
- this.day = Number(md[1]);
- }
- let hm = e.split(':')
- if (hm.length === 2) {
- this.hour = Number(hm[0]);
- this.minutes = Number(hm[1]);
- }
- let ymd = e.split('/');
- if (ymd.length === 3) {
- this.year = Number(md[0]);
- this.month = Number(md[1]);
- this.day = Number(md[2]);
- }
- if (e.toLowerCase() === "today") {
- let now = GLib.DateTime.new_now_local();
- this.month = now.get_month();
- this.day = now.get_day_of_month();
- }
- })
-
- if (this.year == NaN) this.year = undefined;
- if (this.month == NaN) this.month = undefined;
- if (this.day == NaN) this.day = undefined;
- if (this.hour == NaN) this.hour = undefined;
- if (this.minutes == NaN) this.minutes = undefined;
-
- if (!this.valid()) { throw new Error('Wrong date') }
-
- return this;
- }
+ constructor(p) {
+ this.year = p?.year;
+ this.month = p?.month;
+ this.day = p?.day;
+ this.hour = p?.hour;
+ this.minutes = p?.minutes;
+ this.asap = p?.asap || false;
+
+ if (typeof p === "string") this.fromString(p);
+ }
+
+ isEmpty() {
+ return (
+ !this.year &&
+ !this.month &&
+ !this.day &&
+ !this.hour &&
+ !this.minutes
+ );
+ }
+
+ isLate() {
+ let d = GLib.DateTime.new_now_local();
+ if (
+ this.compare(
+ new Date({
+ year: d.get_year(),
+ month: d.get_month(),
+ day: d.get_day_of_month(),
+ hour: d.get_hour(),
+ minutes: d.get_minute(),
+ }),
+ ) < 0
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+ isToday() {
+ let now = GLib.DateTime.new_now_local();
+ return (
+ this.month === now.get_month() &&
+ this.day === now.get_day_of_month()
+ );
+ }
+
+ toString() {
+ if (this.asap) return " asap! ";
+
+ let m, d, h, min, md, hm;
+ if (this.month)
+ m = `${this.month < 10 ? `0${this.month}` : this.month}`;
+ else m = "--";
+
+ if (this.day) d = `${this.day < 10 ? `0${this.day}` : this.day}`;
+ else d = "--";
+
+ if (this.hour) h = `${this.hour < 10 ? `0${this.hour}` : this.hour}`;
+ else h = "--";
+
+ if (this.minutes)
+ min = `${this.minutes < 10 ? `0${this.minutes}` : this.minutes}`;
+ else min = "00";
+
+ md = `${m}/${d}`;
+ hm = `${h}:${min}`;
+ if (!this.month && !this.day) md = " ";
+ if (!this.hour && !this.minutes) hm = " ";
+ if (md === " " && (this.hour || this.minutes)) md = "today";
+ if (this.isToday()) md = "today";
+
+ return `${md} ${hm}`;
+ }
+
+ valid() {
+ let now = GLib.DateTime.new_now_local();
+ let year = this?.year || now.get_year();
+ let month = this?.month || now.get_month();
+ let day = this?.day || now.get_day_of_month();
+ let hour = this?.hour || now.get_hour();
+ let minutes = this?.minutes || now.get_minute();
+ return GLib.DateTime.new_local(year, month, day, hour, minutes, 0);
+ }
+
+ compare(d2) {
+ if (this.asap) return -1;
+ if (d2.asap) return 1;
+ if (this.isEmpty() && d2.isEmpty()) return 0;
+ if (this.isEmpty()) return 1;
+ if (d2.isEmpty()) return -1;
+
+ if (this.year > d2.year) return 1;
+ else if (this.year < d2.year) return -1;
+ else if (this.month > d2.month) return 1;
+ else if (this.month < d2.month) return -1;
+ else if (this.day > d2.day) return 1;
+ else if (this.day < d2.day) return -1;
+ else if (this.hour > d2.hour) return 1;
+ else if (this.hour < d2.hour) return -1;
+ else if (this.minutes > d2.minutes) return 1;
+ else if (this.minutes < d2.minutes) return -1;
+
+ return 0;
+ }
+
+ fromString(str) {
+ let substitutes = getSubstitutes();
+ let days = substitutes.days;
+ let months = substitutes.months;
+
+ str.split(" ").forEach((e) => {
+ if (e.toLowerCase() === "asap") this.asap = true;
+ if (days[e]) this.day = days[e];
+ if (months[e]) this.month = months[e];
+ let md = e.split("/");
+ if (md.length === 2) {
+ this.month = Number(md[0]);
+ this.day = Number(md[1]);
+ }
+ let hm = e.split(":");
+ if (hm.length === 2) {
+ this.hour = Number(hm[0]);
+ this.minutes = Number(hm[1]);
+ }
+ let ymd = e.split("/");
+ if (ymd.length === 3) {
+ this.year = Number(md[0]);
+ this.month = Number(md[1]);
+ this.day = Number(md[2]);
+ }
+ if (e.toLowerCase() === "today") {
+ let now = GLib.DateTime.new_now_local();
+ this.month = now.get_month();
+ this.day = now.get_day_of_month();
+ }
+ });
+
+ if (this.year == NaN) this.year = undefined;
+ if (this.month == NaN) this.month = undefined;
+ if (this.day == NaN) this.day = undefined;
+ if (this.hour == NaN) this.hour = undefined;
+ if (this.minutes == NaN) this.minutes = undefined;
+
+ if (!this.valid()) {
+ throw new Error("Wrong date");
+ }
+
+ return this;
+ }
}
class Task {
- constructor(p) {
- this.title = p?.title,
- this.desc = p?.desc,
- this.date = new Date(p?.date)
- }
-
- parseDate(date) { this.date.fromString(date); }
+ constructor(p) {
+ (this.title = p?.title),
+ (this.desc = p?.desc),
+ (this.date = new Date(p?.date));
+ }
+
+ parseDate(date) {
+ this.date.fromString(date);
+ }
}
function add(input = {}) {
- if (!input.title) throw new Error('Needs a title');
- let tasks = getTasks();
- tasks.push(new Task(input));
- tasks.sort((a, b) => a.date.compare(b.date));
- writeFile(tasks);
+ if (!input.title) throw new Error("Needs a title");
+ let tasks = getTasks();
+ tasks.push(new Task(input));
+ tasks.sort((a, b) => a.date.compare(b.date));
+ writeFile(tasks);
}
function remove(input = {}) {
- let tasks = getTasks();
- input.remove.split(' ').forEach(i => {
- if (!tasks[i - 1]) throw new Error('Index not found.');
- tasks[i - 1] = null
- });
- writeFile(tasks.filter(t => t != null));
+ let tasks = getTasks();
+ input.remove.split(" ").forEach((i) => {
+ if (!tasks[i - 1]) throw new Error("Index not found.");
+ tasks[i - 1] = null;
+ });
+ writeFile(tasks.filter((t) => t != null));
}
function mod(input = {}) {
- let tasks = getTasks();
+ let tasks = getTasks();
- if (isNaN(Number(input.mod)) || !tasks[Number(input.mod) - 1])
- throw new Error('Index not found.');
+ if (isNaN(Number(input.mod)) || !tasks[Number(input.mod) - 1])
+ throw new Error("Index not found.");
- let task = tasks[Number(input.mod) - 1]
- if (input.title) task.title = input.title;
- if (input.date) task.date = (new Date()).fromString(input.date);
- if (input.desc) task.desc = input.desc;
- tasks.sort((a, b) => a.date.compare(b.date));
- writeFile(tasks);
+ let task = tasks[Number(input.mod) - 1];
+ if (input.title) task.title = input.title;
+ if (input.date) task.date = new Date().fromString(input.date);
+ if (input.desc) task.desc = input.desc;
+ tasks.sort((a, b) => a.date.compare(b.date));
+ writeFile(tasks);
}
function printTasks(input = {}) {
- let width = input.terminal_width || TERMINAL_WIDTH
- let sepLine = '', sepSpace = '';
- for (let i = 0; i < width; i++) {
- sepLine += '─';
- sepSpace += ' ';
- }
- let tasks = getTasks();
-
- print('')
- print(` ╭${sepLine.substring(3)}╮`)
- print(` │ Deadline Task${sepSpace.substring(27)}│`);
- print(` ├${sepLine.substring(3)}┤`);
- for (let i = 0; i < tasks.length; ++i) {
- let title = tasks[i].title;
- let date = tasks[i].date.toString();
- let w = width - 24;
-
- print(` │ ${date} ${i + 1}.${i < 9 ? ' ' : ''} ${title.substring(0, w)}${sepSpace.substring(title.length + 24)} │`);
-
- // line break if title exceeds width
- title = title.substring(w)
- for (let i = 0; i < Math.floor(title.length / (w)) + 1; ++i) {
- if (title[i * (w)] === ' ') //dont start line with space
- title = title.substring(0, i * (w) - 1) + title.substring(i * (w))
-
- let line = title.substring(i * (w), (i + 1) * (w));
- let spaceBefore = sepSpace.substring(0, width - w - 6);
- if (line !== '')
- print(` │ ${spaceBefore} ${line}${sepSpace.substring(spaceBefore.length + line.length + 6)} │`);
- }
- }
- print(` ╰${sepLine.substring(3)}╯`)
+ let width = input.terminal_width || TERMINAL_WIDTH;
+ let sepLine = "",
+ sepSpace = "";
+ for (let i = 0; i < width; i++) {
+ sepLine += "─";
+ sepSpace += " ";
+ }
+ let tasks = getTasks();
+
+ print("");
+ print(` ╭${sepLine.substring(3)}╮`);
+ print(` │ Deadline Task${sepSpace.substring(27)}│`);
+ print(` ├${sepLine.substring(3)}┤`);
+ for (let i = 0; i < tasks.length; ++i) {
+ let title = tasks[i].title;
+ let date = tasks[i].date.toString();
+ let w = width - 24;
+
+ print(
+ ` │ ${date} ${i + 1}.${i < 9 ? " " : ""} ${title.substring(
+ 0,
+ w,
+ )}${sepSpace.substring(title.length + 24)} │`,
+ );
+
+ // line break if title exceeds width
+ title = title.substring(w);
+ for (let i = 0; i < Math.floor(title.length / w) + 1; ++i) {
+ if (title[i * w] === " ")
+ //dont start line with space
+ title = title.substring(0, i * w - 1) + title.substring(i * w);
+
+ let line = title.substring(i * w, (i + 1) * w);
+ let spaceBefore = sepSpace.substring(0, width - w - 6);
+ if (line !== "")
+ print(
+ ` │ ${spaceBefore} ${line}${sepSpace.substring(
+ spaceBefore.length + line.length + 6,
+ )} │`,
+ );
+ }
+ }
+ print(` ╰${sepLine.substring(3)}╯`);
}
function eww() {
- let out = [], id = 1;
- let tasks = getTasks();
- tasks.forEach(t => t.id = id++);
- tasks.filter(t => t.date.month || t.date.day || t.date.hour || t.date.asap)
- .forEach(t => out.push({
- asap: t.date.asap || t.date.isLate(),
- date: t.date.toString(),
- title: t.title,
- id: t.id
- }))
-
- print(JSON.stringify(out, null, 3));
+ let out = [],
+ id = 1;
+ let tasks = getTasks();
+ tasks.forEach((t) => (t.id = id++));
+ tasks
+ .filter((t) => t.date.month || t.date.day || t.date.hour || t.date.asap)
+ .forEach((t) =>
+ out.push({
+ asap: t.date.asap || t.date.isLate(),
+ date: t.date.toString(),
+ title: t.title,
+ id: t.id,
+ }),
+ );
+
+ print(JSON.stringify(out, null, 3));
}
function getDesc(input = {}) {
- let tasks = getTasks();
- if (!tasks[input.get_desc - 1]) throw new Error('Index not found.');
-
- let width = input.terminal_width || TERMINAL_WIDTH
- let sepLine = '', sepSpace = '';
- for (let i = 0; i < width; i++) {
- sepLine += '─';
- sepSpace += ' ';
- }
-
- let title = tasks[input.get_desc - 1].title
- let desc = tasks[input.get_desc - 1].desc || "No description for this task."
- print('')
- print(` ╭${sepLine.substring(3)}╮`)
- print(` │ ${title}${sepSpace.substring(title.length + 4)}│`);
- print(` ├${sepLine.substring(3)}┤`);
-
- let w = width - 5;
- for (let i = 0; i < Math.floor(desc.length / (w)) + 1; ++i) {
- if (desc[i * (w)] === ' ') //dont start line with space
- desc = desc.substring(0, i * (w) - 1) + desc.substring(i * (w))
-
- let line = desc.substring(i * (w), (i + 1) * (w));
- print(` │ ${line}${sepSpace.substring(line.length + 4)}│`);
- }
- print(` ╰${sepLine.substring(3)}╯`)
+ let tasks = getTasks();
+ if (!tasks[input.get_desc - 1]) throw new Error("Index not found.");
+
+ let width = input.terminal_width || TERMINAL_WIDTH;
+ let sepLine = "",
+ sepSpace = "";
+ for (let i = 0; i < width; i++) {
+ sepLine += "─";
+ sepSpace += " ";
+ }
+
+ let title = tasks[input.get_desc - 1].title;
+ let desc =
+ tasks[input.get_desc - 1].desc || "No description for this task.";
+ print("");
+ print(` ╭${sepLine.substring(3)}╮`);
+ print(` │ ${title}${sepSpace.substring(title.length + 4)}│`);
+ print(` ├${sepLine.substring(3)}┤`);
+
+ let w = width - 5;
+ for (let i = 0; i < Math.floor(desc.length / w) + 1; ++i) {
+ if (desc[i * w] === " ")
+ //dont start line with space
+ desc = desc.substring(0, i * w - 1) + desc.substring(i * w);
+
+ let line = desc.substring(i * w, (i + 1) * w);
+ print(` │ ${line}${sepSpace.substring(line.length + 4)}│`);
+ }
+ print(` ╰${sepLine.substring(3)}╯`);
}
function main() {
- if (!ARGV[0]) return printTasks();
-
- let input = {};
-
- for (let i = 0; i < ARGV.length; ++i) {
-
- let arg = []; let cmd = ARGV[i];
- for (let j = i + 1; j < ARGV.length && ARGV[j][0] !== '-'; ++j)
- arg.push(ARGV[j]);
-
- switch (cmd) {
- case '--eww': input.eww = true; break;
- case '-m': input.mod = arg.join(' '); break;
- case '--mod': input.mod = arg.join(' '); break;
- case '-t': input.title = arg.join(' '); break;
- case '--title': input.title = arg.join(' '); break;
- case '-a': input.title = arg.join(' '); break;
- case '--add': input.title = arg.join(' '); break;
- case '-D': input.desc = arg.join(' '); break;
- case '--description': input.desc = arg.join(' '); break;
- case '--desc': input.desc = arg.join(' '); break;
- case '-d': input.date = arg.join(' '); break;
- case '--date': input.date = arg.join(' '); break;
- case '--due': input.date = arg.join(' '); break;
- case '-r': input.remove = arg.join(' '); break;
- case '--remove': input.remove = arg.join(' '); break;
- case '--rem': input.remove = arg.join(' '); break;
- case '-w': input.terminal_width = arg.join(' '); break;
- case '--width': input.terminal_width = arg.join(' '); break;
- case '-w': input.terminal_width = arg.join(' '); break;
- case '--width': input.terminal_width = arg.join(' '); break;
- case '-g': input.get_desc = arg.join(' '); break;
- case '--get-desc': input.get_desc = arg.join(' '); break;
- default: input.title = cmd + ' ' + arg.join(' '); break;
- }
- i += arg.length;
- }
-
- if (input.remove) remove(input);
- else if (input.mod) mod(input);
- else if (input.eww) eww();
- else if (input.get_desc) getDesc(input);
- else if (input.title) add(input);
-
- if (!input.eww && !input.get_desc) printTasks(input);
+ if (!ARGV[0]) return printTasks();
+
+ let input = {};
+
+ for (let i = 0; i < ARGV.length; ++i) {
+ let arg = [];
+ let cmd = ARGV[i];
+ for (let j = i + 1; j < ARGV.length && ARGV[j][0] !== "-"; ++j)
+ arg.push(ARGV[j]);
+
+ switch (cmd) {
+ case "--eww":
+ input.eww = true;
+ break;
+ case "-m":
+ input.mod = arg.join(" ");
+ break;
+ case "--mod":
+ input.mod = arg.join(" ");
+ break;
+ case "-t":
+ input.title = arg.join(" ");
+ break;
+ case "--title":
+ input.title = arg.join(" ");
+ break;
+ case "-a":
+ input.title = arg.join(" ");
+ break;
+ case "--add":
+ input.title = arg.join(" ");
+ break;
+ case "-D":
+ input.desc = arg.join(" ");
+ break;
+ case "--description":
+ input.desc = arg.join(" ");
+ break;
+ case "--desc":
+ input.desc = arg.join(" ");
+ break;
+ case "-d":
+ input.date = arg.join(" ");
+ break;
+ case "--date":
+ input.date = arg.join(" ");
+ break;
+ case "--due":
+ input.date = arg.join(" ");
+ break;
+ case "-r":
+ input.remove = arg.join(" ");
+ break;
+ case "--remove":
+ input.remove = arg.join(" ");
+ break;
+ case "--rem":
+ input.remove = arg.join(" ");
+ break;
+ case "-w":
+ input.terminal_width = arg.join(" ");
+ break;
+ case "--width":
+ input.terminal_width = arg.join(" ");
+ break;
+ case "-w":
+ input.terminal_width = arg.join(" ");
+ break;
+ case "--width":
+ input.terminal_width = arg.join(" ");
+ break;
+ case "-g":
+ input.get_desc = arg.join(" ");
+ break;
+ case "--get-desc":
+ input.get_desc = arg.join(" ");
+ break;
+ default:
+ input.title = cmd + " " + arg.join(" ");
+ break;
+ }
+ i += arg.length;
+ }
+
+ if (input.remove) remove(input);
+ else if (input.mod) mod(input);
+ else if (input.eww) eww();
+ else if (input.get_desc) getDesc(input);
+ else if (input.title) add(input);
+
+ if (!input.eww && !input.get_desc) printTasks(input);
}
-main()
+main();
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scripts/volume b/home/isabel/programs/gui/confs/bars/eww/config/scripts/volume
index e5e3af273..4aeae8952 100755
--- a/home/isabel/programs/gui/confs/bars/eww/config/scripts/volume
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scripts/volume
@@ -3,89 +3,89 @@ VOLUME=$(pamixer --get-volume)
MUTED=$(pamixer --get-mute)
function icon {
- if [[ $MUTED == false ]]; then
- if [[ $VOLUME -ge 66 ]]; then
- echo ''
- elif [[ $VOLUME -ge 33 ]]; then
- echo ''
- elif [[ $VOLUME -ge 1 ]]; then
- echo ''
- else
- echo ''
- fi
- else
- echo ''
- fi
+ if [[ $MUTED == false ]]; then
+ if [[ $VOLUME -ge 66 ]]; then
+ echo ''
+ elif [[ $VOLUME -ge 33 ]]; then
+ echo ''
+ elif [[ $VOLUME -ge 1 ]]; then
+ echo ''
+ else
+ echo ''
+ fi
+ else
+ echo ''
+ fi
}
function level {
- if [[ $MUTED == true ]]; then
- echo 0
- else
- echo $VOLUME
- fi
+ if [[ $MUTED == true ]]; then
+ echo 0
+ else
+ echo $VOLUME
+ fi
}
function lower {
- pamixer -d 5
- update
+ pamixer -d 5
+ update
}
function raise {
- pamixer -i 5
- update
+ pamixer -i 5
+ update
}
function mute {
- pamixer --toggle-mute
+ pamixer --toggle-mute
}
function update {
- eww update volume="$(get)"
- ~/.config/eww/scripts/osd $(icon) $(level)
+ eww update volume="$(get)"
+ ~/.config/eww/scripts/osd $(icon) $(level)
}
function type_icon {
- echo ""
- #else
- # echo ""
- #fi
+ echo ""
+ #else
+ # echo ""
+ #fi
}
function mic_mute_state {
- STATE=$(pamixer --default-source --get-mute)
- if [[ $STATE == false ]]; then
- echo 'off'
- else echo 'on'; fi
+ STATE=$(pamixer --default-source --get-mute)
+ if [[ $STATE == false ]]; then
+ echo 'off'
+ else echo 'on'; fi
}
function mic_mute_icon {
- STATE=$(mic_mute_state)
- if [[ $STATE == 'off' ]]; then
- echo ''
- else echo ''; fi
+ STATE=$(mic_mute_state)
+ if [[ $STATE == 'off' ]]; then
+ echo ''
+ else echo ''; fi
}
function mute_mic {
- pamixer --default-source -t
- eww update volume="$(get)"
+ pamixer --default-source -t
+ eww update volume="$(get)"
}
function set {
- pamixer --set-volume $1
- eww update volume="$(get)"
+ pamixer --set-volume $1
+ eww update volume="$(get)"
}
function get {
- echo "{
- \"level\": \"$(level)\",
- \"icon\": \"$(icon)\",
- \"type_icon\": \"$(type_icon)\",
- \"mute\": {
- \"state\": \"$(mic_mute_state)\",
- \"icon\": \"$(mic_mute_icon)\"
-}
-}"
+ echo "{
+ \"level\": \"$(level)\",
+ \"icon\": \"$(icon)\",
+ \"type_icon\": \"$(type_icon)\",
+ \"mute\": {
+ \"state\": \"$(mic_mute_state)\",
+ \"icon\": \"$(mic_mute_icon)\"
+ }
+ }"
}
if [[ $1 == 'mute_mic' ]]; then mute_mic; fi
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/colors.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/colors.scss
index 9c68e6070..2d24d3a05 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/colors.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/colors.scss
@@ -1,4 +1,4 @@
-$theme: 'dark';
+$theme: "dark";
$red: #f38ba8;
$green: #f38ba8;
@@ -12,4 +12,4 @@ $bg_color: #1e1e2e;
$fg_color: #cdd6f4;
$hover_fg: #cdd6f4;
$accent_fg: #11111b;
-$accent: #75c7ec;
\ No newline at end of file
+$accent: #75c7ec;
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_dark.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_dark.scss
index 9c68e6070..2d24d3a05 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_dark.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_dark.scss
@@ -1,4 +1,4 @@
-$theme: 'dark';
+$theme: "dark";
$red: #f38ba8;
$green: #f38ba8;
@@ -12,4 +12,4 @@ $bg_color: #1e1e2e;
$fg_color: #cdd6f4;
$hover_fg: #cdd6f4;
$accent_fg: #11111b;
-$accent: #75c7ec;
\ No newline at end of file
+$accent: #75c7ec;
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_light.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_light.scss
index 6e79d13dc..0d8698e71 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_light.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/colors_light.scss
@@ -1,4 +1,4 @@
-$theme: 'light';
+$theme: "light";
$red: #d20f39;
$green: #40a02b;
@@ -12,4 +12,4 @@ $bg_color: #eff1f5;
$fg_color: #4c4f69;
$hover_fg: #4c4f69;
$accent_fg: #dce0e8;
-$accent: #209fb5;
\ No newline at end of file
+$accent: #209fb5;
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/common.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/common.scss
index 2756b95ff..a8ed1e49b 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/common.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/common.scss
@@ -1,149 +1,162 @@
@mixin widget($radii: $widget_radius) {
- border-radius: $radii;
- color: $fg_color;
- background-color: $widget_bg;
- box-shadow: inset 0 0 0 $border_width $border_color;
+ border-radius: $radii;
+ color: $fg_color;
+ background-color: $widget_bg;
+ box-shadow: inset 0 0 0 $border_width $border_color;
}
-@mixin button($flat: false, $interactive: true, $radii: $radii, $focusable: false) {
- border-radius: $radii;
- color: $fg_color;
-
- @if $flat {
- background-color: transparent;
- background-image: none;
- box-shadow: none;
- }
-
- @else {
- background-color: $button_bg;
- box-shadow: inset 0 0 0 $border_width $border_color;
- }
-
- @if $interactive {
- @if $focusable {
- &:focus {
- box-shadow: inset 0 0 0 $border_width $accent;
- background-color: $hover;
- color: $hover_fg;
- }
- }
-
- &:hover {
- box-shadow: inset 0 0 0 $border_width $border_color;
- background-color: $hover;
- color: $hover_fg;
- }
-
- &:active {
- box-shadow: inset 0 0 0 $border_width $border_color;
- background-color: $accent;
- color: $accent_fg;
- }
- }
+@mixin button(
+ $flat: false,
+ $interactive: true,
+ $radii: $radii,
+ $focusable: false
+) {
+ border-radius: $radii;
+ color: $fg_color;
+
+ @if $flat {
+ background-color: transparent;
+ background-image: none;
+ box-shadow: none;
+ } @else {
+ background-color: $button_bg;
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ }
+
+ @if $interactive {
+ @if $focusable {
+ &:focus {
+ box-shadow: inset 0 0 0 $border_width $accent;
+ background-color: $hover;
+ color: $hover_fg;
+ }
+ }
+
+ &:hover {
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ background-color: $hover;
+ color: $hover_fg;
+ }
+
+ &:active {
+ box-shadow: inset 0 0 0 $border_width $border_color;
+ background-color: $accent;
+ color: $accent_fg;
+ }
+ }
}
@mixin floating_widget($shadow: true, $padding: $popover_padding) {
- @if $shadow {
- box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.6),
- inset 0 0 0 $border_width $popover_border_color;
- }
-
- @else {
- box-shadow: inset 0 0 0 $border_width $popover_border_color;
- }
-
- border-radius: $popover_radius;
- margin: $wm_gaps;
- background-color: $bg_color;
- color: $fg_color;
- padding: $padding;
+ @if $shadow {
+ box-shadow:
+ 0 0 5px 0 rgba(0, 0, 0, 0.6),
+ inset 0 0 0 $border_width $popover_border_color;
+ } @else {
+ box-shadow: inset 0 0 0 $border_width $popover_border_color;
+ }
+
+ border-radius: $popover_radius;
+ margin: $wm_gaps;
+ background-color: $bg_color;
+ color: $fg_color;
+ padding: $padding;
}
-@mixin slider($width: .4em, $color: $accent, $slider: true, $focusable: false) {
- trough {
- border-radius: $button_radius;
- border: $border;
- background-color: $button_bg;
- min-height: $width;
- min-width: $width;
-
- highlight,
- progress {
- border-radius: $popover_radius*0.8;
- background-color: $color;
- min-height: $width;
- min-width: $width;
- }
-
- slider {
- @if $slider {
- background-color: $fg_color;
- border-radius: $button_radius;
- border: $border;
- min-height: $width;
- min-width: $width;
- }
- }
- }
-
- &:hover trough {
- background-color: $hover;
- }
-
- @if $focusable {
- trough:focus {
- background-color: $hover;
- box-shadow: inset 0 0 0 $border_width $accent;
-
- highlight,
- progress {
- background-color: transparentize($color, 0.3);
- }
- }
- }
+@mixin slider(
+ $width: 0.4em,
+ $color: $accent,
+ $slider: true,
+ $focusable: false
+) {
+ trough {
+ border-radius: $button_radius;
+ border: $border;
+ background-color: $button_bg;
+ min-height: $width;
+ min-width: $width;
+
+ highlight,
+ progress {
+ border-radius: $popover_radius * 0.8;
+ background-color: $color;
+ min-height: $width;
+ min-width: $width;
+ }
+
+ slider {
+ @if $slider {
+ background-color: $fg_color;
+ border-radius: $button_radius;
+ border: $border;
+ min-height: $width;
+ min-width: $width;
+ }
+ }
+ }
+
+ &:hover trough {
+ background-color: $hover;
+ }
+
+ @if $focusable {
+ trough:focus {
+ background-color: $hover;
+ box-shadow: inset 0 0 0 $border_width $accent;
+
+ highlight,
+ progress {
+ background-color: transparentize($color, 0.3);
+ }
+ }
+ }
}
@mixin darkened($radii: 0) {
- border-radius: $radii*0.99;
+ border-radius: $radii * 0.99;
- @if $theme =='dark' {
- box-shadow: inset 0 0 3em 1em transparentize($bg_color, 0.1);
- }
+ @if $theme == "dark" {
+ box-shadow: inset 0 0 3em 1em transparentize($bg_color, 0.1);
+ }
- @if $theme =='light' {
- background-color: transparentize($bg_color, 0.5);
- }
+ @if $theme == "light" {
+ background-color: transparentize($bg_color, 0.5);
+ }
}
@mixin tooltip {
- >*>* {
- background-color: $bg_color;
- border-radius: $button_radius;
- border: $border_width solid $popover_border_color;
- color: $fg_color;
- padding: 8px;
- margin: 4px;
- box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.4);
- }
+ > * > * {
+ background-color: $bg_color;
+ border-radius: $button_radius;
+ border: $border_width solid $popover_border_color;
+ color: $fg_color;
+ padding: 8px;
+ margin: 4px;
+ box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.4);
+ }
}
-@mixin scrollbar{
- scrollbar.vertical{
- slider{
- background: $widget_bg;
- border-radius: $radii;
- min-width: .6em;
- min-height: 2em;
- }
- }
- overshoot{
- border-radius: $radii;
- &.top{
- background: linear-gradient(transparentize($bg_color, 0.6), transparent);
- }
- &.bottom{
- background: linear-gradient(transparent,transparentize($bg_color, 0.6));
- }
- }
+@mixin scrollbar {
+ scrollbar.vertical {
+ slider {
+ background: $widget_bg;
+ border-radius: $radii;
+ min-width: 0.6em;
+ min-height: 2em;
+ }
+ }
+ overshoot {
+ border-radius: $radii;
+ &.top {
+ background: linear-gradient(
+ transparentize($bg_color, 0.6),
+ transparent
+ );
+ }
+ &.bottom {
+ background: linear-gradient(
+ transparent,
+ transparentize($bg_color, 0.6)
+ );
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/variables.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/variables.scss
index 31b07a4fa..c1fdadb54 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/variables.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/variables.scss
@@ -1,7 +1,7 @@
-$assets: './assets/';
-$pic_dir = '/home/isabel/media/pictures/';
-$wallpaper: $pic_dir + 'wallpapers/tempest.png';
-$avatar: $pic_dir + 'pfps/avatar';
+$assets: "./assets/";
+$pic_dir: "/home/isabel/media/pictures/";
+$wallpaper: $pic_dir + "wallpapers/tempest.png";
+$avatar: $pic_dir + "pfps/avatar";
$hover: transparentize($fg_color, 0.84);
@@ -31,10 +31,10 @@ $popover_border_color: rgba(255, 255, 255, 0.02);
$popover_padding: 14px;
* {
- all: unset;
- font-size: 14px;
- font-family: 'Ubuntu Nerd Font';
- transition: 200ms;
+ all: unset;
+ font-size: 14px;
+ font-family: "Ubuntu Nerd Font";
+ transition: 200ms;
}
-$mono_font: 'mononoki Nerd Font';
+$mono_font: "mononoki Nerd Font";
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/bar_widget.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/bar_widget.scss
index 5b85d5e95..691410b56 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/bar_widget.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/bar_widget.scss
@@ -1,61 +1,102 @@
@mixin system-indicators($orientation) {
- @include button($flat: false, $radii: $panel_button_radius);
- .reveal{
- @if $orientation == 'v' { padding-top: .5em; }
- @if $orientation == 'h' { padding-left: .2em;}
- }
- .slider{
- @include slider($width: 1em, $slider: false);
- @if $orientation == 'v' { > * { min-height: 80px; } }
- @if $orientation == 'h' { > * { min-width: 90px; } }
- }
- .icon{
- margin: .1em 0;
- &.battery{
- &.low{ color: $destructive; }
- &.charging{ color: $succes; }
- &.charged{ color: $succes; }
- }
- &.notifications.active{
- color: $yellow;
- }
- &.network{
- &.none, &.low{ color: $red; }
- &.medium{}
- &.high{ color: $blue; }
- }
- &.bluetooth, &.bt_speaker{
- color: $blue;
- }
- }
+ @include button($flat: false, $radii: $panel_button_radius);
+ .reveal {
+ @if $orientation == "v" {
+ padding-top: 0.5em;
+ }
+ @if $orientation == "h" {
+ padding-left: 0.2em;
+ }
+ }
+ .slider {
+ @include slider($width: 1em, $slider: false);
+ @if $orientation == "v" {
+ > * {
+ min-height: 80px;
+ }
+ }
+ @if $orientation == "h" {
+ > * {
+ min-width: 90px;
+ }
+ }
+ }
+ .icon {
+ margin: 0.1em 0;
+ &.battery {
+ &.low {
+ color: $destructive;
+ }
+ &.charging {
+ color: $succes;
+ }
+ &.charged {
+ color: $succes;
+ }
+ }
+ &.notifications.active {
+ color: $yellow;
+ }
+ &.network {
+ &.none,
+ &.low {
+ color: $red;
+ }
+ &.medium {
+ }
+ &.high {
+ color: $blue;
+ }
+ }
+ &.bluetooth,
+ &.bt_speaker {
+ color: $blue;
+ }
+ }
}
@mixin panel_media() {
- .player{
- @include button($flat: true, $radii: $panel_button_radius);
- }
- .controls{
- @include button($radii: $panel_button_radius);
- button {
- &.prev, &.next, &.play-pause{
- color: transparentize($fg_color, 0.3);
- &:hover{ color: transparentize($fg_color, 0.15) }
- &:active{ color: $fg_color }
- }
- }
- }
- .icon{
- &.spotify{ color: $green; }
- &.firefox{ color: $orange; }
- &.mpv{ color: $magenta; }
- }
+ .player {
+ @include button($flat: true, $radii: $panel_button_radius);
+ }
+ .controls {
+ @include button($radii: $panel_button_radius);
+ button {
+ &.prev,
+ &.next,
+ &.play-pause {
+ color: transparentize($fg_color, 0.3);
+ &:hover {
+ color: transparentize($fg_color, 0.15);
+ }
+ &:active {
+ color: $fg_color;
+ }
+ }
+ }
+ }
+ .icon {
+ &.spotify {
+ color: $green;
+ }
+ &.firefox {
+ color: $orange;
+ }
+ &.mpv {
+ color: $magenta;
+ }
+ }
}
@mixin workspaces() {
- @include button($flat: false, $radii: $panel_button_radius);
- .workspace-btn{
- color: $fg_color;
- .focus{ color: $accent; }
- &:hover{ color: darken($fg_color, 0.3); }
- }
+ @include button($flat: false, $radii: $panel_button_radius);
+ .workspace-btn {
+ color: $fg_color;
+ .focus {
+ color: $accent;
+ }
+ &:hover {
+ color: darken($fg_color, 0.3);
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/calendar.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/calendar.scss
index 992cd8c53..6f79c2095 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/calendar.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/calendar.scss
@@ -1,31 +1,31 @@
@mixin calendar() {
- calendar {
- &.button {
- @include button($flat: true);
- margin: 1em;
- }
+ calendar {
+ &.button {
+ @include button($flat: true);
+ margin: 1em;
+ }
- &:selected {
- border: 2px solid $accent;
- border-radius: $button_radius;
- }
+ &:selected {
+ border: 2px solid $accent;
+ border-radius: $button_radius;
+ }
- &.header {
- background-color: transparent;
- border: none;
- color: transparentize($fg_color, 0.5);
- }
+ &.header {
+ background-color: transparent;
+ border: none;
+ color: transparentize($fg_color, 0.5);
+ }
- &.highlight {
- background-color: transparent;
- color: transparentize($accent, 0.5);
- }
+ &.highlight {
+ background-color: transparent;
+ color: transparentize($accent, 0.5);
+ }
- &:indeterminate {
- color: transparentize($fg_color, 0.9);
- }
+ &:indeterminate {
+ color: transparentize($fg_color, 0.9);
+ }
- font-size: 1.2em;
- padding: .2em;
- }
-}
\ No newline at end of file
+ font-size: 1.2em;
+ padding: 0.2em;
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/events.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/events.scss
index 0cdac1fca..7590101bc 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/events.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/events.scss
@@ -1,24 +1,49 @@
-@mixin events{
- label{ font-size: 1.1em; }
- .title-box{
- padding: $spacing;
- border-bottom: 1px solid transparentize($fg_color, 0.9);
- label{ font-size: 1.1em; }
- }
- .events-box{ padding: $spacing; }
- .event{
- .deadline{
- color: transparentize($fg_color, 0.5);
- font-family: $mono_font;
- }
- &.done{
- label{ text-decoration: line-through };
- .title{ color: $green }
- .deadline{ color: transparentize($green ,0.5) }
- }
- &.upcoming{
- .title{ color: $red }
- .deadline{ color: transparentize($red ,0.5) }
- }
- }
+@mixin events {
+ label {
+ font-size: 1.1em;
+ }
+
+ .title-box {
+ padding: $spacing;
+ border-bottom: 1px solid transparentize($fg_color, 0.9);
+
+ label {
+ font-size: 1.1em;
+ }
+ }
+
+ .events-box {
+ padding: $spacing;
+ }
+
+ .event {
+ .deadline {
+ color: transparentize($fg_color, 0.5);
+ font-family: $mono_font;
+ }
+
+ &.done {
+ label {
+ text-decoration: line-through;
+ }
+
+ .title {
+ color: $green;
+ }
+
+ .deadline {
+ color: transparentize($green, 0.5);
+ }
+ }
+
+ &.upcoming {
+ .title {
+ color: $red;
+ }
+
+ .deadline {
+ color: transparentize($red, 0.5);
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/media.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/media.scss
index 3c6a0152e..c640a1434 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/media.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/media.scss
@@ -1,94 +1,150 @@
-@mixin media($style: 'widget', $height: 12em) {
- @if $style == 'widget' { @include widget; }
- @if $style == 'popover' { @include floating_widget; }
- border-radius: $radii;
- margin: $spacing;
- min-height: $height;
- padding: 0;
- text-shadow: $text_shadow;
- .cover{
- @if $style == 'widget' { @include widget; }
- @if $style == 'popover' { border-radius: $radii; }
- background-size: cover;
- background-position: center;
- .darkened{
- @if $style == 'widget' { @include darkened($radii: $button_radius); }
- @if $style == 'popover' { @include darkened($radii: $radii); }
- }
- .slider{
- @include slider($width: .4em, $slider: false, $color: transparentize($fg_color, 0.3));
- scale > contents{
- trough{
- border-radius: 0;
- border: 0;
- highlight{
- border-radius: 0;
- }
- }
- }
- }
- .box{ margin: $spacing; }
- .artist{ font-size: 1.2em; }
- .title, .position{ color: transparentize($fg_color, 0.2);}
- .icon.player{
- font-size: 1.4em;
- margin-left: .6em;
- }
- .controls{
- margin: $spacing;
- button{
- label{ font-size: 2em; }
- &.loop, &.shuffle{
- label{ font-size: 1.2em; }
- }
- color: transparentize($fg_color, 0.3);
- &:hover{ color: $fg_color; }
- &.active{ color: $accent; }
- &.inactive{
- color: transparentize($fg_color, 0.7);
- text-shadow: none;
- }
- &.loop{
- &.Playlist{ color: transparentize($accent, 0.2); }
- &.Track{ color: $accent; }
- }
- }
- }
- }
- .sidebar{
- .slider{ @include slider($width: .6em, $slider: false); }
- margin: $spacing*2;
- }
+@mixin media($style: "widget", $height: 12em) {
+ @if $style == "widget" {
+ @include widget;
+ }
+ @if $style == "popover" {
+ @include floating_widget;
+ }
+ border-radius: $radii;
+ margin: $spacing;
+ min-height: $height;
+ padding: 0;
+ text-shadow: $text_shadow;
+ .cover {
+ @if $style == "widget" {
+ @include widget;
+ }
+ @if $style == "popover" {
+ border-radius: $radii;
+ }
+ background-size: cover;
+ background-position: center;
+ .darkened {
+ @if $style == "widget" {
+ @include darkened($radii: $button_radius);
+ }
+ @if $style == "popover" {
+ @include darkened($radii: $radii);
+ }
+ }
+ .slider {
+ @include slider(
+ $width: 0.4em,
+ $slider: false,
+ $color: transparentize($fg_color, 0.3)
+ );
+ scale > contents {
+ trough {
+ border-radius: 0;
+ border: 0;
+ highlight {
+ border-radius: 0;
+ }
+ }
+ }
+ }
+ .box {
+ margin: $spacing;
+ }
+ .artist {
+ font-size: 1.2em;
+ }
+ .title,
+ .position {
+ color: transparentize($fg_color, 0.2);
+ }
+ .icon.player {
+ font-size: 1.4em;
+ margin-left: 0.6em;
+ }
+ .controls {
+ margin: $spacing;
+ button {
+ label {
+ font-size: 2em;
+ }
+ &.loop,
+ &.shuffle {
+ label {
+ font-size: 1.2em;
+ }
+ }
+ color: transparentize($fg_color, 0.3);
+ &:hover {
+ color: $fg_color;
+ }
+ &.active {
+ color: $accent;
+ }
+ &.inactive {
+ color: transparentize($fg_color, 0.7);
+ text-shadow: none;
+ }
+ &.loop {
+ &.Playlist {
+ color: transparentize($accent, 0.2);
+ }
+ &.Track {
+ color: $accent;
+ }
+ }
+ }
+ }
+ }
+ .sidebar {
+ .slider {
+ @include slider($width: 0.6em, $slider: false);
+ }
+ margin: $spacing * 2;
+ }
- &.spotify{
- .icon.player{ color: $green; }
- .sidebar .slider{
- @include slider($width: .6em, $slider: false, $color: $green);
- }
- .controls button{
- &.active{ color: $green; }
- &.loop{
- &.Playlist{ color: transparentize($green, 0.2); }
- &.Track{ color: $green; }
- }
- }
- }
+ &.spotify {
+ .icon.player {
+ color: $green;
+ }
+ .sidebar .slider {
+ @include slider($width: 0.6em, $slider: false, $color: $green);
+ }
+ .controls button {
+ &.active {
+ color: $green;
+ }
+ &.loop {
+ &.Playlist {
+ color: transparentize($green, 0.2);
+ }
+ &.Track {
+ color: $green;
+ }
+ }
+ }
+ }
- &.firefox{
- .icon.player{ color: $orange; }
- }
+ &.firefox {
+ .icon.player {
+ color: $orange;
+ }
+ }
- &.mpv{
- .icon.player{ color: $magenta; }
- .sidebar .slider{
- @include slider($width: .6em, $slider: false, $color: $magenta);
- }
- .controls button{
- &.active{ color: $magenta; }
- &.loop{
- &.Playlist{ color: transparentize($magenta, 0.2); }
- &.Track{ color: $magenta; }
- }
- }
- }
+ &.mpv {
+ .icon.player {
+ color: $magenta;
+ }
+ .sidebar .slider {
+ @include slider($width: 0.6em, $slider: false, $color: $magenta);
+ }
+ .controls button {
+ &.active {
+ color: $magenta;
+ }
+ &.loop {
+ &.Playlist {
+ color: transparentize($magenta, 0.2);
+ }
+ &.Track {
+ color: $magenta;
+ }
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/notification.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/notification.scss
index 80313253e..5d779bb7c 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/notification.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/notification.scss
@@ -1,56 +1,56 @@
@mixin notification() {
- .notification-content{
- padding: $popover_padding;
- .title{
- font-size: 1.2em;
- font-weight: 600;
- margin-bottom: $popover_padding/2;
- }
- .image{
- min-width: 80px;
- min-height: 80px;
- background-size: cover;
- margin-right: $popover_padding;
- border-radius: $button_radius;
- }
- .action-button{
- @include button;
- font-size: 1.1em;
- font-weight: 500;
- padding: .5em;
- margin-top: $popover_padding;
- &:first-child{
- margin-right: $popover_padding/2;
- }
- &:last-child{
- margin-left: $popover_padding/2;
- }
- &:first-child:last-child{
- margin-left: 0;
- margin-right: 0;
- }
- }
- .close-button{
- min-width: 1.4em;
- min-height: 1.4em;
- }
- .time{
- color: transparentize($fg_color, 0.4);
- margin-right: .4em;
- }
- }
- &:hover{
- .notification-content{
- .close-button{
- @include button;
- background-color: transparentize($red, 0.5);
- &:hover{
- background-color: transparentize($red, 0.3);
- }
- &:active{
- background-color: transparentize($red, 0.1);
- }
- }
- }
- }
+ .notification-content {
+ padding: $popover_padding;
+ .title {
+ font-size: 1.2em;
+ font-weight: 600;
+ margin-bottom: $popover_padding/2;
+ }
+ .image {
+ min-width: 80px;
+ min-height: 80px;
+ background-size: cover;
+ margin-right: $popover_padding;
+ border-radius: $button_radius;
+ }
+ .action-button {
+ @include button;
+ font-size: 1.1em;
+ font-weight: 500;
+ padding: 0.5em;
+ margin-top: $popover_padding;
+ &:first-child {
+ margin-right: $popover_padding/2;
+ }
+ &:last-child {
+ margin-left: $popover_padding/2;
+ }
+ &:first-child:last-child {
+ margin-left: 0;
+ margin-right: 0;
+ }
+ }
+ .close-button {
+ min-width: 1.4em;
+ min-height: 1.4em;
+ }
+ .time {
+ color: transparentize($fg_color, 0.4);
+ margin-right: 0.4em;
+ }
+ }
+ &:hover {
+ .notification-content {
+ .close-button {
+ @include button;
+ background-color: transparentize($red, 0.5);
+ &:hover {
+ background-color: transparentize($red, 0.3);
+ }
+ &:active {
+ background-color: transparentize($red, 0.1);
+ }
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/sys_sliders.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/sys_sliders.scss
index 2a9ba7984..d9f572971 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/sys_sliders.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/sys_sliders.scss
@@ -1,16 +1,22 @@
-@mixin sys-sliders () {
- .slider{ @include slider($width: .8em, $slider: false); }
- .percent{
- margin: $spacing;
- min-width: 2.6em;
- }
- .icon{
- margin: $spacing;
- &:first-child{ font-size: 1.4em; }
- }
- button{
- @include button($flat: true);
- margin-right: $spacing;
- .icon{ margin: 0; }
- }
+@mixin sys-sliders() {
+ .slider {
+ @include slider($width: 0.8em, $slider: false);
+ }
+ .percent {
+ margin: $spacing;
+ min-width: 2.6em;
+ }
+ .icon {
+ margin: $spacing;
+ &:first-child {
+ font-size: 1.4em;
+ }
+ }
+ button {
+ @include button($flat: true);
+ margin-right: $spacing;
+ .icon {
+ margin: 0;
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/toggle_button.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/toggle_button.scss
index ad1f3480d..e211e15f8 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/toggle_button.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/toggle_button.scss
@@ -1,34 +1,50 @@
-@mixin toggle_button($toggle_radius: $radii*2.4) {
- @include button($radii: $toggle_radius);
- &.small{ @include button($radii: $toggle_radius*1.1); }
- margin: $spacing;
- .separator{
- background-color: $fg_color;
- min-width: 2px;
- min-height: 1.4em;
- }
- .half{
- @include button($flat: true);
- min-height: 3.4em;
- &:first-child{ border-radius: $toggle_radius 0 0 $toggle_radius }
- &:last-child{ border-radius: 0 $toggle_radius $toggle_radius 0 }
- &:hover{ background-color: $hover }
- }
- &.active{
- * { color: $accent_fg; }
- background-color: $accent;
- .separator{ background-color: $accent_fg; }
- &:hover{
- background-color: transparentize($accent, 0.15);
- *{ color: $accent_fg}
- }
- &:focus{
- background-color: transparentize($accent, 0.4);
- box-shadow: inset 0 0 0 $border_width*2 $accent;
- }
- }
- .icon{
- font-size: 2em;
- &.arrow{ font-size: 1.8em; }
- }
+@mixin toggle_button($toggle_radius: $radii * 2.4) {
+ @include button($radii: $toggle_radius);
+ &.small {
+ @include button($radii: $toggle_radius * 1.1);
+ }
+ margin: $spacing;
+ .separator {
+ background-color: $fg_color;
+ min-width: 2px;
+ min-height: 1.4em;
+ }
+ .half {
+ @include button($flat: true);
+ min-height: 3.4em;
+ &:first-child {
+ border-radius: $toggle_radius 0 0 $toggle_radius;
+ }
+ &:last-child {
+ border-radius: 0 $toggle_radius $toggle_radius 0;
+ }
+ &:hover {
+ background-color: $hover;
+ }
+ }
+ &.active {
+ * {
+ color: $accent_fg;
+ }
+ background-color: $accent;
+ .separator {
+ background-color: $accent_fg;
+ }
+ &:hover {
+ background-color: transparentize($accent, 0.15);
+ * {
+ color: $accent_fg;
+ }
+ }
+ &:focus {
+ background-color: transparentize($accent, 0.4);
+ box-shadow: inset 0 0 0 $border_width * 2 $accent;
+ }
+ }
+ .icon {
+ font-size: 2em;
+ &.arrow {
+ font-size: 1.8em;
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/user.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/user.scss
index ec3e4a8cd..c3582bbbd 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/user.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/user.scss
@@ -1,26 +1,26 @@
@mixin user($width: 10em, $height: 10em) {
- padding: 0;
- min-height: 10em;
- min-width: 10em;
- background-image: url($avatar);
- background-size: cover;
+ padding: 0;
+ min-height: 10em;
+ min-width: 10em;
+ background-image: url($avatar);
+ background-size: cover;
- .darkened {
- @include darkened($radii: $button_radius);
- padding: .3em;
+ .darkened {
+ @include darkened($radii: $button_radius);
+ padding: 0.3em;
- label {
- text-shadow: $text_shadow;
+ label {
+ text-shadow: $text_shadow;
- &:first-child {
- color: transparentize($fg_color, 0.1);
- font-size: 1.3em;
- }
+ &:first-child {
+ color: transparentize($fg_color, 0.1);
+ font-size: 1.3em;
+ }
- &:last-child {
- color: transparentize($fg_color, 0.3);
- font-size: 1.1em;
- }
- }
- }
-}
\ No newline at end of file
+ &:last-child {
+ color: transparentize($fg_color, 0.3);
+ font-size: 1.1em;
+ }
+ }
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/weather.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/weather.scss
index 306946c37..97765577e 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/weather.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/widgets/weather.scss
@@ -1,29 +1,50 @@
@mixin weather {
- .info{
- .place{
- label{ font-size: 1.2em }
- .icon{
- font-size: .9em;
- margin-right: .2em;
- color: transparentize($accent, 0);
- }
- }
- .feels{ color: transparentize($fg_color, 0.3); }
- .temp{ font-size: 1.2em; }
- }
- .icon{
- font-size: 2.6em;
+ .info {
+ .place {
+ label {
+ font-size: 1.2em;
+ }
+ .icon {
+ font-size: 0.9em;
+ margin-right: 0.2em;
+ color: transparentize($accent, 0);
+ }
+ }
+ .feels {
+ color: transparentize($fg_color, 0.3);
+ }
+ .temp {
+ font-size: 1.2em;
+ }
+ }
+ .icon {
+ font-size: 2.6em;
- &.clear.d{ color: transparentize($yellow, 0.6); }
- &.clear.n{ color: transparentize($blue, 0.6); }
+ &.clear.d {
+ color: transparentize($yellow, 0.6);
+ }
+ &.clear.n {
+ color: transparentize($blue, 0.6);
+ }
- &.clouds.d{ color: transparentize($fg_color, 0.6); }
- &.clouds.n{ color: transparentize($blue, 0.6); }
-
- &.rain{ color: transparentize($blue, 0.6); }
- &.thunderstorm{ color: transparentize($yellow, 0.6); }
- &.snow{ color: transparentize($fg_color, 0.6); }
- &.mist{ color: transparentize($teal, 0.6); }
- }
+ &.clouds.d {
+ color: transparentize($fg_color, 0.6);
+ }
+ &.clouds.n {
+ color: transparentize($blue, 0.6);
+ }
+ &.rain {
+ color: transparentize($blue, 0.6);
+ }
+ &.thunderstorm {
+ color: transparentize($yellow, 0.6);
+ }
+ &.snow {
+ color: transparentize($fg_color, 0.6);
+ }
+ &.mist {
+ color: transparentize($teal, 0.6);
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/app_laucher.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/app_laucher.scss
index 79776f7f3..94eea77fe 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/app_laucher.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/app_laucher.scss
@@ -1,53 +1,58 @@
-.app-launcher{
- @include floating_widget;
- min-height: 530px;
- min-width: 530px;
- padding: 3em;
+.app-launcher {
+ @include floating_widget;
+ min-height: 530px;
+ min-width: 530px;
+ padding: 3em;
- .search{
- min-height: 1.4em;
- padding: 2em;
- border-radius: $radii;
- background-image: url($wallpaper);
- background-size: cover;
- background-position: right bottom;
- margin-bottom: 3em;
- .icon, .input {
- @include button;
- background-color: transparentize($bg_color, 0.1);
- box-shadow: 0 0 5px 0 rgba(0,0,0,0.4);
- }
- .icon {
- min-width: 2.4em;
- margin-right: $spacing
- }
- .input{
- padding: .6em .8em;
- }
- }
+ .search {
+ min-height: 1.4em;
+ padding: 2em;
+ border-radius: $radii;
+ background-image: url($wallpaper);
+ background-size: cover;
+ background-position: right bottom;
+ margin-bottom: 3em;
+ .icon,
+ .input {
+ @include button;
+ background-color: transparentize($bg_color, 0.1);
+ box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.4);
+ }
+ .icon {
+ min-width: 2.4em;
+ margin-right: $spacing;
+ }
+ .input {
+ padding: 0.6em 0.8em;
+ }
+ }
- .separator{
- min-height: 1px;
- background-color: transparentize($fg_color, 0.94);
- margin: .2em;
- }
+ .separator {
+ min-height: 1px;
+ background-color: transparentize($fg_color, 0.94);
+ margin: 0.2em;
+ }
- .app{
- @include button($flat: true, $focusable: true);
- .app-content{
- .name{ font-size: 1.1em }
- .description{ color: transparentize($fg_color, 0.3) }
- .appicon{
- background-size: cover;
- min-width: 2.4em;
- min-height: 2.4em;
- margin-right: 1em;
- }
- padding: .6em;
- }
- }
+ .app {
+ @include button($flat: true, $focusable: true);
+ .app-content {
+ .name {
+ font-size: 1.1em;
+ }
+ .description {
+ color: transparentize($fg_color, 0.3);
+ }
+ .appicon {
+ background-size: cover;
+ min-width: 2.4em;
+ min-height: 2.4em;
+ margin-right: 1em;
+ }
+ padding: 0.6em;
+ }
+ }
- .scroll {
- @include scrollbar;
- }
+ .scroll {
+ @include scrollbar;
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/datemenu.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/datemenu.scss
index 23e76021e..404cba280 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/datemenu.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/datemenu.scss
@@ -1,66 +1,70 @@
-.datemenu{
- @include floating_widget;
+.datemenu {
+ @include floating_widget;
- .widget{
- @include widget;
- margin: $spacing;
- padding: $spacing;
- }
+ .widget {
+ @include widget;
+ margin: $spacing;
+ padding: $spacing;
+ }
- .clock *{
- margin-top: $spacing;
- text-shadow: $text_shadow;
- font-size: 7em;
- }
+ .clock * {
+ margin-top: $spacing;
+ text-shadow: $text_shadow;
+ font-size: 7em;
+ }
- .uptime{
- margin-bottom: $spacing*2;
- font-size: 1.1em;
- text-shadow: $text_shadow;
- color: transparentize($fg_color, 0.3)
- }
-
- .calendar-bin{
- padding: 1em 2em .4em 2em;
- @include calendar;
- }
+ .uptime {
+ margin-bottom: $spacing * 2;
+ font-size: 1.1em;
+ text-shadow: $text_shadow;
+ color: transparentize($fg_color, 0.3);
+ }
- .system{
- > * {
- @include widget;
- margin: $spacing;
- padding: 5px;
- min-width: 3.4em;
- min-height: 3.4em;
- }
- circular-progress{
- background-color: $bg_color;
- color: $accent;
- &.battery{
- &.low{ color: $red }
- }
- .icon{ font-size: 1.3em; }
- }
- }
+ .calendar-bin {
+ padding: 1em 2em 0.4em 2em;
+ @include calendar;
+ }
- .media{
- @include media($style: 'widget')
- }
+ .system {
+ > * {
+ @include widget;
+ margin: $spacing;
+ padding: 5px;
+ min-width: 3.4em;
+ min-height: 3.4em;
+ }
+ circular-progress {
+ background-color: $bg_color;
+ color: $accent;
+ &.battery {
+ &.low {
+ color: $red;
+ }
+ }
+ .icon {
+ font-size: 1.3em;
+ }
+ }
+ }
- .events.widget {
- padding: 0;
- .events{
- @include events;
- }
- }
-
- .weather{
- @include weather;
- }
+ .media {
+ @include media($style: "widget");
+ }
- .wallpaper{
- min-height: 13em;
- background-image: url($assets+'wallpaper.png');
- background-size: cover;
- }
+ .events.widget {
+ padding: 0;
+ .events {
+ @include events;
+ }
+ }
+
+ .weather {
+ @include weather;
+ }
+
+ .wallpaper {
+ min-height: 13em;
+ background-image: url($assets + "wallpaper.png");
+ background-size: cover;
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/desktop.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/desktop.scss
index ae4769f97..4be309c22 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/desktop.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/desktop.scss
@@ -1,48 +1,48 @@
.desktop {
- background-image: url($wallpaper);
- background-size: cover;
-
- .clock {
- color: white;
- text-shadow: 4px 4px 4px black;
-
- .time {
- border: 3px solid $fg_color;
- box-shadow: inset 0 0 0 3px $bg_color;
- border-radius: $popover_radius;
- padding: .5em 1.3em;
-
- .hour,
- .minutes,
- .separator {
- font-size: 10em;
- font-family: $mono_font;
- }
- }
-
- .date {
- font-size: 2em;
- }
- }
-
- .system {
- >* {
- padding: 8px;
- }
-
- circular-progress {
- background-color: transparentize($bg_color, 0.5);
- color: $fg_color;
-
- &.battery {
- &.low {
- color: $red
- }
- }
-
- .icon {
- font-size: 3em;
- }
- }
- }
-}
\ No newline at end of file
+ background-image: url($wallpaper);
+ background-size: cover;
+
+ .clock {
+ color: white;
+ text-shadow: 4px 4px 4px black;
+
+ .time {
+ border: 3px solid $fg_color;
+ box-shadow: inset 0 0 0 3px $bg_color;
+ border-radius: $popover_radius;
+ padding: 0.5em 1.3em;
+
+ .hour,
+ .minutes,
+ .separator {
+ font-size: 10em;
+ font-family: $mono_font;
+ }
+ }
+
+ .date {
+ font-size: 2em;
+ }
+ }
+
+ .system {
+ > * {
+ padding: 8px;
+ }
+
+ circular-progress {
+ background-color: transparentize($bg_color, 0.5);
+ color: $fg_color;
+
+ &.battery {
+ &.low {
+ color: $red;
+ }
+ }
+
+ .icon {
+ font-size: 3em;
+ }
+ }
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/dock.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/dock.scss
index ff643ca4f..020e07aa0 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/dock.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/dock.scss
@@ -1,55 +1,76 @@
$dock_icon_size: 6em;
-.dock{
- .container{
- min-width: $dock_icon_size*11.5;
- min-height: $dock_icon_size*1.3;
- &.hovered{
- min-width: $dock_icon_size*11.7;
- }
- }
+.dock {
+ .container {
+ min-width: $dock_icon_size * 11.5;
+ min-height: $dock_icon_size * 1.3;
+ &.hovered {
+ min-width: $dock_icon_size * 11.7;
+ }
+ }
- .foot{
- @include floating_widget;
- margin: 0 1.5em;
- padding: 0;
- border-radius: $popover_radius $popover_radius 0 0;
- border-bottom: none;
- min-height: 1.5em; //footer height
- }
+ .foot {
+ @include floating_widget;
+ margin: 0 1.5em;
+ padding: 0;
+ border-radius: $popover_radius $popover_radius 0 0;
+ border-bottom: none;
+ min-height: 1.5em; //footer height
+ }
- .laucher{
- .indicator{
- min-height: .4em; //indicator height
- min-width: 2em; //indicator width
- border-radius: $button_radius;
- }
- .icon{
- min-width: $dock_icon_size;
- min-height: $dock_icon_size;
- background-size: contain;
- background-repeat: no-repeat;
- }
- &:hover{
- background-image: linear-gradient(transparent, transparentize($fg_color, 0.94));
- .icon{
- min-width: $dock_icon_size*1.2;
- min-height: $dock_icon_size*1.2;
- }
- }
- &:active{
- .indicator{
- background-color: $accent;
- }
- }
- &.firefox .icon{ background-image: url($assets+'apps/firefox.png'); }
- &.terminal .icon{ background-image: url($assets+'apps/terminal.png'); }
- &.file-manager .icon{ background-image: url($assets+'apps/file-manager.png'); }
- &.editor .icon{ background-image: url($assets+'apps/editor.png'); }
- &.spotify .icon{ background-image: url($assets+'apps/spotify.png'); }
- &.caprine .icon{ background-image: url($assets+'apps/caprine.png'); }
- &.bitwig .icon{ background-image: url($assets+'apps/bitwig.png'); }
- &.battle .icon{ background-image: url($assets+'apps/battle.png'); }
- &.bottles .icon{ background-image: url($assets+'apps/bottles.png'); }
- }
+ .laucher {
+ .indicator {
+ min-height: 0.4em; //indicator height
+ min-width: 2em; //indicator width
+ border-radius: $button_radius;
+ }
+ .icon {
+ min-width: $dock_icon_size;
+ min-height: $dock_icon_size;
+ background-size: contain;
+ background-repeat: no-repeat;
+ }
+ &:hover {
+ background-image: linear-gradient(
+ transparent,
+ transparentize($fg_color, 0.94)
+ );
+ .icon {
+ min-width: $dock_icon_size * 1.2;
+ min-height: $dock_icon_size * 1.2;
+ }
+ }
+ &:active {
+ .indicator {
+ background-color: $accent;
+ }
+ }
+ &.firefox .icon {
+ background-image: url($assets + "apps/firefox.png");
+ }
+ &.terminal .icon {
+ background-image: url($assets + "apps/terminal.png");
+ }
+ &.file-manager .icon {
+ background-image: url($assets + "apps/file-manager.png");
+ }
+ &.editor .icon {
+ background-image: url($assets + "apps/editor.png");
+ }
+ &.spotify .icon {
+ background-image: url($assets + "apps/spotify.png");
+ }
+ &.caprine .icon {
+ background-image: url($assets + "apps/caprine.png");
+ }
+ &.bitwig .icon {
+ background-image: url($assets + "apps/bitwig.png");
+ }
+ &.battle .icon {
+ background-image: url($assets + "apps/battle.png");
+ }
+ &.bottles .icon {
+ background-image: url($assets + "apps/bottles.png");
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/hbar.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/hbar.scss
index 949752194..28569f5b2 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/hbar.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/hbar.scss
@@ -1,113 +1,113 @@
.hpanel {
- min-height: 2.2em;
- font-weight: bold;
- font-size: 1.1em;
- color: $fg_color;
- background-color: transparent;
- border-bottom: $border_width solid $popover_border_color;
- box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.8);
-
- .button-bin {
- margin: 3px 2px;
- background-color: $bg_color;
- border-radius: $button_radius;
-
- &.launcher {
- margin-left: 4px
- }
-
- &.powermenu {
- margin-right: 4px
- }
- }
-
- .button {
- .icon {
- font-size: 1.2em;
- }
-
- @include button($flat: true, $radii: $panel_button_radius);
-
- >* {
- padding: 0 .7em
- }
-
- &.launcher {
- color: $accent;
- }
-
- &.powermenu {
- color: $red;
- }
-
- &.window {
- @include button($flat: true, $interactive: false)
- }
-
- &.workspaces {
- @include button($flat: false, $radii: $panel_button_radius);
- background-color: $bg_color;
- border-radius: $button_radius;
-
- .workspace-btn {
- label {
- font-size: 1.2em;
- }
-
- margin: 2px;
-
- &.empty {
- color: transparentize($fg_color, 0.34);
- }
-
- &.occupied {
- color: transparentize($fg_color, 0.18);
- }
-
- &.active {
- color: $fg_color;
- }
-
- &:hover {
- &.empty {
- color: transparentize($fg_color, 0.18);
- }
-
- &.occupied {
- color: $fg_color;
- }
- }
-
- &:active {
- color: $accent;
- }
- }
- }
-
- &.system-indicators {
- @include system-indicators($orientation: 'h');
-
- >*>*>* {
- padding: 0 .3em;
- }
- }
-
- &.media {
- .icon {
- margin-right: .2em;
-
- &.spotify {
- color: $green;
- }
-
- &.firefox {
- color: $orange;
- }
-
- &.mpv {
- color: $magenta;
- }
- }
- }
- }
-}
\ No newline at end of file
+ min-height: 2.2em;
+ font-weight: bold;
+ font-size: 1.1em;
+ color: $fg_color;
+ background-color: transparent;
+ border-bottom: $border_width solid $popover_border_color;
+ box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.8);
+
+ .button-bin {
+ margin: 3px 2px;
+ background-color: $bg_color;
+ border-radius: $button_radius;
+
+ &.launcher {
+ margin-left: 4px;
+ }
+
+ &.powermenu {
+ margin-right: 4px;
+ }
+ }
+
+ .button {
+ .icon {
+ font-size: 1.2em;
+ }
+
+ @include button($flat: true, $radii: $panel_button_radius);
+
+ > * {
+ padding: 0 0.7em;
+ }
+
+ &.launcher {
+ color: $accent;
+ }
+
+ &.powermenu {
+ color: $red;
+ }
+
+ &.window {
+ @include button($flat: true, $interactive: false);
+ }
+
+ &.workspaces {
+ @include button($flat: false, $radii: $panel_button_radius);
+ background-color: $bg_color;
+ border-radius: $button_radius;
+
+ .workspace-btn {
+ label {
+ font-size: 1.2em;
+ }
+
+ margin: 2px;
+
+ &.empty {
+ color: transparentize($fg_color, 0.34);
+ }
+
+ &.occupied {
+ color: transparentize($fg_color, 0.18);
+ }
+
+ &.active {
+ color: $fg_color;
+ }
+
+ &:hover {
+ &.empty {
+ color: transparentize($fg_color, 0.18);
+ }
+
+ &.occupied {
+ color: $fg_color;
+ }
+ }
+
+ &:active {
+ color: $accent;
+ }
+ }
+ }
+
+ &.system-indicators {
+ @include system-indicators($orientation: "h");
+
+ > * > * > * {
+ padding: 0 0.3em;
+ }
+ }
+
+ &.media {
+ .icon {
+ margin-right: 0.2em;
+
+ &.spotify {
+ color: $green;
+ }
+
+ &.firefox {
+ color: $orange;
+ }
+
+ &.mpv {
+ color: $magenta;
+ }
+ }
+ }
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/media.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/media.scss
index a55f3b694..0284dcef1 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/media.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/media.scss
@@ -1,10 +1,10 @@
-.media-window{
- padding: 0;
- .media{
- @include media($height: 20em, $style: 'popover');
- padding: 0;
- .cover{
- min-width: 20em;
- }
- }
+.media-window {
+ padding: 0;
+ .media {
+ @include media($height: 20em, $style: "popover");
+ padding: 0;
+ .cover {
+ min-width: 20em;
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/noti_center.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/noti_center.scss
index 1ae2109dd..91e668731 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/noti_center.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/noti_center.scss
@@ -1,47 +1,72 @@
-.notification-center{
- min-width: 400px;
- @include floating_widget;
- .title{
- button{
- font-size: 1.0em;
- padding: .4em 1em;
- @include button;
- }
- label{ font-size: 1.4em }
- margin-bottom: $spacing;
- }
- .notifications-list{
- @include scrollbar;
- .placeholder{
- .icon{ font-size: 8em; }
- label{ font-size: 2em; }
- }
- .notification{
- @include notification;
- .notification-content{
- @include widget;
- margin-bottom: $spacing;
- border-radius: $widget_radius*0.3;
- }
- &:first-child .notification-content{
- border-radius: $widget_radius $widget_radius $widget_radius*0.3 $widget_radius*0.3;
- }
- &:last-child .notification-content{
- border-radius: $widget_radius*0.3 $widget_radius*0.3 $widget_radius $widget_radius;
- }
- &:first-child:last-child .notification-content{
- border-radius: $widget_radius;
- }
- }
- margin-bottom: $spacing;
- }
- .controls{
- @include widget;
- padding: $popover_padding * 0.5;
- .sys-sliders{ @include sys-sliders; }
- .toggle {
- min-height: 3.4em;
- @include toggle_button($toggle_radius: $radii*1.4);
- }
- }
+.notification-center {
+ min-width: 400px;
+ @include floating_widget;
+
+ .title {
+ button {
+ font-size: 1em;
+ padding: 0.4em 1em;
+ @include button;
+ }
+
+ label {
+ font-size: 1.4em;
+ }
+
+ margin-bottom: $spacing;
+ }
+
+ .notifications-list {
+ @include scrollbar;
+
+ .placeholder {
+ .icon {
+ font-size: 8em;
+ }
+
+ label {
+ font-size: 2em;
+ }
+ }
+
+ .notification {
+ @include notification;
+
+ .notification-content {
+ @include widget;
+ margin-bottom: $spacing;
+ border-radius: $widget_radius * 0.3;
+ }
+
+ &:first-child .notification-content {
+ border-radius: $widget_radius $widget_radius $widget_radius *
+ 0.3 $widget_radius * 0.3;
+ }
+
+ &:last-child .notification-content {
+ border-radius: $widget_radius * 0.3 $widget_radius * 0.3
+ $widget_radius $widget_radius;
+ }
+
+ &:first-child:last-child .notification-content {
+ border-radius: $widget_radius;
+ }
+ }
+
+ margin-bottom: $spacing;
+ }
+
+ .controls {
+ @include widget;
+ padding: $popover_padding * 0.5;
+
+ .sys-sliders {
+ @include sys-sliders;
+ }
+
+ .toggle {
+ min-height: 3.4em;
+ @include toggle_button($toggle_radius: $radii * 1.4);
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/notifications.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/notifications.scss
index 76bc3d39a..f0225e6d1 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/notifications.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/notifications.scss
@@ -1,9 +1,9 @@
-.notifications-window-box{
- .notification{
- @include notification;
- .notification-content{
- min-width: 450px;
- @include floating_widget;
- }
- }
+.notifications-window-box {
+ .notification {
+ @include notification;
+ .notification-content {
+ min-width: 450px;
+ @include floating_widget;
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/osd.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/osd.scss
index 56f2c44e4..528570099 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/osd.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/osd.scss
@@ -1,18 +1,18 @@
-.osd-widget{
- @include floating_widget;
- padding: .3em;
- .icon{
- font-size: 40px;
- color: $accent_fg;
- min-width: 30px;
- min-height: 30px;
- }
- .scale{
- min-height: 14em;
- @include slider($width: 3em);
- trough{
- background-color: transparent;
- border: none;
- }
- }
-}
\ No newline at end of file
+.osd-widget {
+ @include floating_widget;
+ padding: 0.3em;
+ .icon {
+ font-size: 40px;
+ color: $accent_fg;
+ min-width: 30px;
+ min-height: 30px;
+ }
+ .scale {
+ min-height: 14em;
+ @include slider($width: 3em);
+ trough {
+ background-color: transparent;
+ border: none;
+ }
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/powermenu.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/powermenu.scss
index b098ccdab..721d26796 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/powermenu.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/powermenu.scss
@@ -1,49 +1,75 @@
-.background.powermenu{
- background-color: rgba(0,0,0,0.5);
- .content{
- @include floating_widget;
- .user{ @include user; }
- .clock{
- text-shadow: $text_shadow;
- margin-bottom: 2.2em;
- .hour *{ font-size: 9em }
- .date{ font-size: 2em }
- }
- .power-menu{
- border-radius: $radii*3;
- padding: 15px;
- }
- .button-bin{
- margin: 15px;
- margin-bottom: 0;
- .button{
- @include button($focusable: true);
- border-radius: $radii*2.4;
- font-size: 60px;
- min-width: 130px;
- min-height: 130px;
- .icon{
- background-size: contain;
- margin: 24px;
- @if $theme == 'light' {
- &.shutdown{ background-image: url($assets+'powermenu/light-shutdown.png'); }
- &.reboot{ background-image: url($assets+'powermenu/light-reboot.png'); }
- &.logout{ background-image: url($assets+'powermenu/light-logout.png'); }
- &.suspend{ background-image: url($assets+'powermenu/light-suspend.png'); }
- &.lock{ background-image: url($assets+'powermenu/light-lock.png'); }
- }@else{
- &.shutdown{ background-image: url($assets+'powermenu/shutdown.png'); }
- &.reboot{ background-image: url($assets+'powermenu/reboot.png'); }
- &.logout{ background-image: url($assets+'powermenu/logout.png'); }
- &.suspend{ background-image: url($assets+'powermenu/suspend.png'); }
- &.lock{ background-image: url($assets+'powermenu/lock.png'); }
- }
- }
- }
- .label{
- font-size: 20px;
- margin: 8px 0;
- }
- }
- }
+.background.powermenu {
+ background-color: rgba(0, 0, 0, 0.5);
+ .content {
+ @include floating_widget;
+ .user {
+ @include user;
+ }
+ .clock {
+ text-shadow: $text_shadow;
+ margin-bottom: 2.2em;
+ .hour * {
+ font-size: 9em;
+ }
+ .date {
+ font-size: 2em;
+ }
+ }
+ .power-menu {
+ border-radius: $radii * 3;
+ padding: 15px;
+ }
+ .button-bin {
+ margin: 15px;
+ margin-bottom: 0;
+ .button {
+ @include button($focusable: true);
+ border-radius: $radii * 2.4;
+ font-size: 60px;
+ min-width: 130px;
+ min-height: 130px;
+ .icon {
+ background-size: contain;
+ margin: 24px;
+ @if $theme == "light" {
+ &.shutdown {
+ background-image: url($assets + "powermenu/light-shutdown.png");
+ }
+ &.reboot {
+ background-image: url($assets + "powermenu/light-reboot.png");
+ }
+ &.logout {
+ background-image: url($assets + "powermenu/light-logout.png");
+ }
+ &.suspend {
+ background-image: url($assets + "powermenu/light-suspend.png");
+ }
+ &.lock {
+ background-image: url($assets + "powermenu/light-lock.png");
+ }
+ } @else {
+ &.shutdown {
+ background-image: url($assets + "powermenu/shutdown.png");
+ }
+ &.reboot {
+ background-image: url($assets + "powermenu/reboot.png");
+ }
+ &.logout {
+ background-image: url($assets + "powermenu/logout.png");
+ }
+ &.suspend {
+ background-image: url($assets + "powermenu/suspend.png");
+ }
+ &.lock {
+ background-image: url($assets + "powermenu/lock.png");
+ }
+ }
+ }
+ }
+ .label {
+ font-size: 20px;
+ margin: 8px 0;
+ }
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/quicksettings.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/quicksettings.scss
index 4c6a69d04..ea749ef6d 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/quicksettings.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/quicksettings.scss
@@ -1,54 +1,66 @@
-.quick-settings{
- @include floating_widget;
+.quick-settings {
+ @include floating_widget;
- .widget{
- @include widget;
- margin: $spacing;
- padding: $spacing;
- }
+ .widget {
+ @include widget;
+ margin: $spacing;
+ padding: $spacing;
+ }
- .sys-sliders{ @include sys-sliders; }
+ .sys-sliders {
+ @include sys-sliders;
+ }
- .sys-actions{
- .user{ @include user; }
- .sysactions{
- button{
- @include button($radii: 40%);
- margin: $spacing;
- padding: .4em;
- label{ font-size: 2.4em }
- &.power{ color: $red; }
- }
- .uptime{
- font-size: 1.3em;
- color: transparentize($fg_color, 0.5);
- }
- }
- }
+ .sys-actions {
+ .user {
+ @include user;
+ }
+ .sysactions {
+ button {
+ @include button($radii: 40%);
+ margin: $spacing;
+ padding: 0.4em;
+ label {
+ font-size: 2.4em;
+ }
+ &.power {
+ color: $red;
+ }
+ }
+ .uptime {
+ font-size: 1.3em;
+ color: transparentize($fg_color, 0.5);
+ }
+ }
+ }
- .system{
- > * > *{
- @include widget;
- margin: $spacing;
- padding: 8px;
- min-width: 4.4em;
- min-height: 4.4em;
- }
- circular-progress{
- background-color: $bg_color;
- color: $accent;
- &.battery{
- &.low{ color: $red }
- }
- .icon{ font-size: 1.8em; }
- }
- }
+ .system {
+ > * > * {
+ @include widget;
+ margin: $spacing;
+ padding: 8px;
+ min-width: 4.4em;
+ min-height: 4.4em;
+ }
+ circular-progress {
+ background-color: $bg_color;
+ color: $accent;
+ &.battery {
+ &.low {
+ color: $red;
+ }
+ }
+ .icon {
+ font-size: 1.8em;
+ }
+ }
+ }
- .toggles .toggle{
- @include toggle_button($toggle_radius: $radii*2.4);
- }
+ .toggles .toggle {
+ @include toggle_button($toggle_radius: $radii * 2.4);
+ }
- .media{
- @include media($height: 12em);
- }
+ .media {
+ @include media($height: 12em);
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/screenshot.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/screenshot.scss
index 163e36c9b..b67d501d6 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/screenshot.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/screenshot.scss
@@ -1,99 +1,99 @@
.background.takeshot {
- background-color: rgba(0, 0, 0, 0.5);
-
- .content {
- @include floating_widget;
-
- .takeshot-menu {
- border-radius: $radii*3;
- padding: 15px;
- }
-
- .button-bin {
- margin: 15px;
- margin-bottom: 0;
- margin-top: 0;
-
- .button {
- @include button($focusable: true);
- border-radius: $radii*2.4;
- min-width: 130px;
- min-height: 130px;
- }
-
- .label {
- font-size: 20px;
- margin: 8px 0;
- }
- }
-
- .icon {
- font-size: 5rem;
- }
-
- .blue {
- color: $blue;
- }
-
- .red {
- color: $red;
- }
-
- .green {
- color: $green;
- }
- }
+ background-color: rgba(0, 0, 0, 0.5);
+
+ .content {
+ @include floating_widget;
+
+ .takeshot-menu {
+ border-radius: $radii * 3;
+ padding: 15px;
+ }
+
+ .button-bin {
+ margin: 15px;
+ margin-bottom: 0;
+ margin-top: 0;
+
+ .button {
+ @include button($focusable: true);
+ border-radius: $radii * 2.4;
+ min-width: 130px;
+ min-height: 130px;
+ }
+
+ .label {
+ font-size: 20px;
+ margin: 8px 0;
+ }
+ }
+
+ .icon {
+ font-size: 5rem;
+ }
+
+ .blue {
+ color: $blue;
+ }
+
+ .red {
+ color: $red;
+ }
+
+ .green {
+ color: $green;
+ }
+ }
}
.background.previewshot {
- .content {
- @include floating_widget;
-
- .previewshot-menu {
- border-radius: $radii*3;
- padding: 15px;
- }
-
- .button-bin {
- margin: 15px;
- margin-bottom: 0;
- margin-top: 0;
-
- .button {
- @include button($focusable: true);
- border-radius: $radii;
- min-width: 15px;
- min-height: 50px;
- }
-
- .label {
- font-size: 15px;
- margin: 8px 0;
- }
- }
-
- .icon {
- font-size: 1.5rem;
- }
-
- .blue {
- color: $blue;
- }
-
- .red {
- color: $red;
- }
-
- .green {
- color: $green;
- }
- }
-
- .preview {
- background-image: url("/tmp/screenshot.png");
- background-size: contain;
- background-repeat: no-repeat;
- background-position: center;
- margin: 1rem;
- }
-}
\ No newline at end of file
+ .content {
+ @include floating_widget;
+
+ .previewshot-menu {
+ border-radius: $radii * 3;
+ padding: 15px;
+ }
+
+ .button-bin {
+ margin: 15px;
+ margin-bottom: 0;
+ margin-top: 0;
+
+ .button {
+ @include button($focusable: true);
+ border-radius: $radii;
+ min-width: 15px;
+ min-height: 50px;
+ }
+
+ .label {
+ font-size: 15px;
+ margin: 8px 0;
+ }
+ }
+
+ .icon {
+ font-size: 1.5rem;
+ }
+
+ .blue {
+ color: $blue;
+ }
+
+ .red {
+ color: $red;
+ }
+
+ .green {
+ color: $green;
+ }
+ }
+
+ .preview {
+ background-image: url("/tmp/screenshot.png");
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ margin: 1rem;
+ }
+}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/vbar.scss b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/vbar.scss
index 9f5123d82..f3c572307 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/vbar.scss
+++ b/home/isabel/programs/gui/confs/bars/eww/config/scss/windows/vbar.scss
@@ -1,71 +1,83 @@
.vpanel {
- min-width: 2.2em;
- font-weight: bold;
- color: $fg_color;
- background-color: $bg_color;
+ min-width: 2.2em;
+ font-weight: bold;
+ color: $fg_color;
+ background-color: $bg_color;
- // &.floating {
- margin: $wm_gaps;
- border-radius: $panel_radius;
- box-shadow: 0 0 5px rgba(0,0,0,0.3);
- border: $border_width solid $popover_border_color;
- // }
+ // &.floating {
+ margin: $wm_gaps;
+ border-radius: $panel_radius;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+ border: $border_width solid $popover_border_color;
+ // }
- .leftBar .button-bin {
- margin: .4em .4em 0 .4em;
- }
- .centerBar .button-bin {
- margin: .2em .4em;
- }
- .rightBar .button-bin {
- margin: 0 .4em .4em .4em;
- }
+ .leftBar .button-bin {
+ margin: 0.4em 0.4em 0 0.4em;
+ }
+ .centerBar .button-bin {
+ margin: 0.2em 0.4em;
+ }
+ .rightBar .button-bin {
+ margin: 0 0.4em 0.4em 0.4em;
+ }
- .media{
- @include panel_media();
- .player{ min-height: 2.6em; }
- }
+ .media {
+ @include panel_media();
+ .player {
+ min-height: 2.6em;
+ }
+ }
- .icon{ font-size: 1.3em;}
- .button{
- @include button($flat: true, $radii: $panel_button_radius);
- > * { padding: .4em }
+ .icon {
+ font-size: 1.3em;
+ }
+ .button {
+ @include button($flat: true, $radii: $panel_button_radius);
+ > * {
+ padding: 0.4em;
+ }
- &.launcher{ color: $blue; }
- &.powermenu{ color: $red; }
+ &.launcher {
+ color: $blue;
+ }
+ &.powermenu {
+ color: $red;
+ }
- &.clock{
- @include button($flat: false, $interactive: true);
- label{ font-size: 1.4em;}
- .separator{
- min-height: 0.2em;
- padding: 0 .3em;
- .dot{
- min-height: .15em;
- min-width: .15em;
- border-radius: $radii;
- background-color: $fg_color;
- }
- }
- }
+ &.clock {
+ @include button($flat: false, $interactive: true);
+ label {
+ font-size: 1.4em;
+ }
+ .separator {
+ min-height: 0.2em;
+ padding: 0 0.3em;
+ .dot {
+ min-height: 0.15em;
+ min-width: 0.15em;
+ border-radius: $radii;
+ background-color: $fg_color;
+ }
+ }
+ }
- &.workspaces{
- @include workspaces;
- }
+ &.workspaces {
+ @include workspaces;
+ }
- &.system-indicators{
- @include system-indicators($orientation: 'v');
- }
- }
+ &.system-indicators {
+ @include system-indicators($orientation: "v");
+ }
+ }
- > * > .separator{
- margin: .3em 0;
- padding: 0 .8em;
- .dot{
- min-height: .3em;
- min-width: .3em;
- border-radius: $radii;
- background-color: transparentize($fg_color, 0.6);
- }
- }
+ > * > .separator {
+ margin: 0.3em 0;
+ padding: 0 0.8em;
+ .dot {
+ min-height: 0.3em;
+ min-width: 0.3em;
+ border-radius: $radii;
+ background-color: transparentize($fg_color, 0.6);
+ }
+ }
}
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows.yuck b/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows.yuck
index 20b13445a..01be61d8a 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows.yuck
+++ b/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows.yuck
@@ -8,4 +8,4 @@
(include "./yuck/windows/noti_center.yuck")
(include "./yuck/windows/media.yuck")
(include "./yuck/windows/app_launcher.yuck")
-(include "./yuck/windows/screenshot.yuck")
\ No newline at end of file
+(include "./yuck/windows/screenshot.yuck")
diff --git a/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows/screenshot.yuck b/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows/screenshot.yuck
index 1d36ee4a7..27b5a9571 100644
--- a/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows/screenshot.yuck
+++ b/home/isabel/programs/gui/confs/bars/eww/config/yuck/windows/screenshot.yuck
@@ -85,4 +85,4 @@
)
(box :class "preview" :vexpand true :hexpand true)
)
-)
\ No newline at end of file
+)
diff --git a/home/isabel/programs/gui/confs/bars/eww/default.nix b/home/isabel/programs/gui/confs/bars/eww/default.nix
index 1bcb9e066..2c4bb3581 100644
--- a/home/isabel/programs/gui/confs/bars/eww/default.nix
+++ b/home/isabel/programs/gui/confs/bars/eww/default.nix
@@ -1,25 +1,21 @@
{
- config,
lib,
+ self',
pkgs,
osConfig,
defaults,
...
}: let
- inherit (lib) mkIf;
+ inherit (lib) isWayland;
ewwPackage =
- if env.isWayland
+ if isWayland osConfig
then pkgs.eww-wayland
else pkgs.eww;
- device = osConfig.modules.device;
- env = osConfig.modules.usrEnv;
acceptedTypes = ["desktop" "laptop" "hybrid"];
- programs = osConfig.modules.programs;
- sys = osConfig.modules.system;
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable && defaults.bar == "eww") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && (isWayland osConfig) && osConfig.modules.programs.gui.enable && defaults.bar == "eww") {
home.packages = with pkgs; [
socat
jaq
@@ -35,7 +31,7 @@ in {
harfbuzz
gdk-pixbuf
glib
- nur.repos.bella.gjs # patched gjs version
+ self'.packages.gjs # patched gjs version
];
programs.eww = {
diff --git a/home/isabel/programs/gui/confs/bars/waybar/default.nix b/home/isabel/programs/gui/confs/bars/waybar/default.nix
index 5fe29b75b..2ac1137c5 100644
--- a/home/isabel/programs/gui/confs/bars/waybar/default.nix
+++ b/home/isabel/programs/gui/confs/bars/waybar/default.nix
@@ -1,22 +1,23 @@
{
- config,
pkgs,
lib,
osConfig,
defaults,
...
}: let
- inherit (lib) mkIf;
- env = osConfig.modules.usrEnv;
- acceptedTypes = ["desktop" "laptop" "hybrid"];
- inherit (osConfig.modules) programs device;
+ inherit (lib) optionalString;
sys = osConfig.modules.system;
+ cfg = osConfig.modules.programs;
+ acceptedTypes = ["desktop" "laptop" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable && env.isWayland && defaults.bar == "waybar") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && lib.isWayland osConfig && defaults.bar == "waybar") {
home.packages = with pkgs; [wlogout];
+
programs.waybar = {
enable = true;
package = pkgs.waybar;
+ systemd.enable = true;
+ style = import ./style.nix {};
settings = {
mainBar = {
layer = "top";
@@ -31,12 +32,13 @@ in {
"custom/launcher"
];
modules-center = [
- "wlr/workspaces"
+ "hyprland/workspaces"
];
modules-right = [
"tray"
"backlight"
- "bluetooth"
+ (optionalString sys.bluetooth.enable "bluetooth")
+ (optionalString cfg.gaming.enable "gamemode")
"pulseaudio"
"battery"
"clock"
@@ -51,7 +53,7 @@ in {
"on-click-middle" = "close";
"on-click-right" = "activate";
};
- "wlr/workspaces" = {
+ "hyprland/workspaces" = {
disable-scroll = true;
all-outputs = true;
sort-by-number = true;
@@ -183,9 +185,20 @@ in {
on-click = "rofi -show drun";
on-click-right = "rofi -show drun";
};
+ gamemode = {
+ format = "";
+ format-alt = "{glyph}";
+ glyph = "";
+ hide-not-running = true;
+ use-icon = true;
+ icon-name = "input-gaming-symbolic";
+ icon-spacing = 4;
+ icon-size = 20;
+ tooltip = true;
+ tooltip-format = "Games running: {count}";
+ };
};
};
- style = builtins.readFile ./style.css;
};
};
}
diff --git a/home/isabel/programs/gui/confs/bars/waybar/style.css b/home/isabel/programs/gui/confs/bars/waybar/style.css
deleted file mode 100644
index 85b94589b..000000000
--- a/home/isabel/programs/gui/confs/bars/waybar/style.css
+++ /dev/null
@@ -1,191 +0,0 @@
-@define-color base #1e1e2e;
-@define-color mantle #181825;
-@define-color crust #11111b;
-
-@define-color text #cdd6f4;
-@define-color subtext0 #a6adc8;
-@define-color subtext1 #bac2de;
-
-@define-color surface0 #313244;
-@define-color surface1 #45475a;
-@define-color surface2 #585b70;
-
-@define-color overlay0 #6c7086;
-@define-color overlay1 #7f849c;
-@define-color overlay2 #9399b2;
-
-@define-color blue #89b4fa;
-@define-color lavender #b4befe;
-@define-color sapphire #74c7ec;
-@define-color sky #89dceb;
-@define-color teal #94e2d5;
-@define-color green #a6e3a1;
-@define-color yellow #f9e2af;
-@define-color peach #fab387;
-@define-color maroon #eba0ac;
-@define-color red #f38ba8;
-@define-color mauve #cba6f7;
-@define-color pink #f5c2e7;
-@define-color flamingo #f2cdcd;
-@define-color rosewater #f5e0dc;
-
-@define-color white #ffffff;
-
-* {
- border: none;
- border-radius: 0;
- font-family: RobotoMono Nerd Font, monospace, Noto Sans CJK JP;
- font-weight: normal;
- font-size: 14px;
- min-height: 0;
-}
-
-window#waybar {
- background: rgba(21, 18, 27, 0);
- color: #cdd6f4;
-}
-
-tooltip {
- background: #1e1e2e;
- border-radius: 10px;
- border-width: 2px;
- border-style: solid;
- border-color: #11111b;
-}
-
-#workspaces button {
- padding: 5px;
- color: #313244;
- margin-right: 5px;
-}
-
-#workspaces button.active {
- color: #a6adc8;
-}
-
-#workspaces button.focused {
- color: #a6adc8;
- background: #eba0ac;
- border-radius: 10px;
-}
-
-#workspaces button.urgent {
- color: #11111b;
- background: #a6e3a1;
- border-radius: 10px;
-}
-
-#workspaces button:hover {
- background: #11111b;
- color: #cdd6f4;
- border-radius: 10px;
-}
-
-#custom-language,
-#custom-logout,
-#custom-updates,
-#custom-caffeine,
-#custom-weather,
-#taskbar,
-#window,
-#clock,
-#battery,
-#pulseaudio,
-#network,
-#workspaces,
-#tray,
-#battery,
-#custom-launcher,
-#backlight {
- background: #1e1e2e;
- padding: 0px 10px;
- margin: 3px 0px;
- margin-top: 10px;
- border: 1px solid #181825;
- color: @white;
-}
-
-
-#backlight {
- border-radius: 10px 0px 0px 10px;
- border-right: 0px;
- margin-left: 0px;
-}
-
-#tray {
- border-radius: 10px;
- margin-right: 10px;
-}
-
-#workspaces {
- border-radius: 10px;
- margin-left: 10px;
- padding-right: 0px;
- padding-left: 5px;
-}
-
-#custom-language {
- border-left: 0px;
- border-right: 0px;
-}
-
-#custom-updates {
- border-radius: 10px;
- margin-right: 10px;
-}
-
-#window {
- border-radius: 10px;
- margin-left: 60px;
- margin-right: 60px;
-}
-
-#clock {
- margin-left: 0px;
- border-right: 0px;
-}
-
-#network {
- border-left: 0px;
- border-right: 0px;
-}
-
-#pulseaudio {
- border-left: 0px;
- border-right: 0px;
-}
-
-#pulseaudio.microphone {
- border-left: 0px;
- border-right: 0px;
-}
-
-#battery {
- margin-right: 0px;
- border-left: 0px;
-}
-
-#taskbar {
- border-radius: 10px;
- margin-right: 10px;
-}
-
-#custom-weather {
- border-radius: 0px 10px 10px 0px;
- border-right: 0px;
- margin-left: 0px;
-}
-
-#custom-logout {
- border-radius: 0px 10px 10px 0px;
- border-right: 0px;
- margin-left: 0px;
-}
-
-#custom-launcher {
- border-radius: 10px 10px 10px 10px;
- margin-right: 10px;
- margin-left: 10px;
- padding-right: 12.5px;
- padding-left: 12.5px;
-}
diff --git a/home/isabel/programs/gui/confs/bars/waybar/style.nix b/home/isabel/programs/gui/confs/bars/waybar/style.nix
new file mode 100644
index 000000000..180888a5c
--- /dev/null
+++ b/home/isabel/programs/gui/confs/bars/waybar/style.nix
@@ -0,0 +1,193 @@
+_: ''
+ @define-color base #1e1e2e;
+ @define-color mantle #181825;
+ @define-color crust #11111b;
+
+ @define-color text #cdd6f4;
+ @define-color subtext0 #a6adc8;
+ @define-color subtext1 #bac2de;
+
+ @define-color surface0 #313244;
+ @define-color surface1 #45475a;
+ @define-color surface2 #585b70;
+
+ @define-color overlay0 #6c7086;
+ @define-color overlay1 #7f849c;
+ @define-color overlay2 #9399b2;
+
+ @define-color blue #89b4fa;
+ @define-color lavender #b4befe;
+ @define-color sapphire #74c7ec;
+ @define-color sky #89dceb;
+ @define-color teal #94e2d5;
+ @define-color green #a6e3a1;
+ @define-color yellow #f9e2af;
+ @define-color peach #fab387;
+ @define-color maroon #eba0ac;
+ @define-color red #f38ba8;
+ @define-color mauve #cba6f7;
+ @define-color pink #f5c2e7;
+ @define-color flamingo #f2cdcd;
+ @define-color rosewater #f5e0dc;
+
+ @define-color white #ffffff;
+
+ * {
+ border: none;
+ border-radius: 0;
+ font-family: RobotoMono Nerd Font, monospace, Noto Sans CJK JP;
+ font-weight: normal;
+ font-size: 14px;
+ min-height: 0;
+ }
+
+ window#waybar {
+ background: rgba(21, 18, 27, 0);
+ color: #cdd6f4;
+ }
+
+ tooltip {
+ background: #1e1e2e;
+ border-radius: 10px;
+ border-width: 2px;
+ border-style: solid;
+ border-color: #11111b;
+ }
+
+ #workspaces button {
+ padding: 5px;
+ color: #313244;
+ margin-right: 5px;
+ }
+
+ #workspaces button.active {
+ color: #a6adc8;
+ }
+
+ #workspaces button.focused {
+ color: #a6adc8;
+ background: #eba0ac;
+ border-radius: 10px;
+ }
+
+ #workspaces button.urgent {
+ color: #11111b;
+ background: #a6e3a1;
+ border-radius: 10px;
+ }
+
+ #workspaces button:hover {
+ background: #11111b;
+ color: #cdd6f4;
+ border-radius: 10px;
+ }
+
+ #custom-language,
+ #custom-logout,
+ #custom-updates,
+ #custom-caffeine,
+ #custom-weather,
+ #taskbar,
+ #window,
+ #clock,
+ #battery,
+ #pulseaudio,
+ #network,
+ #workspaces,
+ #tray,
+ #battery,
+ #custom-launcher,
+ #backlight {
+ background: #1e1e2e;
+ padding: 0px 10px;
+ margin: 3px 0px;
+ margin-top: 10px;
+ border: 1px solid #181825;
+ color: @white;
+ }
+
+
+ #backlight {
+ border-radius: 10px 0px 0px 10px;
+ border-right: 0px;
+ margin-left: 0px;
+ }
+
+ #tray {
+ border-radius: 10px;
+ margin-right: 10px;
+ }
+
+ #workspaces {
+ border-radius: 10px;
+ margin-left: 10px;
+ padding-right: 0px;
+ padding-left: 5px;
+ }
+
+ #custom-language {
+ border-left: 0px;
+ border-right: 0px;
+ }
+
+ #custom-updates {
+ border-radius: 10px;
+ margin-right: 10px;
+ }
+
+ #window {
+ border-radius: 10px;
+ margin-left: 60px;
+ margin-right: 60px;
+ }
+
+ #clock {
+ margin-left: 0px;
+ border-right: 0px;
+ }
+
+ #network {
+ border-left: 0px;
+ border-right: 0px;
+ }
+
+ #pulseaudio {
+ border-left: 0px;
+ border-right: 0px;
+ }
+
+ #pulseaudio.microphone {
+ border-left: 0px;
+ border-right: 0px;
+ }
+
+ #battery {
+ margin-right: 0px;
+ border-left: 0px;
+ }
+
+ #taskbar {
+ border-radius: 10px;
+ margin-right: 10px;
+ }
+
+ #custom-weather {
+ border-radius: 0px 10px 10px 0px;
+ border-right: 0px;
+ margin-left: 0px;
+ }
+
+ #custom-logout {
+ border-radius: 0px 10px 10px 0px;
+ border-right: 0px;
+ margin-left: 0px;
+ }
+
+ #custom-launcher {
+ border-radius: 10px 10px 10px 10px;
+ margin-right: 10px;
+ margin-left: 10px;
+ padding-right: 12.5px;
+ padding-left: 12.5px;
+ }
+''
diff --git a/home/isabel/programs/gui/confs/browsers/chromium.nix b/home/isabel/programs/gui/confs/browsers/chromium.nix
index 44df0d83c..cee94b349 100644
--- a/home/isabel/programs/gui/confs/browsers/chromium.nix
+++ b/home/isabel/programs/gui/confs/browsers/chromium.nix
@@ -5,13 +5,10 @@
defaults,
...
}: let
- inherit (lib) mkIf optionals;
- inherit (osConfig.modules) device programs;
- sys = osConfig.modules.system;
- env = osConfig.modules.usrEnv;
+ inherit (osConfig.modules.system) video;
acceptedTypes = ["laptop" "desktop" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable && defaults.browser == "chromium") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable && defaults.browser == "chromium") {
programs.chromium = {
enable = true;
extensions = [
@@ -23,7 +20,7 @@ in {
"jghecgabfgfdldnmbfkhmffcabddioke" # Volume Master
"emffkefkbkpkgpdeeooapgaicgmcbolj" # Wikiwand
];
- package = pkgs.chromium.override {
+ package = pkgs.ungoogled-chromium.override {
nss = pkgs.nss_latest;
commandLineArgs =
[
@@ -53,7 +50,7 @@ in {
"--disable-speech-api"
"--disable-speech-synthesis-api"
]
- ++ optionals (env.isWayland) [
+ ++ lib.optionals (lib.isWayland osConfig) [
# Wayland
# Disabled because hardware acceleration doesn't work
# when disabling --use-gl=egl, it's not gonna show any emoji
diff --git a/home/isabel/programs/gui/confs/browsers/default.nix b/home/isabel/programs/gui/confs/browsers/default.nix
index 381947f32..f4d7c836c 100644
--- a/home/isabel/programs/gui/confs/browsers/default.nix
+++ b/home/isabel/programs/gui/confs/browsers/default.nix
@@ -1,6 +1,6 @@
_: {
imports = [
./chromium.nix
- ./firefox.nix
+ ./schizofox.nix
];
}
diff --git a/home/isabel/programs/gui/confs/browsers/firefox.nix b/home/isabel/programs/gui/confs/browsers/schizofox.nix
similarity index 62%
rename from home/isabel/programs/gui/confs/browsers/firefox.nix
rename to home/isabel/programs/gui/confs/browsers/schizofox.nix
index 20bbe37f9..9c60aaca6 100644
--- a/home/isabel/programs/gui/confs/browsers/firefox.nix
+++ b/home/isabel/programs/gui/confs/browsers/schizofox.nix
@@ -1,26 +1,34 @@
{
- config,
lib,
inputs,
osConfig,
defaults,
...
-}:
-with lib; let
- inherit (osConfig.modules) device programs system;
+}: let
+ inherit (osConfig.modules.system) video;
acceptedTypes = ["desktop" "laptop" "hybrid"];
in {
imports = [inputs.schizofox.homeManagerModule];
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && system.video.enable && defaults.browser == "firefox") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable && defaults.browser == "schizofox") {
programs.schizofox = {
enable = true;
- package = "firefox-esr-115-unwrapped";
+
+ theme = {
+ background-darker = "181825";
+ background = "1e1e2e";
+ foreground = "cdd6f4";
+ font = "RobotoMono Nerd Font";
+ simplefox.enable = true;
+ darkreader.enable = true;
+ extraCss = ''
+ '';
+ };
search = {
defaultSearchEngine = "Searx";
removeEngines = ["Google" "Bing" "Amazon.com" "eBay" "Twitter" "Wikipedia"];
searxUrl = "https://search.isabelroses.com";
- searxQuery = "https://search.isabelroses.com/search?q={searchTerms}&categories=general";
+ # searxQuery = "https://search.isabelroses.com/search?q={searchTerms}&categories=general";
addEngines = [];
};
@@ -33,17 +41,15 @@ in {
misc = {
drmFix = true;
disableWebgl = false;
- #startPageURL = "file://${./startpage.html}";
+ startPageURL = "https://dash.isabelroses.com";
};
extensions.extraExtensions = {
# Addon IDs are in manifest.json or manifest-firefox.json
"{446900e4-71c2-419f-a6a7-df9c091e268b}".install_url = "https://addons.mozilla.org/firefox/downloads/latest/bitwarden-password-manager/latest.xpi";
- "{b6129aa9-e45d-4280-aac8-3654e9d89d21}".install_url = "https://github.com/catppuccin/firefox/releases/download/old/catppuccin_mocha_sapphire.xpi";
"sponsorBlocker@ajay.app".install_url = "https://addons.mozilla.org/firefox/downloads/latest/sponsorblock/latest.xpi";
- "1018e4d6-728f-4b20-ad56-37578a4de76".install_url = "https://addons.mozilla.org/firefox/downloads/latest/flagfox/latest.xpi";
"{a4c4eda4-fb84-4a84-b4a1-f7c1cbf2a1ad}".install_url = "https://addons.mozilla.org/firefox/downloads/latest/refined-github-/latest.xpi";
- "{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}".install_url = "https://addons.mozilla.org/firefox/downloads/latest/stylus/latest.xpi";
+ "{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}".install_url = "https://addons.mozilla.org/firefox/downloads/latest/styl-us/latest.xpi";
};
};
};
diff --git a/home/isabel/programs/gui/confs/default.nix b/home/isabel/programs/gui/confs/default.nix
index c121861f3..e47e90a64 100644
--- a/home/isabel/programs/gui/confs/default.nix
+++ b/home/isabel/programs/gui/confs/default.nix
@@ -2,6 +2,7 @@ _: {
imports = [
./bars
./browsers
+ ./fileMangers
./launchers
./terminals
diff --git a/home/isabel/programs/gui/confs/discord.nix b/home/isabel/programs/gui/confs/discord.nix
index 63a9f1f10..b9d56111e 100644
--- a/home/isabel/programs/gui/confs/discord.nix
+++ b/home/isabel/programs/gui/confs/discord.nix
@@ -2,19 +2,19 @@
osConfig,
lib,
pkgs,
+ self,
...
-}:
-with lib; let
- device = osConfig.modules.device;
- programs = osConfig.modules.programs;
- sys = osConfig.modules.system;
+}: let
+ inherit (osConfig.modules.system) video;
acceptedTypes = ["laptop" "desktop" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable) {
home.packages = with pkgs; [
((discord.override {
+ nss = pkgs.nss_latest;
withOpenASAR = true;
withVencord = true;
+ withTTS = false;
})
.overrideAttrs (old: {
libPath = old.libPath + ":${pkgs.libglvnd}/lib";
diff --git a/home/isabel/programs/gui/confs/fileMangers/default.nix b/home/isabel/programs/gui/confs/fileMangers/default.nix
new file mode 100644
index 000000000..1feef033f
--- /dev/null
+++ b/home/isabel/programs/gui/confs/fileMangers/default.nix
@@ -0,0 +1,6 @@
+_: {
+ imports = [
+ ./dolphin.nix
+ ./nemo.nix
+ ];
+}
diff --git a/home/isabel/programs/gui/confs/fileMangers/dolphin.nix b/home/isabel/programs/gui/confs/fileMangers/dolphin.nix
new file mode 100644
index 000000000..e5491ba2d
--- /dev/null
+++ b/home/isabel/programs/gui/confs/fileMangers/dolphin.nix
@@ -0,0 +1,17 @@
+{
+ osConfig,
+ lib,
+ pkgs,
+ defaults,
+ ...
+}: let
+ inherit (osConfig.modules.system) video;
+
+ acceptedTypes = ["laptop" "desktop" "hybrid"];
+in {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable && defaults.fileManager == "dolphin") {
+ home.packages = with pkgs; [
+ libsForQt5.dolphin
+ ];
+ };
+}
diff --git a/home/isabel/programs/gui/confs/fileMangers/nemo.nix b/home/isabel/programs/gui/confs/fileMangers/nemo.nix
new file mode 100644
index 000000000..42262c899
--- /dev/null
+++ b/home/isabel/programs/gui/confs/fileMangers/nemo.nix
@@ -0,0 +1,18 @@
+{
+ osConfig,
+ lib,
+ pkgs,
+ defaults,
+ ...
+}: let
+ inherit (osConfig.modules.system) video;
+ acceptedTypes = ["laptop" "desktop" "hybrid"];
+in {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable && defaults.fileManager == "nemo") {
+ home.packages = with pkgs; [
+ cinnamon.nemo-with-extensions
+ cinnamon.nemo-fileroller
+ cinnamon.nemo-emblems
+ ];
+ };
+}
diff --git a/home/isabel/programs/gui/confs/launchers/rofi/config.nix b/home/isabel/programs/gui/confs/launchers/rofi/config.nix
index 7b74cb8ff..5335a316f 100644
--- a/home/isabel/programs/gui/confs/launchers/rofi/config.nix
+++ b/home/isabel/programs/gui/confs/launchers/rofi/config.nix
@@ -1,10 +1,14 @@
-{config, ...}: {
+{
+ config,
+ defaults,
+ ...
+}: {
programs.rofi = {
extraConfig = {
modi = "drun";
icon-theme = "Papirus-Dark";
show-icons = true;
- terminal = "alacritty";
+ terminal = defaults.terminal;
location = 0;
disable-history = false;
hide-scrollbar = true;
diff --git a/home/isabel/programs/gui/confs/launchers/rofi/default.nix b/home/isabel/programs/gui/confs/launchers/rofi/default.nix
index 4122a9a13..b517295c6 100644
--- a/home/isabel/programs/gui/confs/launchers/rofi/default.nix
+++ b/home/isabel/programs/gui/confs/launchers/rofi/default.nix
@@ -5,20 +5,17 @@
osConfig,
defaults,
...
-}:
-with lib; let
- device = osConfig.modules.device;
+}: let
acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
- sys = osConfig.modules.system;
- programs = osConfig.modules.programs;
rofiPackage =
- if osConfig.modules.usrEnv.isWayland
+ if lib.isWayland osConfig
then pkgs.rofi-wayland
else pkgs.rofi;
in {
imports = [./config.nix];
- config = mkIf (builtins.elem device.type acceptedTypes && sys.video.enable && programs.gui.enable && defaults.launcher == "rofi") {
+
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && defaults.launcher == "rofi") {
programs.rofi = {
enable = true;
package = rofiPackage.override {
diff --git a/home/isabel/programs/gui/confs/launchers/wofi/default.nix b/home/isabel/programs/gui/confs/launchers/wofi/default.nix
index 1287ec33c..64cba0070 100644
--- a/home/isabel/programs/gui/confs/launchers/wofi/default.nix
+++ b/home/isabel/programs/gui/confs/launchers/wofi/default.nix
@@ -4,15 +4,11 @@
osConfig,
defaults,
...
-}:
-with lib; let
- device = osConfig.modules.device;
+}: let
acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
- sys = osConfig.modules.system;
- programs = osConfig.modules.programs;
in {
imports = [./config.nix];
- config = mkIf (builtins.elem device.type acceptedTypes && sys.video.enable && programs.gui.enable && defaults.launcher == "wofi") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && (lib.isWayland osConfig) && osConfig.modules.programs.gui.enable && defaults.launcher == "wofi") {
programs.wofi.enable = true;
};
}
diff --git a/home/isabel/programs/gui/confs/steam.nix b/home/isabel/programs/gui/confs/steam.nix
deleted file mode 100644
index 9d0180620..000000000
--- a/home/isabel/programs/gui/confs/steam.nix
+++ /dev/null
@@ -1,27 +0,0 @@
-{lib, ...}: {
- nixpkgs.config.allowUnfreePredicate = pkg:
- builtins.elem (lib.getName pkg) [
- "steam"
- "steam-original"
- "steam-runtime"
- ];
-
- nixpkgs.config.packageOverrides = pkgs: {
- steam = pkgs.steam.override {
- extraPkgs = pkgs:
- with pkgs; [
- libgdiplus
- keyutils
- libkrb5
- libpng
- libpulseaudio
- libvorbis
- stdenv.cc.cc.lib
- xorg.libXcursor
- xorg.libXi
- xorg.libXinerama
- xorg.libXScrnSaver
- ];
- };
- };
-}
diff --git a/home/isabel/programs/gui/confs/terminals/alacritty.nix b/home/isabel/programs/gui/confs/terminals/alacritty.nix
index 5efcf096b..6d5000ce5 100644
--- a/home/isabel/programs/gui/confs/terminals/alacritty.nix
+++ b/home/isabel/programs/gui/confs/terminals/alacritty.nix
@@ -4,12 +4,10 @@
defaults,
...
}: let
- inherit (lib) mkIf;
- inherit (osConfig.modules) device programs;
- sys = osConfig.modules.system;
+ inherit (osConfig.modules.system) video;
acceptedTypes = ["laptop" "desktop" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable && defaults.terminal == "alacritty") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable && defaults.terminal == "alacritty") {
programs.alacritty = {
enable = true;
catppuccin.enable = true;
diff --git a/home/isabel/programs/gui/confs/terminals/kitty.nix b/home/isabel/programs/gui/confs/terminals/kitty.nix
index 564e137d2..0970bc4ce 100644
--- a/home/isabel/programs/gui/confs/terminals/kitty.nix
+++ b/home/isabel/programs/gui/confs/terminals/kitty.nix
@@ -1,23 +1,19 @@
{
- config,
lib,
osConfig,
defaults,
...
}: let
- inherit (lib) mkIf;
- inherit (osConfig.modules) device programs;
- sys = osConfig.modules.system;
+ inherit (osConfig.modules.system) video;
acceptedTypes = ["laptop" "desktop" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable && defaults.terminal == "kitty") {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable && video.enable && defaults.terminal == "kitty") {
programs.kitty = {
enable = true;
catppuccin.enable = true;
settings = {
- # General
background_opacity = "0.85";
- font_family = "monospace";
+ font_family = "RobotoMono Nerd Font";
font_size = 13;
disable_ligatures = "never";
cursor_shape = "beam";
diff --git a/home/isabel/programs/gui/confs/zathura.nix b/home/isabel/programs/gui/confs/zathura.nix
index 42cf29470..0be41d509 100644
--- a/home/isabel/programs/gui/confs/zathura.nix
+++ b/home/isabel/programs/gui/confs/zathura.nix
@@ -4,14 +4,8 @@
pkgs,
osConfig,
...
-}:
-with lib; let
- device = osConfig.modules.device;
- programs = osConfig.modules.programs;
- sys = osConfig.modules.system;
- acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
-in {
- config = mkIf (builtins.elem device.type acceptedTypes && programs.gui.enable && sys.video.enable) {
+}: {
+ config = lib.mkIf (osConfig.modules.programs.zathura.enable) {
xdg.configFile."zathura/catppuccin-mocha".source = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/catppuccin/zathura/main/src/catppuccin-mocha";
hash = "sha256-/HXecio3My2eXTpY7JoYiN9mnXsps4PAThDPs4OCsAk=";
diff --git a/home/isabel/programs/gui/gaming/default.nix b/home/isabel/programs/gui/gaming/default.nix
new file mode 100644
index 000000000..edcc23c5d
--- /dev/null
+++ b/home/isabel/programs/gui/gaming/default.nix
@@ -0,0 +1,29 @@
+{
+ lib,
+ pkgs,
+ osConfig,
+ ...
+}: let
+ inherit (osConfig.modules) programs;
+ acceptedTypes = ["laptop" "desktop" "lite"];
+in {
+ imports = [
+ ./minecraft
+ ];
+
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && programs.gaming.enable) {
+ home = {
+ packages = with pkgs; [
+ gamescope
+ legendary-gl
+ mono
+ winetricks
+ mangohud
+ lutris
+ #dolphin-emu # cool emulator
+ #yuzu # switch emulator
+ dotnet-runtime_6 # needed by terraria
+ ];
+ };
+ };
+}
diff --git a/home/isabel/programs/gui/gaming/minecraft/default.nix b/home/isabel/programs/gui/gaming/minecraft/default.nix
new file mode 100644
index 000000000..0e26105c0
--- /dev/null
+++ b/home/isabel/programs/gui/gaming/minecraft/default.nix
@@ -0,0 +1,41 @@
+{
+ lib,
+ pkgs,
+ osConfig,
+ ...
+}: let
+ catppuccin-mocha = pkgs.fetchzip {
+ url = "https://raw.githubusercontent.com/catppuccin/prismlauncher/main/themes/Mocha/Catppuccin-Mocha.zip";
+ sha256 = "8uRqCoe9iSIwNnK13d6S4XSX945g88mVyoY+LZSPBtQ=";
+ };
+
+ javaPackages = with pkgs; [
+ # Java 8
+ temurin-jre-bin-8
+ zulu8
+ # Java 11
+ temurin-jre-bin-11
+ # Java 17
+ temurin-jre-bin-17
+ # Latest
+ temurin-jre-bin
+ zulu
+ graalvm-ce
+ ];
+in {
+ config = lib.mkIf osConfig.modules.programs.gaming.minecraft.enable {
+ home = {
+ # PrismLauncher now with a cool theme
+ file.".local/share/PrismLauncher/themes/mocha" = {
+ source = catppuccin-mocha;
+ recursive = true;
+ };
+
+ packages = [
+ (pkgs.prismlauncher.override {
+ jdks = javaPackages;
+ })
+ ];
+ };
+ };
+}
diff --git a/home/isabel/programs/gui/shared.nix b/home/isabel/programs/gui/shared.nix
index b00f5c795..5504deea0 100644
--- a/home/isabel/programs/gui/shared.nix
+++ b/home/isabel/programs/gui/shared.nix
@@ -3,25 +3,18 @@
lib,
osConfig,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
-
- device = osConfig.modules.device;
+}: let
acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
- sys = osConfig.modules.system;
in {
- config = mkIf ((programs.gui.enable && sys.video.enable) && (builtins.elem device.type acceptedTypes)) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.gui.enable) {
home.packages = with pkgs; [
- bitwarden
- obsidian
- #zoom-us # I hate this
- xfce.thunar
- pamixer # move
- jellyfin-media-player
+ bitwarden # password manager
+ obsidian # note taking with markdown
+ pamixer # move evntually
+ # jellyfin-media-player
mangal # tui manga finder + reader
- insomnia # rest client
- libreoffice # office apps
+ # insomnia # rest client
+ nextcloud-client # cloud storage
];
};
}
diff --git a/home/isabel/programs/gui/wayland.nix b/home/isabel/programs/gui/wayland.nix
index d1ec49178..6227f2f41 100644
--- a/home/isabel/programs/gui/wayland.nix
+++ b/home/isabel/programs/gui/wayland.nix
@@ -3,19 +3,17 @@
lib,
pkgs,
...
-}:
-with lib; let
- env = osConfig.modules.usrEnv;
- programs = osConfig.modules.programs;
- sys = osConfig.modules.system;
+}: let
+ acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf (env.isWayland && programs.gui.enable && sys.video.enable) {
- home.packages = with pkgs; [
- swappy
- #swaynotificationcenter
- wlsunset
- wl-gammactl
- pavucontrol
- ];
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && (lib.isWayland osConfig) && osConfig.modules.programs.gui.enable) {
+ home.packages = with pkgs;
+ [
+ swappy # used for screenshot area selection
+ # swaynotificationcenter
+ wlsunset # reduce blue light at night
+ wl-gammactl
+ ]
+ ++ lib.optionals osConfig.modules.system.sound.enable [pavucontrol];
};
}
diff --git a/home/isabel/programs/cli/scripts/default.nix b/home/isabel/programs/scripts/default.nix
similarity index 91%
rename from home/isabel/programs/cli/scripts/default.nix
rename to home/isabel/programs/scripts/default.nix
index 1fda07abb..510be2206 100644
--- a/home/isabel/programs/cli/scripts/default.nix
+++ b/home/isabel/programs/scripts/default.nix
@@ -11,7 +11,7 @@
file = {
".local/bin/preview" = {
- # Preview script for fzf tab
+ # Preview files script for fzf tab
executable = true;
text = import ./preview.nix {inherit lib pkgs;};
};
diff --git a/home/isabel/programs/scripts/extract.nix b/home/isabel/programs/scripts/extract.nix
new file mode 100644
index 000000000..f5b066d15
--- /dev/null
+++ b/home/isabel/programs/scripts/extract.nix
@@ -0,0 +1,50 @@
+_: ''
+ SAVEIFS=$IFS
+ IFS="$(printf '\n\t')"
+
+ function extract {
+ if [ $# -eq 0 ]; then
+ # display usage if no parameters given
+ echo "Usage: extract ."
+ echo " extract [path/file_name_2.ext] [path/file_name_3.ext]"
+ fi
+ for n in "$@"; do
+ if [ ! -f "$n" ]; then
+ echo "'$n' - file doesn't exist"
+ return 1
+ fi
+
+ case "''${n%,}" in
+ *.cbt|*.tar.bz2|*.tar.gz|*.tar.xz|*.tbz2|*.tgz|*.txz|*.tar)
+ tar zxvf "$n" ;;
+ *.lzma) unlzma ./"$n" ;;
+ *.bz2) bunzip2 ./"$n" ;;
+ *.cbr|*.rar) unrar x -ad ./"$n" ;;
+ *.gz) gunzip ./"$n" ;;
+ *.cbz|*.epub|*.zip) unzip ./"$n" ;;
+ *.z) uncompress ./"$n" ;;
+ *.7z|*.apk|*.arj|*.cab|*.cb7|*.chm|*.deb|*.iso|*.lzh|*.msi|*.pkg|*.rpm|*.udf|*.wim|*.xar|*.vhd)
+ 7z x ./"$n" ;;
+ *.xz) unxz ./"$n" ;;
+ *.exe) cabextract ./"$n" ;;
+ *.cpio) cpio -id < ./"$n" ;;
+ *.cba|*.ace) unace x ./"$n" ;;
+ *.zpaq) zpaq x ./"$n" ;;
+ *.arc) arc e ./"$n" ;;
+ *.cso)
+ ciso 0 ./"$n" ./"$n.iso" && \
+ extract "$n.iso" && \rm -f "$n" ;;
+ *.zlib)
+ zlib-flate -uncompress < ./"$n" > ./"$n.tmp" && \
+ mv ./"$n.tmp" ./"''${n%.*zlib}" && rm -f "$n" ;;
+ *.dmg)
+ hdiutil mount ./"$n" -mountpoint "./$n.mounted" ;;
+ *)
+ echo "extract: '$n' - unknown archive method"
+ return 1
+ ;;
+ esac
+ done
+ }
+ IFS=$SAVEIFS
+''
diff --git a/home/isabel/programs/cli/scripts/preview.nix b/home/isabel/programs/scripts/preview.nix
similarity index 87%
rename from home/isabel/programs/cli/scripts/preview.nix
rename to home/isabel/programs/scripts/preview.nix
index 291be3fad..68691393e 100644
--- a/home/isabel/programs/cli/scripts/preview.nix
+++ b/home/isabel/programs/scripts/preview.nix
@@ -18,7 +18,7 @@
${lib.getExe pkgs.catimg} -w 100 -r 2 "$1"
;;
*directory*)
- ${lib.getExe pkgs.exa} --icons -1 --color=always "$1"
+ ${lib.getExe pkgs.eza} --icons -1 --color=always "$1"
;;
*)
echo "unknown file format"
diff --git a/home/isabel/programs/shells/bash.nix b/home/isabel/programs/shells/bash.nix
new file mode 100644
index 000000000..19baf756f
--- /dev/null
+++ b/home/isabel/programs/shells/bash.nix
@@ -0,0 +1,25 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: {
+ programs.bash = {
+ enable = true;
+ bashrcExtra = ''
+ eval "$(${lib.getExe pkgs.starship} init bash)"
+ '';
+ historyFile = "${config.xdg.stateHome}/bash/history";
+ historyFileSize = 1000;
+ historySize = 100;
+ shellOptions = [
+ "cdspell"
+ "checkjobs"
+ "checkwinsize"
+ "dirspell"
+ "globstar"
+ "histappend"
+ "no_empty_cmd_completion"
+ ];
+ };
+}
diff --git a/home/isabel/programs/shells/default.nix b/home/isabel/programs/shells/default.nix
new file mode 100644
index 000000000..968cfec6e
--- /dev/null
+++ b/home/isabel/programs/shells/default.nix
@@ -0,0 +1,8 @@
+_: {
+ imports = [
+ ./bash.nix
+ ./fish.nix
+ ./nushell.nix
+ ./shellAlias.nix
+ ];
+}
diff --git a/home/isabel/programs/shells/fish.nix b/home/isabel/programs/shells/fish.nix
new file mode 100644
index 000000000..6d174ada2
--- /dev/null
+++ b/home/isabel/programs/shells/fish.nix
@@ -0,0 +1,31 @@
+_: {
+ programs.fish = {
+ enable = true;
+ catppuccin.enable = true;
+ plugins = [];
+ functions = {
+ bj = "nohup $argv /dev/null &";
+ "." = ''
+ set -l input $argv[1]
+ if echo $input | grep -q '^[1-9][0-9]*$'
+ set -l levels $input
+ for i in (seq $levels)
+ cd ..
+ end
+ else
+ echo "Invalid input format. Please use '' to go back a specific number of directories."
+ end
+ '';
+ };
+ shellAbbrs = {};
+ shellInit = ''
+ starship init fish | source
+ set -x MANPAGER "sh -c 'col -bx | bat -l man -p'"
+ set TERM "xterm-256color"
+ set fish_greeting
+ set TERMINAL "alacritty"
+ export "MICRO_TRUECOLOR=1"
+ export GPG_TTY=$(tty)
+ '';
+ };
+}
diff --git a/home/isabel/programs/shells/nushell.nix b/home/isabel/programs/shells/nushell.nix
new file mode 100644
index 000000000..9d5ab81a2
--- /dev/null
+++ b/home/isabel/programs/shells/nushell.nix
@@ -0,0 +1,281 @@
+{
+ config,
+ lib,
+ pkgs,
+ inputs,
+ osConfig,
+ ...
+}: let
+ inherit (lib) mkIf;
+ inherit (osConfig.modules) system;
+in {
+ programs.nushell = {
+ inherit (osConfig.modules.programs.cli) enable;
+ package = pkgs.nushell;
+
+ extraConfig = ''
+ use std
+ $env.config = {
+ show_banner: false,
+ }
+
+ # nu custom commands
+ # Open a file. Show structured data, if possible. Else fallback to `bat`
+ def o [filename: path] {
+ if (open $filename | describe) == "raw input" {
+ ${lib.getExe pkgs.bat} $filename
+ } else {
+ open $filename
+ }
+ }
+
+ # If multiple shells are open, exit current one. If this is the last one, exit completely.
+ def-env x [] {
+ if (shells | length) == 1 { exit } else { dexit }
+ }
+
+ # Go to system configuration flake, and open editor.
+ def-env fk [] {
+ enter ${system.flakePath}
+ commandline -i ($env.EDITOR + " ./")
+ }
+
+ # CTP theme
+ let catppuccin = {
+ latte: {
+ rosewater: "#dc8a78"
+ flamingo: "#dd7878"
+ pink: "#ea76cb"
+ mauve: "#8839ef"
+ red: "#d20f39"
+ maroon: "#e64553"
+ peach: "#fe640b"
+ yellow: "#df8e1d"
+ green: "#40a02
+ teal: "#179299"
+ sky: "#04a5e5"
+ sapphire: "#209fb5"
+ blue: "#1e66f5"
+ lavender: "#7287fd"
+ text: "#4c4f69"
+ subtext1: "#5c5f77"
+ subtext0: "#6c6f85"
+ overlay2: "#7c7f93"
+ overlay1: "#8c8fa1"
+ overlay0: "#9ca0b0"
+ surface2: "#acb0be"
+ surface1: "#bcc0cc"
+ surface0: "#ccd0da"
+ crust: "#dce0e8"
+ mantle: "#e6e9ef"
+ base: "#eff1f5"
+ }
+ frappe: {
+ rosewater: "#f2d5cf"
+ flamingo: "#eebebe"
+ pink: "#f4b8e4"
+ mauve: "#ca9ee6"
+ red: "#e78284"
+ maroon: "#ea999c"
+ peach: "#ef9f76"
+ yellow: "#e5c890"
+ green: "#a6d189"
+ teal: "#81c8be"
+ sky: "#99d1db"
+ sapphire: "#85c1dc"
+ blue: "#8caaee"
+ lavender: "#babbf1"
+ text: "#c6d0f5"
+ subtext1: "#b5bfe2"
+ subtext0: "#a5adce"
+ overlay2: "#949cbb"
+ overlay1: "#838ba7"
+ overlay0: "#737994"
+ surface2: "#626880"
+ surface1: "#51576d"
+ surface0: "#414559"
+ base: "#303446"
+ mantle: "#292c3c"
+ crust: "#232634"
+ }
+ macchiato: {
+ rosewater: "#f4dbd6"
+ flamingo: "#f0c6c6"
+ pink: "#f5bde6"
+ mauve: "#c6a0f6"
+ red: "#ed8796"
+ maroon: "#ee99a0"
+ peach: "#f5a97f"
+ yellow: "#eed49f"
+ green: "#a6da95"
+ teal: "#8bd5ca"
+ sky: "#91d7e3"
+ sapphire: "#7dc4e4"
+ blue: "#8aadf4"
+ lavender: "#b7bdf8"
+ text: "#cad3f5"
+ subtext1: "#b8c0e0"
+ subtext0: "#a5adcb"
+ overlay2: "#939ab7"
+ overlay1: "#8087a2"
+ overlay0: "#6e738d"
+ surface2: "#5b6078"
+ surface1: "#494d64"
+ surface0: "#363a4f"
+ base: "#24273a"
+ mantle: "#1e2030"
+ crust: "#181926"
+ }
+ mocha: {
+ 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"
+ subtext0: "#a6adc8"
+ overlay2: "#9399b2"
+ overlay1: "#7f849c"
+ overlay0: "#6c7086"
+ surface2: "#585b70"
+ surface1: "#45475a"
+ surface0: "#313244"
+ base: "#1e1e2e"
+ mantle: "#181825"
+ crust: "#11111b"
+ }
+ }
+
+ let stheme = $catppuccin.mocha
+
+ let theme = {
+ separator: $stheme.overlay0
+ leading_trailing_space_bg: $stheme.overlay0
+ header: $stheme.green
+ date: $stheme.mauve
+ filesize: $stheme.blue
+ row_index: $stheme.pink
+ bool: $stheme.peach
+ int: $stheme.peach
+ duration: $stheme.peach
+ range: $stheme.peach
+ float: $stheme.peach
+ string: $stheme.green
+ nothing: $stheme.peach
+ binary: $stheme.peach
+ cellpath: $stheme.peach
+ hints: dark_gray
+
+ shape_garbage: { fg: $stheme.crust bg: $stheme.red attr: b }
+ shape_bool: $stheme.blue
+ shape_int: { fg: $stheme.mauve attr: b}
+ shape_float: { fg: $stheme.mauve attr: b}
+ shape_range: { fg: $stheme.yellow attr: b}
+ shape_internalcall: { fg: $stheme.blue attr: b}
+ shape_external: { fg: $stheme.blue attr: b}
+ shape_externalarg: $stheme.text
+ shape_literal: $stheme.blue
+ shape_operator: $stheme.yellow
+ shape_signature: { fg: $stheme.green attr: b}
+ shape_string: $stheme.green
+ shape_filepath: $stheme.yellow
+ shape_globpattern: { fg: $stheme.blue attr: b}
+ shape_variable: $stheme.text
+ shape_flag: { fg: $stheme.blue attr: b}
+ shape_custom: {attr: b}
+ }
+
+ # nu scripts
+ use "~/.config/nushell/scripts/custom-completions/nix/nix-completions.nu" *
+ use "~/.config/nushell/scripts/custom-completions/git/git-completions.nu" *
+ use "~/.config/nushell/scripts/custom-completions/npm/npm-completions.nu" *
+ use "~/.config/nushell/scripts/custom-completions/just/just-completions.nu" *
+ use "~/.config/nushell/scripts/custom-completions/tealdeer/tldr-completions.nu" *
+ use "~/.config/nushell/scripts/custom-completions/btm/btm-completions.nu" *
+ use "~/.config/nushell/scripts/custom-completions/make/make-completions.nu" *
+
+ source ~/.cache/starship/init.nu
+ '';
+ shellAliases = builtins.removeAttrs config.home.shellAliases ["o" "x" "fk" "mkdir" "nixclean"]; # are nu functions instead
+ envFile.text = ''
+ mkdir ~/.cache/starship
+ starship init nu | str replace "term size -c" "term size" | save -f ~/.cache/starship/init.nu
+
+ '';
+ loginFile.text = let
+ drv = pkgs.runCommandLocal "expand-env.nu" {} ''
+ . "${config.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh"
+ ${builtins.concatStringsSep "\n"
+ (
+ map
+ (key: "echo \\$env.${key} = \\(__login_hm_var_new_value \\\"${key}\\\" \\\"\$${key}\\\"\\) >> $out")
+ ((builtins.attrNames config.home.sessionVariables) ++ ["PATH"])
+ )}
+ '';
+ in
+ #nu
+ ''
+ def __login_hm_var_new_value [key: string, value: string] {
+ if $key in $env {
+ # if it already exists, see if replacement is possible
+ let old = ($env | get $key)
+ let newVal = match ($old | describe) {
+ "string" => {
+ let oldSplit = ($old | split row ":")
+ if ($oldSplit | length) <= 1 {
+ $value # override
+ } else {
+ let newSplit = ($value | split row ":")
+ $oldSplit | prepend $newSplit | uniq | str join ":"
+ }
+ },
+ "list" => ($old | prepend ($value | split row ":") | uniq),
+ }
+ $newVal
+ } else {
+ $value
+ }
+ }
+
+ source ${drv}
+ '';
+ };
+
+ home.file = mkIf osConfig.modules.programs.cli.enable {
+ "${config.xdg.configHome}/nushell/history.txt" = {
+ source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.dataHome}/history";
+ };
+ "${config.xdg.configHome}/nushell/env-nix.nu" = let
+ environmentVariables = {
+ EDITOR = "nvim";
+ GIT_EDITOR = "nvim";
+ VISUAL = "code";
+ TERMINAL = "alacritty";
+ };
+ in {
+ text = ''
+ ${lib.concatStringsSep "\n"
+ (lib.mapAttrsToList (k: v: "$env.${k} = ${v}")
+ environmentVariables)}
+ '';
+ };
+ "${config.xdg.configHome}/nushell/scripts" = {
+ source = pkgs.fetchFromGitHub {
+ owner = "nushell";
+ repo = "nu_scripts";
+ rev = "85da8c2fb5967a7f575d8f63ebeb8d49d36fc139";
+ hash = "sha256-tT/BTnIXEgcMoyfujzWMFlOM7EclWT9LL/dt5jj7Y2M=";
+ };
+ };
+ };
+}
diff --git a/home/isabel/programs/shells/shellAlias.nix b/home/isabel/programs/shells/shellAlias.nix
new file mode 100644
index 000000000..a8be3254d
--- /dev/null
+++ b/home/isabel/programs/shells/shellAlias.nix
@@ -0,0 +1,23 @@
+{osConfig, ...}: let
+ inherit (osConfig.modules) system;
+in {
+ # This configuration creates the shell aliases across: bash, zsh and fish
+ home.shellAliases = {
+ mkdir = "mkdir -pv"; # always create pearent directory
+ df = "df -h"; # human readblity
+ rs = "sudo reboot";
+ sysctl = "sudo systemctl";
+ jctl = "journalctl -p 3 -xb"; # get error messages from journalctl
+ lg = "lazygit";
+
+ # Remap docker to podman
+ docker = "podman";
+ docker-compose = "podman-compose";
+
+ # nix stuff
+ rebuild = "nix-store --verify; sudo nixos-rebuild switch --flake ${system.flakePath}#${system.hostname} --use-remote-sudo";
+ deploy = "nixos-rebuild switch --flake ${system.flakePath}#$1 --target-host $1 --use-remote-sudo";
+ nixclean = "sudo nix-collect-garbage --delete-older-than 3d && nix-collect-garbage -d";
+ nixrepair = "nix-store --verify --check-contents --repair";
+ };
+}
diff --git a/home/isabel/btop.nix b/home/isabel/programs/tui/confs/btop.nix
similarity index 53%
rename from home/isabel/btop.nix
rename to home/isabel/programs/tui/confs/btop.nix
index 95dde838a..7a2ccfc05 100644
--- a/home/isabel/btop.nix
+++ b/home/isabel/programs/tui/confs/btop.nix
@@ -2,19 +2,15 @@
osConfig,
lib,
...
-}:
-with lib; let
- programs = osConfig.modules.programs;
- device = osConfig.modules.device;
-
+}: let
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.cli.enable)) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.tui.enable) {
programs.btop = {
enable = true;
catppuccin.enable = true;
settings = {
- # color_theme = "catppuccin_mocha";
+ color_theme = "catppuccin_mocha";
vim_keys = true;
rounded_corners = true;
};
diff --git a/home/isabel/programs/tui/confs/default.nix b/home/isabel/programs/tui/confs/default.nix
index d8524f17f..af81e156b 100644
--- a/home/isabel/programs/tui/confs/default.nix
+++ b/home/isabel/programs/tui/confs/default.nix
@@ -1,5 +1,6 @@
_: {
imports = [
+ ./btop.nix
./lazygit.nix
./ranger.nix
];
diff --git a/home/isabel/programs/tui/confs/lazygit.nix b/home/isabel/programs/tui/confs/lazygit.nix
index 1959d7d3b..a71491f92 100644
--- a/home/isabel/programs/tui/confs/lazygit.nix
+++ b/home/isabel/programs/tui/confs/lazygit.nix
@@ -3,11 +3,8 @@
lib,
osConfig,
...
-}: let
- inherit (lib) mkIf;
- inherit (osConfig.modules) programs;
-in {
- config.programs.lazygit = mkIf (programs.tui.enable) {
+}: {
+ config.programs.lazygit = lib.mkIf (osConfig.modules.programs.tui.enable) {
enable = true;
catppuccin.enable = true;
};
diff --git a/home/isabel/programs/tui/confs/ranger.nix b/home/isabel/programs/tui/confs/ranger.nix
index e7ef197f7..0c14f7571 100644
--- a/home/isabel/programs/tui/confs/ranger.nix
+++ b/home/isabel/programs/tui/confs/ranger.nix
@@ -4,13 +4,10 @@
osConfig,
lib,
...
-}:
-with lib; let
- inherit (osConfig.modules) programs device;
-
+}: let
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (programs.tui.enable)) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && osConfig.modules.programs.tui.enable) {
home.packages = with pkgs; [
ranger
];
@@ -18,7 +15,7 @@ in {
# TODO: more file preview methods
xdg.configFile."ranger/rc.conf".text = ''
set preview_images true
- ${(optionalString config.programs.kitty.enable "set preview_images_method kitty")}
+ ${(lib.optionalString config.programs.kitty.enable "set preview_images_method kitty")}
'';
};
}
diff --git a/home/isabel/programs/tui/default.nix b/home/isabel/programs/tui/default.nix
index 0d8cae13a..8effbc4b7 100644
--- a/home/isabel/programs/tui/default.nix
+++ b/home/isabel/programs/tui/default.nix
@@ -1,21 +1,18 @@
{
- config,
pkgs,
osConfig,
lib,
...
-}: let
- inherit (lib) mkIf;
- inherit (osConfig.modules) programs;
-in {
+}: {
imports = [
./confs
];
- config = mkIf (programs.tui.enable) {
+ config = lib.mkIf osConfig.modules.programs.tui.enable {
home.packages = with pkgs; [
wishlist # fancy ssh
glow # fancy markdown
+ fx # fancy jq
];
};
}
diff --git a/home/isabel/programs/wm/hyprland/config.nix b/home/isabel/programs/wm/hyprland/config.nix
index b74b6264d..dd8a3f684 100644
--- a/home/isabel/programs/wm/hyprland/config.nix
+++ b/home/isabel/programs/wm/hyprland/config.nix
@@ -10,30 +10,6 @@
pointer = config.home.pointerCursor;
dev = osConfig.modules.device;
inherit (osConfig.modules.device) monitors;
-
- mapMonitors = builtins.concatStringsSep "\n" (imap0 (i: monitor: ''monitor=${monitor},${
- if monitor == "DP-1"
- then "1920x1080@144"
- else "preferred"
- },${toString (i * 1920)}x0,1'') monitors);
-
- mapMonitorsToWs = builtins.concatStringsSep "\n" (
- builtins.genList (
- x: ''
- workspace = ${toString (x + 1)}, monitor:${
- if (x + 1) <= 5
- then "${builtins.elemAt monitors 0} ${
- if (x + 1) == 1
- then ", default:true"
- else ""
- }"
- else "${builtins.elemAt monitors 1}"
- }
-
- ''
- )
- 10
- );
in {
wayland.windowManager.hyprland = {
settings = {
@@ -59,7 +35,7 @@ in {
"waybar"
]
++ optionals (defaults.bar == "ags") [
- "ags"
+ "ags -b hypr"
];
input = {
@@ -69,8 +45,9 @@ in {
touchpad = {
tap-to-click = true;
natural_scroll = false; # this is not natrual
- disable_while_typing = false;
+ disable_while_typing = false; # this is annoying
};
+ numlock_by_default = true; # numlock enable
};
gestures.workspace_swipe = dev.type == "laptop" || dev.type == "hybrid";
@@ -85,8 +62,23 @@ in {
"col.active_border" = "$sapphire";
"col.inactive_border" = "$surface0";
- "col.group_border_active" = "$blue";
- "col.group_border" = "$surface0";
+ };
+
+ group = {
+ insert_after_current = true;
+ # focus on the window that has just been moved out of the group
+ focus_removed_window = true;
+
+ "col.border_active" = "$blue";
+ "col.border_inactive" = "$surface0";
+
+ groupbar = {
+ gradients = false;
+ font_size = 12;
+
+ render_titles = false;
+ scrolling = true; # change focused window with scroll
+ };
};
misc = {
@@ -105,7 +97,6 @@ in {
decoration = {
rounding = 10;
- multisample_edges = true;
active_opacity = 1.0;
inactive_opacity = 1.0;
@@ -128,7 +119,7 @@ in {
};
animations = {
- enabled = !(dev.type == "laptop");
+ enabled = dev.type != "laptop";
bezier = [
"overshot, 0.05, 0.9, 0.1, 1.1"
@@ -185,7 +176,7 @@ in {
"$mod, E, exec, ${defaults.fileManager}"
"$mod, C, exec, ${defaults.editor}"
"$mod, Return, exec, ${defaults.terminal}"
- "$mod, L, exec, ${defaults.screenLock}"
+ "$mod, L, exec, ${defaults.screenLocker}"
"$mod, O, exec, obsidian"
# window managment
@@ -224,16 +215,17 @@ in {
]
++ optionals (defaults.bar == "waybar") [
"$mod, D, exec, rofi -show drun"
+ ", XF86AudioMute, exec, pamixer -t"
"$mod, escape, exec, wlogout"
"$mod, period, exec, killall rofi || rofi -show emoji -emoji-format '{emoji}' -modi emoji"
]
++ optionals (defaults.bar == "ags") [
- "$mod, D, exec, ags toggle-window applauncher"
- "$mod, escape, exec, ags toggle-window powermenu"
- "$mod SHIFT, R, exec, ags quit ; ags"
+ "$mod, D, exec, ags -b hypr -t applauncher"
+ "$mod, escape, exec, ags -b hypr -t powermenu"
+ "$mod SHIFT, R, exec, ags -b hypr --quit ; ags -b hypr"
+ ", Xf86AudioMute, exec, ags -b hypr -r 'volume.master.toggleMute(); indicator.display()'"
]
++ optionals (defaults.bar != "eww") [
- ", XF86AudioMute, exec, pamixer -t"
", Print, exec, grim -g '$(slurp)' - | swappy -f -"
"$mod, V, exec, cliphist list | rofi -dmenu -p 'Clipboard' | cliphist decode | wl-copy"
]
@@ -244,24 +236,20 @@ in {
", XF86AudioPrev, exec, playerctl previous"
];
- bindle =
- []
- ++ optionals (defaults.bar == "ags") [
- ", XF86MonBrightnessUp, exec, ags run-js 'ags.Service.Brightness.screen += 0.02; ags.Service.Indicator.display()'"
- ", XF86MonBrightnessDown, exec, ags run-js 'ags.Service.Brightness.screen -= 0.02; ags.Service.Indicator.display()'"
- ", XF86AudioRaiseVolume, exec, ags run-js 'ags.Service.Audio.speaker.volume += 0.05; ags.Service.Indicator.speaker()'"
- ", XF86AudioLowerVolume, exec, ags run-js 'ags.Service.Audio.speaker.volume -= 0.05; ags.Service.Indicator.speaker()'"
- ];
+ bindle = optionals (defaults.bar == "ags") [
+ ", XF86MonBrightnessUp, exec, ags -b hypr -r 'brightness.screen += 0.05; indicator.display()'"
+ ", XF86MonBrightnessDown, exec, ags -b hypr -r 'brightness.screen -= 0.05; indicator.display()'"
+ ", XF86AudioRaiseVolume, exec, ags -b hypr -r 'audio.speaker.volume += 0.05; indicator.speaker()'"
+ ", XF86AudioLowerVolume, exec, ags -b hypr -r 'audio.speaker.volume -= 0.05; indicator.speaker()'"
+ ];
- bindl =
- []
- ++ optionals (defaults.bar == "ags") [
- ", XF86AudioPlay, exec, ags run-js `ags.Service.Mpris.getPlayer()?.playPause()`"
- ", XF86AudioStop, exec, ags run-js `ags.Service.Mpris.getPlayer()?.stop()`"
- ", XF86AudioPause, exec, ags run-js `ags.Service.Mpris.getPlayer()?.pause()`"
- ", XF86AudioPrev, exec, ags run-js `ags.Service.Mpris.getPlayer()?.previous()`"
- ", XF86AudioNext, exec, ags run-js `ags.Service.Mpris.getPlayer()?.next()`"
- ];
+ bindl = optionals (defaults.bar == "ags") [
+ ", XF86AudioPlay, exec, ags -b hypr -r 'mpris.players.pop()?.playPause()'"
+ ", XF86AudioStop, exec, ags -b hypr -r 'mpris.players.pop()?.stop()'"
+ ", XF86AudioPause, exec, ags -b hypr -r 'mpris.players.pop()?.pause()'"
+ ", XF86AudioPrev, exec, ags -b hypr -r 'mpris.players.pop()?.previous()'"
+ ", XF86AudioNext, exec, ags -b hypr -r 'mpris.players.pop()?.next()'"
+ ];
# mouse binds
bindm = [
@@ -271,8 +259,7 @@ in {
# hold to repeat action buttons
binde =
- []
- ++ optionals (defaults.bar == "eww") [
+ optionals (defaults.bar == "eww") [
", XF86AudioRaiseVolume, exec, ~/.config/eww/scripts/volume up"
", XF86AudioLowerVolume, exec, ~/.config/eww/scripts/volume down"
", XF86MonBrightnessUp, exec, ~/.config/eww/scripts/brightness up"
@@ -286,7 +273,30 @@ in {
];
};
- extraConfig = ''
+ extraConfig = let
+ mapMonitors = builtins.concatStringsSep "\n" (imap0 (i: monitor: ''monitor=${monitor},${
+ if monitor == "DP-1"
+ then "1920x1080@144"
+ else "preferred"
+ },${toString (i * 1920)}x0,1'') monitors);
+
+ mapMonitorsToWs = builtins.concatStringsSep "\n" (
+ builtins.genList (
+ x: ''
+ workspace = ${toString (x + 1)}, monitor:${
+ if (x + 1) <= 5
+ then "${builtins.elemAt monitors 0} ${
+ if (x + 1) == 1
+ then ", default:true"
+ else ""
+ }"
+ else "${builtins.elemAt monitors 1}"
+ }
+ ''
+ )
+ 10
+ );
+ in ''
${mapMonitors}
${optionalString (builtins.length monitors != 1) "${mapMonitorsToWs}"}
diff --git a/home/isabel/programs/wm/hyprland/default.nix b/home/isabel/programs/wm/hyprland/default.nix
index 535fa66b7..8bdfddbfc 100644
--- a/home/isabel/programs/wm/hyprland/default.nix
+++ b/home/isabel/programs/wm/hyprland/default.nix
@@ -4,32 +4,27 @@
osConfig,
inputs',
...
-}:
-with lib; let
- hyprpicker = inputs'.hyprpicker.packages.default;
- hyprland-share-picker = inputs'.xdg-portal-hyprland.packages.xdg-desktop-portal-hyprland;
+}: let
+ inherit (osConfig.modules) device usrEnv;
- env = osConfig.modules.usrEnv;
- device = osConfig.modules.device;
- sys = osConfig.modules.system;
- programs = osConfig.modules.programs;
+ acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
imports = [./config.nix];
- config = mkIf ((sys.video.enable) && (env.isWayland && (env.desktop == "Hyprland"))) {
- home.packages = with pkgs;
- [
- grim
- hyprpicker
- hyprland-share-picker
- ]
- ++ optionals (programs.nur.enable && programs.nur.bella) [
- nur.repos.bella.catppuccin-hyprland
- ];
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && lib.isWayland osConfig && usrEnv.desktop == "Hyprland") {
+ home.packages = with pkgs; [
+ grim
+ inputs'.hyprpicker.packages.default
+ ];
+
wayland.windowManager.hyprland = {
enable = true;
- systemdIntegration = true;
- package = inputs'.hyprland.packages.default.override {
- enableNvidiaPatches = (device.gpu == "nvidia") || (device.gpu == "hybrid-nv");
+ package = inputs'.hyprland.packages.default;
+ enableNvidiaPatches = (device.gpu == "nvidia") || (device.gpu == "hybrid-nv");
+ xwayland.enable = true;
+
+ systemd = {
+ enable = true;
+ variables = ["--all"];
};
};
};
diff --git a/home/isabel/programs/wm/sway/config.nix b/home/isabel/programs/wm/sway/config.nix
index d42564264..f5dd3cc13 100644
--- a/home/isabel/programs/wm/sway/config.nix
+++ b/home/isabel/programs/wm/sway/config.nix
@@ -1,84 +1,79 @@
{
- lib,
config,
defaults,
...
-}: let
- inherit (lib) mkIf;
-in {
- config = mkIf (config.wayland.windowManager.sway.enable) {
- wayland.windowManager.sway = {
- config = {
- modifier = "Mod4";
- workspaceAutoBackAndForth = true;
- terminal = defaults.terminal;
- menu = defaults.launcher;
- defaultWorkspace = "workspace number 1";
+}: {
+ wayland.windowManager.sway = {
+ config = {
+ modifier = "Mod4";
+ workspaceAutoBackAndForth = true;
+ terminal = defaults.terminal;
+ menu = defaults.launcher;
+ defaultWorkspace = "workspace number 1";
- keybindings = let
- mod = config.wayland.windowManager.sway.config.modifier;
- in {
- # launchers
- "${mod}+Return" = "exec ${defaults.terminal}";
- "${mod}+d" = "exec ${defaults.launcher}";
- "${mod}+b" = "exec ${defaults.browser}";
- "${mod}+e" = "exec ${defaults.fileManager}";
- "${mod}+o" = "exec obsidian";
+ keybindings = let
+ mod = config.wayland.windowManager.sway.config.modifier;
+ in {
+ # launchers
+ "${mod}+Return" = "exec ${defaults.terminal}";
+ "${mod}+d" = "exec ${defaults.launcher}";
+ "${mod}+b" = "exec ${defaults.browser}";
+ "${mod}+e" = "exec ${defaults.fileManager}";
+ "${mod}+o" = "exec obsidian";
- "${mod}+l" = "exec swaylock";
- "${mod}+t" = "floating toggle";
- "Print" = "grim -g \"$(slurp)\"";
- "${mod}+q" = "kill";
- };
+ "${mod}+l" = "exec swaylock";
+ "${mod}+t" = "floating toggle";
+ "Print" = "grim -g \"$(slurp)\"";
+ "${mod}+q" = "kill";
+ };
- window = {
- titlebar = false;
- hideEdgeBorders = "none";
- border = 2;
- };
+ window = {
+ titlebar = false;
+ hideEdgeBorders = "none";
+ border = 2;
+ };
- gaps = {
- smartBorders = "on";
- outer = 5;
- inner = 5;
- };
+ gaps = {
+ smartBorders = "on";
+ outer = 5;
+ inner = 5;
+ };
- startup = [{command = "dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY";}];
+ startup = [{command = "dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY";}];
- input = {
- "type:pointer" = {
- accel_profile = "flat";
- pointer_accel = "0";
- };
- "type:touchpad" = {
- middle_emulation = "enabled";
- natural_scroll = "enabled";
- tap = "enabled";
- };
+ input = {
+ "type:pointer" = {
+ accel_profile = "flat";
+ pointer_accel = "0";
+ };
+ "type:touchpad" = {
+ middle_emulation = "enabled";
+ natural_scroll = "enabled";
+ tap = "enabled";
};
- extraConfig = ''
- set $ws1 1:一
- set $ws2 2:二
- set $ws3 3:三
- set $ws4 4:四
- set $ws5 5:五
- set $ws6 6:六
- set $ws7 7:七
- set $ws8 8:八
- set $ws9 9:九
- set $ws10 10:十
+ };
+ extraConfig = ''
+ set $ws1 1:一
+ set $ws2 2:二
+ set $ws3 3:三
+ set $ws4 4:四
+ set $ws5 5:五
+ set $ws6 6:六
+ set $ws7 7:七
+ set $ws8 8:八
+ set $ws9 9:九
+ set $ws10 10:十
- for_window [window_role="PictureInPicture"] floating enable sticky enable
- for_window [class="Pavucontrol"] floating enable
+ for_window [window_role="PictureInPicture"] floating enable sticky enable
+ for_window [class="Pavucontrol"] floating enable
- corner_radius 5
- smart_corner_radius enable
+ corner_radius 5
+ smart_corner_radius enable
- blur enable
- blur_passes 2
- blur_radius 4
- '';
- };
+ blur enable
+ blur_passes 2
+ blur_radius 4
+ '';
};
};
}
diff --git a/home/isabel/programs/wm/sway/default.nix b/home/isabel/programs/wm/sway/default.nix
index e15fad9a6..3e3997ef4 100644
--- a/home/isabel/programs/wm/sway/default.nix
+++ b/home/isabel/programs/wm/sway/default.nix
@@ -1,10 +1,14 @@
-{lib, ...}:
-with lib; let
- env = osConfig.modules.usrEnv;
- sys = osConfig.modules.system;
+{
+ lib,
+ osConfig,
+ ...
+}: let
+ inherit (osConfig.modules) usrEnv;
+
+ acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
imports = [./config.nix];
- config = mkIf ((sys.video.enable) && (env.isWayland && (env.desktop == "Sway"))) {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && lib.isWayland osConfig && usrEnv.desktop == "Sway") {
wayland.windowManager.sway = {
enable = true;
package = null;
diff --git a/home/isabel/services/default.nix b/home/isabel/services/default.nix
index ac6ebb398..859966c66 100644
--- a/home/isabel/services/default.nix
+++ b/home/isabel/services/default.nix
@@ -1,7 +1,9 @@
_: {
imports = [
- ./wayland # services that are wayland-only
- ./x11 # services that are x11-only
- ./shared # services that should be enabled regardless
+ ./shared # Always on services
+ ./wayland # wayland-only services
+ #./x11 # x11-only services
+
+ ./nix-index.nix
];
}
diff --git a/home/isabel/services/nix-index.nix b/home/isabel/services/nix-index.nix
new file mode 100644
index 000000000..28f664db3
--- /dev/null
+++ b/home/isabel/services/nix-index.nix
@@ -0,0 +1,13 @@
+{inputs, ...}: {
+ imports = [inputs.nix-index-db.hmModules.nix-index];
+
+ config.programs = {
+ nix-index = {
+ enable = true;
+
+ # link nix-index database to ~/.cache/nix-index
+ symlinkToCacheHome = true;
+ };
+ nix-index-database.comma.enable = true;
+ };
+}
diff --git a/home/isabel/services/shared/cloud/default.nix b/home/isabel/services/shared/cloud/default.nix
new file mode 100644
index 000000000..026d35ba3
--- /dev/null
+++ b/home/isabel/services/shared/cloud/default.nix
@@ -0,0 +1,28 @@
+{
+ lib,
+ osConfig,
+ pkgs,
+ ...
+}: let
+ acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
+in {
+ config = lib.mkIf ((lib.isAcceptedDevice osConfig acceptedTypes) && (lib.isWayland osConfig)) {
+ /*
+ services = {
+ nextcloud-client.enable = true;
+ nextcloud-client.startInBackground = true;
+ };
+ */
+
+ home.packages = [pkgs.nextcloud-client];
+
+ systemd.user.services.nextcloud = lib.mkGraphicalService {
+ Unit.Description = "Nextcloud client service";
+ Service = {
+ ExecStart = "${pkgs.nextcloud-client}/bin/nextcloud --background";
+ Restart = "always";
+ Slice = "background.slice";
+ };
+ };
+ };
+}
diff --git a/home/isabel/services/shared/default.nix b/home/isabel/services/shared/default.nix
index 31d3e81a2..eb3a0c339 100644
--- a/home/isabel/services/shared/default.nix
+++ b/home/isabel/services/shared/default.nix
@@ -1,5 +1,6 @@
_: {
imports = [
+ ./cloud
./polkit
./kdeconnect.nix
diff --git a/home/isabel/services/shared/kdeconnect.nix b/home/isabel/services/shared/kdeconnect.nix
index 0949295b5..9210fc233 100644
--- a/home/isabel/services/shared/kdeconnect.nix
+++ b/home/isabel/services/shared/kdeconnect.nix
@@ -2,14 +2,14 @@
lib,
osConfig,
...
-}:
-with lib; let
- device = osConfig.modules.device;
+}: let
+ inherit (osConfig.modules.system) video;
+ inherit (lib) mkIf isAcceptedDevice;
+
acceptedTypes = ["desktop" "laptop" "hybrid"];
- sys = osConfig.modules.system;
in {
- config = mkIf (builtins.elem device.type acceptedTypes && sys.video.enable) {
- # connect my phone
+ config = mkIf ((isAcceptedDevice osConfig acceptedTypes) && video.enable) {
+ # connect my phone, please its so inconsistant
services.kdeconnect = {
enable = true;
indicator = true;
diff --git a/home/isabel/services/shared/polkit/default.nix b/home/isabel/services/shared/polkit/default.nix
index cef89efd3..4f6e23078 100644
--- a/home/isabel/services/shared/polkit/default.nix
+++ b/home/isabel/services/shared/polkit/default.nix
@@ -3,18 +3,19 @@
osConfig,
pkgs,
...
-}:
-with lib; let
- device = osConfig.modules.device;
- video = osConfig.modules.system.video;
- env = osConfig.modules.usrEnv;
-
+}: let
+ inherit (lib) mkIf isAcceptedDevice mkGraphicalService;
+ inherit (osConfig.modules.system) video;
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (video.enable && env.isWayland)) {
+ config = mkIf ((isAcceptedDevice osConfig acceptedTypes) && video.enable) {
# gnome polkit agent
- systemd.user.services.polkit-gnome-authentication-agent-1 = lib.mkGraphicalService {
- Service.ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
+ # systemd.user.services.polkit-gnome-authentication-agent-1 = mkGraphicalService {
+ # Service.ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
+
+ # pantheon alternate, probaly runs lighter
+ systemd.user.services.polkit-pantheon-authentication-agent-1 = mkGraphicalService {
+ Service.ExecStart = "${pkgs.pantheon.pantheon-agent-polkit}/libexec/policykit-1-pantheon/io.elementary.desktop.agent-polkit";
};
};
}
diff --git a/home/isabel/services/shared/rnnoise.nix b/home/isabel/services/shared/rnnoise.nix
index 000795e44..70a76c366 100644
--- a/home/isabel/services/shared/rnnoise.nix
+++ b/home/isabel/services/shared/rnnoise.nix
@@ -4,14 +4,13 @@
pkgs,
...
}: let
- inherit (lib) mkIf;
- inherit (osConfig.modules) device;
+ inherit (lib) mkIf isAcceptedDevice;
json = pkgs.formats.json {};
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes) {
+ config = mkIf (isAcceptedDevice osConfig acceptedTypes) {
xdg.configFile."pipewire/pipewire.conf.d/99-input-denoising.conf" = {
source = json.generate "99-input-denoising.conf" {
"context.modules" = [
diff --git a/home/isabel/services/shared/tray.nix b/home/isabel/services/shared/tray.nix
index 528d8385a..8dd3eebb7 100644
--- a/home/isabel/services/shared/tray.nix
+++ b/home/isabel/services/shared/tray.nix
@@ -3,10 +3,10 @@
lib,
...
}: let
- env = osConfig.modules.usrEnv;
+ inherit (lib) mkIf isAcceptedDevice;
+ acceptedTypes = ["lite" "hybrid" "laptop" "desktop"];
in {
- config = (lib.mkIf env.useHomeManager) {
- # fake a tray to let apps start
+ config = mkIf (isAcceptedDevice osConfig acceptedTypes) {
# https://github.com/nix-community/home-manager/issues/2064
systemd.user.targets.tray = {
Unit = {
diff --git a/home/isabel/services/wayland/clipboard.nix b/home/isabel/services/wayland/clipboard.nix
index 194c9952b..ea1cdd3fd 100644
--- a/home/isabel/services/wayland/clipboard.nix
+++ b/home/isabel/services/wayland/clipboard.nix
@@ -3,20 +3,16 @@
pkgs,
osConfig,
...
-}:
-with lib; let
- device = osConfig.modules.device;
- video = osConfig.modules.system.video;
- env = osConfig.modules.usrEnv;
-
+}: let
+ inherit (lib) mkIf isAcceptedDevice isWayland mkGraphicalService getExe;
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem device.type acceptedTypes) && (video.enable && env.isWayland)) {
+ config = mkIf ((isAcceptedDevice osConfig acceptedTypes) && (isWayland osConfig)) {
systemd.user.services = {
- cliphist = lib.mkGraphicalService {
+ cliphist = mkGraphicalService {
Unit.Description = "Clipboard history service";
Service = {
- ExecStart = "${pkgs.wl-clipboard}/bin/wl-paste --watch ${lib.getExe pkgs.cliphist} store";
+ ExecStart = "${pkgs.wl-clipboard}/bin/wl-paste --watch ${getExe pkgs.cliphist} store";
Restart = "always";
};
};
diff --git a/home/isabel/services/wayland/default.nix b/home/isabel/services/wayland/default.nix
index c884bc22d..dd1e033f2 100644
--- a/home/isabel/services/wayland/default.nix
+++ b/home/isabel/services/wayland/default.nix
@@ -1,6 +1,5 @@
_: {
imports = [
./screenlock
- #./clipboard.nix
];
}
diff --git a/home/isabel/services/wayland/screenlock/gtklock.nix b/home/isabel/services/wayland/screenlock/gtklock.nix
index 57844e9e9..70ac5104a 100644
--- a/home/isabel/services/wayland/screenlock/gtklock.nix
+++ b/home/isabel/services/wayland/screenlock/gtklock.nix
@@ -6,14 +6,10 @@
defaults,
...
}: let
- inherit (lib) mkIf;
- dev = osConfig.modules.device;
- vid = osConfig.modules.system.video;
- env = osConfig.modules.usrEnv;
-
+ inherit (lib) mkIf isAcceptedDevice isWayland;
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem dev.type acceptedTypes && defaults.screenLock == "gtklock") && (vid.enable && env.isWayland)) {
+ config = mkIf ((isAcceptedDevice osConfig acceptedTypes) && (isWayland osConfig) && defaults.screenLocker == "gtklock") {
programs.gtklock = {
enable = true;
package = pkgs.gtklock;
diff --git a/home/isabel/services/wayland/screenlock/swaylock.nix b/home/isabel/services/wayland/screenlock/swaylock.nix
index fb9d69cc0..05902e341 100644
--- a/home/isabel/services/wayland/screenlock/swaylock.nix
+++ b/home/isabel/services/wayland/screenlock/swaylock.nix
@@ -6,15 +6,10 @@
defaults,
...
}: let
- inherit (lib) mkIf;
-
- dev = osConfig.modules.device;
- vid = osConfig.modules.system.video;
- env = osConfig.modules.usrEnv;
-
+ inherit (lib) mkIf isWayland isAcceptedDevice;
acceptedTypes = ["desktop" "laptop" "lite" "hybrid"];
in {
- config = mkIf ((builtins.elem dev.type acceptedTypes && defaults.screenLock == "swaylock") && (vid.enable && env.isWayland)) {
+ config = mkIf ((isAcceptedDevice osConfig acceptedTypes) && (isWayland osConfig) && defaults.screenLocker == "swaylock") {
home.packages = with pkgs; [swaylock-effects];
programs.swaylock = {
diff --git a/home/isabel/shells/default.nix b/home/isabel/shells/default.nix
deleted file mode 100644
index b901e1c6f..000000000
--- a/home/isabel/shells/default.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{...}: {
- home.file."shells/" = {source = ../shells;};
-}
diff --git a/home/isabel/shells/docker.nix b/home/isabel/shells/docker.nix
deleted file mode 100644
index d394e9223..000000000
--- a/home/isabel/shells/docker.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- pkgs ? import {},
- extras ? "",
-}:
-pkgs.mkShell {
- nativeBuildInputs = with pkgs; [
- docker
- docker-compose
- extras
- ];
-}
diff --git a/home/isabel/shells/node.nix b/home/isabel/shells/node.nix
deleted file mode 100644
index 593c31781..000000000
--- a/home/isabel/shells/node.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- pkgs ? import {},
- extras ? "",
-}:
-pkgs.mkShell {
- nativeBuildInputs = with pkgs; [
- nodejs
- nodePackages.typescript
- extras
- ];
-}
diff --git a/home/isabel/shells/py.nix b/home/isabel/shells/py.nix
deleted file mode 100644
index 105247bf7..000000000
--- a/home/isabel/shells/py.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- pkgs ? import {},
- extras ? "",
-}:
-pkgs.mkShell {
- nativeBuildInputs = with pkgs; [
- python
- python3
- extras
- ];
-}
diff --git a/home/isabel/shells/rust.nix b/home/isabel/shells/rust.nix
deleted file mode 100644
index 3d72bcc0a..000000000
--- a/home/isabel/shells/rust.nix
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- pkgs ? import {},
- extras ? "",
-}:
-pkgs.mkShell {
- buildInputs = with pkgs; [
- rustc
- rustfmt
- sccache
- rust-analyzer
- cargo
- openssl
- extras
- ];
-
- shellHook = ''
- export OPENSSL_DIR="${pkgs.openssl.dev}"
- export OPENSSL_LIB_DIR="${pkgs.openssl.out}/lib"
- '';
-}
diff --git a/home/isabel/shells/spawnshell.sh b/home/isabel/shells/spawnshell.sh
deleted file mode 100755
index 289238eeb..000000000
--- a/home/isabel/shells/spawnshell.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-if [[ $# -gt 1 ]]; then
- extras="${*:2}"
- nix-shell ~/shells/"$1".nix --arg extras "with import {}; [ $extras ]"
-else
- nix-shell ~/shells/"$1".nix
-fi
diff --git a/home/isabel/system/default.nix b/home/isabel/system/default.nix
index 77695f7a1..083ed5459 100644
--- a/home/isabel/system/default.nix
+++ b/home/isabel/system/default.nix
@@ -1,5 +1,6 @@
_: {
imports = [
+ ./env.nix
./gpg.nix
./ssh.nix
./xdg.nix
diff --git a/home/isabel/system/env.nix b/home/isabel/system/env.nix
new file mode 100644
index 000000000..83e1f6a65
--- /dev/null
+++ b/home/isabel/system/env.nix
@@ -0,0 +1,15 @@
+{
+ osConfig,
+ defaults,
+ ...
+}: {
+ home.sessionVariables = {
+ EDITOR = defaults.editor;
+ GIT_EDITOR = defaults.editor;
+ VISUAL = defaults.editor;
+ TERMINAL = defaults.terminal;
+ SYSTEMD_PAGERSECURE = "true";
+ PAGER = "less -FR";
+ FLAKE = "${osConfig.modules.system.flakePath}";
+ };
+}
diff --git a/home/isabel/system/gpg.nix b/home/isabel/system/gpg.nix
index 72bc1d7c4..0c0c8d2d7 100644
--- a/home/isabel/system/gpg.nix
+++ b/home/isabel/system/gpg.nix
@@ -5,7 +5,7 @@
inputs,
...
}: let
- sys = osConfig.modules.system;
+ inherit (osConfig.modules.system) video;
in {
imports = [inputs.sops.homeManagerModules.sops];
@@ -13,7 +13,7 @@ in {
gpg-agent = {
enable = true;
pinentryFlavor =
- if (sys.video.enable)
+ if (video.enable)
then "gnome3"
else "curses";
enableSshSupport = true;
@@ -25,7 +25,7 @@ in {
};
};
- # Allow manually restarting gpg-agent in case of failure
+ # Allow manually restarting gpg-agent if it fails
systemd.user.services.gpg-agent.Unit.RefuseManualStart = lib.mkForce false;
sops.gnupg.home = config.programs.gpg.homedir;
diff --git a/home/isabel/system/ssh.nix b/home/isabel/system/ssh.nix
index f7f46e20b..5d3385cfa 100644
--- a/home/isabel/system/ssh.nix
+++ b/home/isabel/system/ssh.nix
@@ -1,15 +1,21 @@
-{pkgs, ...}: {
- home.packages = with pkgs; [cloudflared];
+_: {
+ # {pkgs, ...}: {
+ # home.packages = with pkgs; [cloudflared];
programs = {
ssh = {
enable = true;
hashKnownHosts = true;
compression = true;
- extraConfig = ''
- Host *
- Port 22
- '';
- matchBlocks = {
+ matchBlocks = let
+ base = {
+ user = "isabel";
+ };
+ template =
+ base
+ // {
+ identityFile = "~/.ssh/nixos";
+ };
+ in {
# git clients
"aur.archlinux.org" = {
user = "aur";
@@ -30,31 +36,34 @@
identityFile = "~/.ssh/openvpn";
};
- #"edalyn" = {
- # hostname = "141.147.113.225";
- # user = "ubuntu";
- # identityFile = "~/.ssh/edalyn";
- #};
-
- #"luz" = {
- # hostname = "144.21.55.221";
- # user = "ubuntu";
- # identityFile = "~/.ssh/luz";
- #};
-
"king" = {
hostname = "150.230.117.215";
user = "ubuntu";
identityFile = "~/.ssh/king";
};
- "bernie" = {
- hostname = "143.47.240.116";
- user = "isabel";
- identityFile = "~/.ssh/bernie";
- };
+ "amity" =
+ base
+ // {
+ hostname = "143.47.240.116";
+ identityFile = "~/.ssh/amity";
+ };
+
+ # hetzner cloud vps
+ "bernie" =
+ template
+ // {
+ hostname = "91.107.198.173";
+ };
# my local servers / clients
+ "hydra" =
+ template
+ // {
+ hostname = "192.168.86.3";
+ };
+
+ /*
"alpha" = {
hostname = "192.168.86.4";
user = "isabel";
@@ -67,12 +76,7 @@
identityFile = "~/.ssh/alpha";
proxyCommand = "cloudflared access ssh --hostname %h";
};
-
- "hydra" = {
- hostname = "192.168.86.3";
- user = "isabel";
- identityFile = "~/.ssh/hydra";
- };
+ */
};
};
};
diff --git a/home/isabel/system/xdg.nix b/home/isabel/system/xdg.nix
index b76385526..5e28dfa05 100644
--- a/home/isabel/system/xdg.nix
+++ b/home/isabel/system/xdg.nix
@@ -3,7 +3,8 @@
pkgs,
...
}: let
- browser = ["chromium.desktop"];
+ # browser = ["chromium.desktop"];
+ browser = ["Schizofox.desktop"];
zathura = ["org.pwmt.zathura.desktop"];
filemanager = ["thunar.desktop"];
diff --git a/home/isabel/themes/global.nix b/home/isabel/themes/global.nix
index 6a73a8329..8e974afa0 100644
--- a/home/isabel/themes/global.nix
+++ b/home/isabel/themes/global.nix
@@ -1,14 +1,12 @@
{osConfig, ...}: let
cfg = osConfig.modules.style;
in {
- # cursor theme
- home = {
- pointerCursor = {
- package = cfg.pointerCursor.package;
- name = "${cfg.pointerCursor.name}";
- size = cfg.pointerCursor.size;
- gtk.enable = true;
- x11.enable = true;
- };
+ # pointer / cursor theming
+ home.pointerCursor = {
+ package = cfg.pointerCursor.package;
+ name = "${cfg.pointerCursor.name}";
+ size = cfg.pointerCursor.size;
+ gtk.enable = true;
+ x11.enable = true;
};
}
diff --git a/home/isabel/themes/gtk.nix b/home/isabel/themes/gtk.nix
index 85d69bd9d..d7e995a20 100644
--- a/home/isabel/themes/gtk.nix
+++ b/home/isabel/themes/gtk.nix
@@ -12,7 +12,7 @@
acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && (sys.video.enable)) {
+ config = mkIf (builtins.elem device.type acceptedTypes && sys.video.enable) {
xdg.systemDirs.data = let
schema = pkgs.gsettings-desktop-schemas;
in ["${schema}/share/gsettings-schemas/${schema.name}"];
@@ -28,7 +28,7 @@ in {
# set GTK theme to the name specified by the gtk package
GTK_THEME = "${cfg.gtk.theme.name}";
- # gtk applications should use filepickers specified by xdg
+ # gtk applications should use xdg specified settings
GTK_USE_PORTAL = "${with lib; toString (boolToNum cfg.gtk.usePortal)}";
};
};
diff --git a/home/isabel/themes/qt.nix b/home/isabel/themes/qt.nix
index 19d52b403..7a57e12db 100644
--- a/home/isabel/themes/qt.nix
+++ b/home/isabel/themes/qt.nix
@@ -4,7 +4,7 @@
osConfig,
...
}: let
- inherit (lib) mkIf optionalAttrs;
+ inherit (lib) mkIf optionals;
inherit (osConfig.modules) device;
sys = osConfig.modules.system;
cfg = osConfig.modules.style;
@@ -12,64 +12,63 @@
acceptedTypes = ["laptop" "desktop" "hybrid" "lite"];
in {
config = mkIf (builtins.elem device.type acceptedTypes && sys.video.enable) {
- xdg.configFile."kdeglobals".source = cfg.qt.kdeglobals.source;
+ xdg.configFile = {
+ "kdeglobals".source = cfg.qt.kdeglobals.source;
+
+ "Kvantum/kvantum.kvconfig".source = (pkgs.formats.ini {}).generate "kvantum.kvconfig" {
+ General.theme = "catppuccin";
+ Applications.catppuccin = ''
+ qt5ct, org.kde.dolphin, org.kde.kalendar, org.qbittorrent.qBittorrent, hyprland-share-picker, dolphin-emu, Nextcloud, nextcloud, cantata, org.kde.kid3-qt
+ '';
+ };
+ "Kvantum/catppuccin/catppuccin.kvconfig".source = builtins.fetchurl {
+ url = "https://raw.githubusercontent.com/catppuccin/Kvantum/main/src/Catppuccin-Mocha-Sapphire/Catppuccin-Mocha-Sapphire.kvconfig";
+ sha256 = "0n9f5hysr4k1sf9fd3sgd9fvqwrxrpcvj6vajqmb5c5ji8nv2w3c";
+ };
+
+ "Kvantum/catppuccin/catppuccin.svg".source = builtins.fetchurl {
+ url = "https://raw.githubusercontent.com/catppuccin/Kvantum/main/src/Catppuccin-Mocha-Sapphire/Catppuccin-Mocha-Sapphire.svg";
+ sha256 = "1hq9h34178h0d288hgwb0ngqnixz24m9lk0ahc4dahwqn77fndwf";
+ };
+ };
qt = {
enable = true;
- platformTheme = mkIf cfg.forceGtk "gtk"; # just an override for QT_QPA_PLATFORMTHEME, takes "gtk" or "gnome"
- style = {
+ platformTheme = mkIf cfg.forceGtk "gtk"; # just an override for QT_QPA_PLATFORMTHEME, takes “gtk”, “gnome”, “qtct” or “kde”
+ style = mkIf (!cfg.forceGtk) {
name = "${cfg.qt.theme.name}";
- package = cfg.qt.theme.package;
+ inherit (cfg.qt.theme) package;
};
};
- # credits: yavko
- # catppuccin theme for qt-apps
- home.packages = with pkgs; [
- qt5.qttools
- qt6Packages.qtstyleplugin-kvantum
- libsForQt5.qtstyleplugin-kvantum
- libsForQt5.qt5ct
- breeze-icons
-
- # add theme package to path just in case
- cfg.qt.theme.package
- ];
+ home.packages = with pkgs;
+ [
+ libsForQt5.qt5ct
+ breeze-icons
- home.sessionVariables =
- {
- #QT_QPA_PLATFORMTHEME = "kvantum"; # can't be used alongside kvantum, nix above knows why
- #QT_STYLE_OVERRIDE = "kvantum";
- QT_AUTO_SCREEN_SCALE_FACTOR = "1";
- QT_QPA_PLATFORM = "wayland;xcb";
- QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
- DISABLE_QT5_COMPAT = "0";
+ # add theme package to path just in case
+ cfg.qt.theme.package
+ ]
+ ++ optionals cfg.useKvantum [
+ qt6Packages.qtstyleplugin-kvantum
+ libsForQt5.qtstyleplugin-kvantum
+ ];
- # tell calibre to use the dark theme, because the light one hurts my eyes
- CALIBRE_USE_DARK_PALETTE = "1";
- }
- // optionalAttrs cfg.useKvantum {
- xdg.configFile."Kvantum/catppuccin/catppuccin.kvconfig".source = builtins.fetchurl {
- url = "https://raw.githubusercontent.com/catppuccin/Kvantum/main/src/Catppuccin-Mocha-Blue/Catppuccin-Mocha-Blue.kvconfig";
- sha256 = "";
- };
+ home.sessionVariables = {
+ # scaling - 1 means no scaling
+ QT_AUTO_SCREEN_SCALE_FACTOR = "1";
- xdg.configFile."Kvantum/catppuccin/catppuccin.svg".source = builtins.fetchurl {
- url = "https://raw.githubusercontent.com/catppuccin/Kvantum/main/src/Catppuccin-Mocha-Blue/Catppuccin-Mocha-Blue.svg";
- sha256 = "";
- };
+ # use wayland as the default backend, fallback to xcb if wayland is not available
+ QT_QPA_PLATFORM = "wayland;xcb";
- xdg.configFile."Kvantum/kvantum.kvconfig".source = (pkgs.formats.ini {}).generate "kvantum.kvconfig" {
- General.Theme = "Catppuccin-Mocha-Mauve";
- };
+ # disable window decorations everywhere
+ QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
- xdg.configFile."Kvantum/kvantum.kvconfig".text = ''
- [General]
- theme=catppuccin
+ # remain backwards compatible with qt5
+ DISABLE_QT5_COMPAT = "0";
- [Applications]
- catppuccin=qt5ct, org.kde.dolphin, org.kde.kalendar, org.qbittorrent.qBittorrent, hyprland-share-picker, dolphin-emu, Nextcloud, nextcloud
- '';
- };
+ # tell calibre to use the dark theme
+ CALIBRE_USE_DARK_PALETTE = "1";
+ };
};
}
diff --git a/hosts/amatarasu/default.nix b/hosts/amatarasu/default.nix
index c7c65e705..43826e00a 100644
--- a/hosts/amatarasu/default.nix
+++ b/hosts/amatarasu/default.nix
@@ -21,11 +21,11 @@ in {
};
system = {
mainUser = "isabel";
-
hostname = "amatarasu";
boot = {
loader = "systemd-boot";
+ secureBoot = false;
plymouth = {
enable = true;
withThemes = true;
@@ -35,11 +35,16 @@ in {
loadRecommendedModules = true;
};
+ fs = ["ext4" "vfat"];
video.enable = true;
sound.enable = true;
bluetooth.enable = false;
printing.enable = false;
+ security = {
+ auditd.enable = true;
+ };
+
networking = {
optimizeTcp = true;
};
@@ -57,32 +62,33 @@ in {
desktop = "Hyprland";
useHomeManager = true;
};
- services = {
- smb = {
- enable = true;
- recive = {
- media = true;
- general = true;
- };
- };
- photoprism.enable = true;
- vscode-server.enable = true;
- };
+
programs = {
git.signingKey = "7F2F6BD6997FCDF7";
- cli.enable = true;
+ cli = {
+ enable = true;
+ modernShell.enable = true;
+ };
+ tui.enable = true;
gui.enable = true;
- default = {
+ zathura.enable = true;
+
+ defaults = {
bar = "ags";
};
+ };
- nur = {
- enable = true;
- bella = true;
- nekowinston = true;
+ services = {
+ smb = {
+ enable = false;
+ recive = {
+ media = false;
+ general = false;
+ };
};
+ vscode-server.enable = true;
};
};
diff --git a/hosts/amatarasu/hardware-configuration.nix b/hosts/amatarasu/hardware-configuration.nix
index 4e8613ff6..8a56d3107 100644
--- a/hosts/amatarasu/hardware-configuration.nix
+++ b/hosts/amatarasu/hardware-configuration.nix
@@ -1,6 +1,3 @@
-# Do not modify this file! It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations. Please make changes
-# to /etc/nixos/configuration.nix instead.
{
config,
lib,
diff --git a/hosts/bernie/default.nix b/hosts/bernie/default.nix
index dbd0539ed..39a5c56c0 100644
--- a/hosts/bernie/default.nix
+++ b/hosts/bernie/default.nix
@@ -1,93 +1,63 @@
-{
- lib,
- config,
- ...
-}: {
- imports = [./hardware-configuration.nix];
- config = {
- modules = {
- device = {
- type = "server";
- cpu = null;
- gpu = null;
- hasTPM = false;
- hasBluetooth = false;
- hasSound = false;
+_: {
+ imports = [
+ ./hardware-configuration.nix
+ ./mount.nix
+ ./overrides.nix
+ ./services.nix
+ ];
+
+ config.modules = {
+ device = {
+ type = "server";
+ cpu = "amd";
+ gpu = null;
+ hasTPM = false;
+ hasBluetooth = false;
+ hasSound = false;
+ };
+ system = {
+ mainUser = "isabel";
+ hostname = "bernie";
+
+ boot = {
+ loader = "grub";
+ enableKernelTweaks = true;
+ enableInitrdTweaks = true;
+ loadRecommendedModules = true;
};
- system = {
- mainUser = "isabel";
-
- hostname = "bernie";
-
- boot = {
- loader = "grub";
- device = lib.mkForce "/dev/sda15";
- enableKernelTweaks = true;
- enableInitrdTweaks = true;
- loadRecommendedModules = true;
- };
- video.enable = false;
- sound.enable = false;
- bluetooth.enable = false;
- printing.enable = false;
+ fs = ["vfat" "exfat" "ext4"];
+ video.enable = false;
+ sound.enable = false;
+ bluetooth.enable = false;
+ printing.enable = false;
- networking = {
- optimizeTcp = false;
- };
-
- virtualization = {
- enable = true;
- docker.enable = true;
- qemu.enable = false;
- podman.enable = false;
- distrobox.enable = false;
- };
- };
- usrEnv = {
- isWayland = false;
- useHomeManager = true;
+ networking = {
+ optimizeTcp = false;
};
- services = {
- smb = {
- enable = true;
- };
- vscode-server.enable = true;
- mailserver.enable = true;
- gitea.enable = true;
- vaultwarden.enable = true;
- };
- programs = {
- git.signingKey = "";
-
- cli.enable = true;
- gui.enable = false;
- nur = {
- enable = true;
- bella = true;
- nekowinston = true;
- };
+ virtualization = {
+ enable = true;
+ docker.enable = false;
+ qemu.enable = false;
+ podman.enable = false;
+ distrobox.enable = false;
};
};
+ usrEnv = {
+ isWayland = false;
+ useHomeManager = true;
+ };
- zramSwap.enable = true;
- services.openssh.enable = true;
- users.users.root.openssh.authorizedKeys.keys = [
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQhSDXRDS5ABDyCPOZ2B3bl455Mlzb32vmofdkXJCNXW98jUeCyaZk8XHRta06KeADFMvpwDEzjGz6Zb+NJIfMkh20mVdOpTHrA80cER1F2SlNf9fmZIgOyCzSUOSGqXHsWppikHmKzv1hPifQYoqWdRXN7bD9Jk5JjgxGcaXkICcV93s/tRy5Yl5l5LhM00fUDXUF85xnmqU3Ujepx0gknE0qaqgT+kFRe0hy7HIkjrEjMqy5nfHFlJG/XAxrHKK9p/BvvCgO/xiRimK2UgfH/5jml20EytVeZ6fIAeyVLvWA/FtLyaafoLqmETV6BhUnk8PtdAxjGQTQXZmUOv2D0Lvmxo1GqjYVPOfhINBprUaRwxIFM57SpwmXmGVWOlyTgTtBoPewUQ/QwT5cVV+a8ASeEhrFB4TzHxK4RM8++zL0eVtESW+L+/rsmfUHIIEXnLvVmnb8t0AWpWxQWaEe7YaNS9VNtm6gK0wl12PZXqN5K4eCXIyrsCbUdaldnts= root"
- ];
+ programs = {
+ git.signingKey = "B4D9D513B1560D99";
- boot = {
- growPartition = !config.boot.initrd.systemd.enable;
- kernelParams = ["net.ifnames=0"];
- kernel = {
- sysctl = {
- "net.ipv4.ip_forward" = true;
- "net.ipv6.conf.all.forwarding" = true;
- };
+ cli = {
+ enable = true;
+ modernShell.enable = true;
};
+ tui.enable = true;
+ gui.enable = false;
};
-
- nix.settings.system-features = ["nixos-test" "benchmark" "big-parallel" "kvm" "gccarch-armv8-a"];
};
}
diff --git a/hosts/bernie/hardware-configuration.nix b/hosts/bernie/hardware-configuration.nix
index 005bed96a..3dc12bddc 100644
--- a/hosts/bernie/hardware-configuration.nix
+++ b/hosts/bernie/hardware-configuration.nix
@@ -1,34 +1,25 @@
{
lib,
+ config,
modulesPath,
...
}: {
imports = [(modulesPath + "/profiles/qemu-guest.nix")];
-
- boot.initrd.availableKernelModules = ["xhci_pci" "virtio_pci" "virtio_scsi" "usbhid"];
- boot.initrd.kernelModules = [];
- boot.kernelModules = [];
- boot.extraModulePackages = [];
-
+ boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi"];
+ boot.initrd.kernelModules = ["nvme"];
+ boot.kernelModules = ["kvm-amd"];
fileSystems."/" = {
- device = "/dev/disk/by-uuid/de867c31-4437-4638-89f2-a345197bcb18";
+ device = "/dev/sda1";
fsType = "ext4";
};
- fileSystems."/boot" = {
- device = "/dev/disk/by-uuid/AF75-5E6E";
- fsType = "vfat";
- };
-
- swapDevices = [];
-
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces..useDHCP`.
networking.useDHCP = lib.mkDefault true;
- # networking.interfaces.enp0s6.useDHCP = lib.mkDefault true;
+ # networking.interfaces.ens3.useDHCP = lib.mkDefault true;
- nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
- powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+ hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
diff --git a/hosts/bernie/mount.nix b/hosts/bernie/mount.nix
new file mode 100644
index 000000000..7d0139e55
--- /dev/null
+++ b/hosts/bernie/mount.nix
@@ -0,0 +1,6 @@
+_: {
+ fileSystems."/srv/storage" = {
+ device = "/dev/disk/by-id/scsi-0HC_Volume_37980392";
+ fsType = "ext4";
+ };
+}
diff --git a/hosts/bernie/overrides.nix b/hosts/bernie/overrides.nix
new file mode 100644
index 000000000..1bd2f64dd
--- /dev/null
+++ b/hosts/bernie/overrides.nix
@@ -0,0 +1,31 @@
+{
+ lib,
+ config,
+ ...
+}: {
+ config = {
+ services.smartd.enable = lib.mkForce false; # Unavailable - device lacks SMART capability.
+
+ boot = {
+ growPartition = !config.boot.initrd.systemd.enable;
+ kernelParams = ["net.ifnames=0"];
+ kernel = {
+ sysctl = {
+ "net.ipv4.ip_forward" = true;
+ "net.ipv6.conf.all.forwarding" = true;
+ };
+ };
+
+ loader.grub = {
+ enable = true;
+ useOSProber = lib.mkForce false;
+ efiSupport = lib.mkForce false;
+ enableCryptodisk = false;
+ theme = null;
+ backgroundColor = null;
+ splashImage = null;
+ device = lib.mkForce "/dev/sda";
+ };
+ };
+ };
+}
diff --git a/hosts/bernie/services.nix b/hosts/bernie/services.nix
new file mode 100644
index 000000000..a868a6c97
--- /dev/null
+++ b/hosts/bernie/services.nix
@@ -0,0 +1,30 @@
+_: {
+ modules.services = {
+ nextcloud.enable = true;
+ vscode-server.enable = false;
+ miniflux.enable = false;
+ matrix.enable = true;
+ forgejo.enable = true;
+ vaultwarden.enable = true;
+ isabelroses-web.enable = true;
+ nginx.enable = true;
+ cloudflared.enable = false;
+
+ mailserver = {
+ enable = true;
+ rspamd-web.enable = false;
+ };
+
+ monitoring = {
+ grafana.enable = true;
+ prometheus.enable = true;
+ };
+
+ database = {
+ mysql.enable = false;
+ mongodb.enable = false;
+ postgresql.enable = true;
+ redis.enable = true;
+ };
+ };
+}
diff --git a/hosts/beta/default.nix b/hosts/beta/default.nix
index e95cc4918..72778b2ee 100644
--- a/hosts/beta/default.nix
+++ b/hosts/beta/default.nix
@@ -1,8 +1,4 @@
-{
- lib,
- config,
- ...
-}: {
+{config, ...}: {
imports = [./hardware-configuration.nix];
config = {
modules = {
@@ -16,7 +12,6 @@
};
system = {
mainUser = "isabel";
-
hostname = "beta";
boot = {
@@ -47,24 +42,20 @@
isWayland = false;
useHomeManager = true;
};
- services = {
- smb = {
- enable = true;
- };
- vscode-server.enable = true;
- mailserver.enable = true;
- };
+
programs = {
git.signingKey = "";
cli.enable = true;
gui.enable = false;
+ };
- nur = {
+ services = {
+ smb = {
enable = true;
- bella = true;
- nekowinston = true;
};
+ vscode-server.enable = true;
+ mailserver.enable = true;
};
};
diff --git a/hosts/default.nix b/hosts/default.nix
index 8cdaed8fa..f39893929 100644
--- a/hosts/default.nix
+++ b/hosts/default.nix
@@ -7,73 +7,82 @@
inherit (self) inputs;
inherit (lib) concatLists mkNixosSystem mkNixosIso;
- modulePath = ../modules;
+ # home manager modules from inputs
+ hm = inputs.home-manager.nixosModules.home-manager;
+ cat = inputs.catppuccin.nixosModules.catppuccin;
- # common modules, to be shared across all systems
- commonModules = modulePath + /common; # the path where common modules reside
- core = commonModules + /core; # the self-proclaimed sane defaults for all my systems
- options = commonModules + /options; # the module that provides the options for my system configuration
- secrets = commonModules + /secrets;
+ # modules
+ modulePath = ../modules; # the base module path
+ options = modulePath + /options; # the module options for quick configuration
- # system types, split up per system
- deviceType = commonModules + /types; # the path where device type modules reside
- server = deviceType + /server; # for devices that are of the server type - provides online services
- laptop = deviceType + /laptop; # for devices that are of the laptop type - provides power optimizations
- workstation = deviceType + /workstation; # for devices that are of workstation type - any device that is for daily use
- hybrid = [server laptop];
+ # common modules, these are shared across all systems
+ commonModules = modulePath + /common; # the base directory for the common module
+ core = commonModules + /core; # defaults for all systems
+ secrets = commonModules + /secrets; # shhh
- # extra modules, likely optional but possibly critical
- extraModules = modulePath + /extra; # the path where extra modules reside
- sharedModules = extraModules + /shared; # shared modules
+ # hardware types, providing improved defaults and system preformance improvements
+ deviceType = commonModules + /types; # the base directory for the types module
+ server = deviceType + /server; # for server type configurations
+ laptop = deviceType + /laptop; # for laptop type configurations
+ desktop = deviceType + /desktop; # for desktop type configurations
+ workstation = deviceType + /workstation; # for server type configurations
+ #hybrid = [server laptop]; # combine the server and laptop configurations for the best of both worlds
- ## home-manager ##
- home = ../home; # home-manager configurations for hosts that need home-manager
- homes = [hm home]; # combine hm flake input and the home module to be imported together
+ # extra modules
+ extraModules = modulePath + /extra; # the base directory for the extra module
+ sharedModules = extraModules + /shared; # the base directory for the shared module
- ## flake inputs ##
- hm = inputs.home-manager.nixosModules.home-manager; # home-manager nixos module
- cat = inputs.catppuccin.nixosModules.catppuccin;
+ ## home-manager
+ home = ../home; # home-manager configurations, used if hm is enabled
+ homes = [hm home]; # combine hm input module and the home module, confiuration modules
- # a list of shared modules that ALL systems need
+ # a list of shared modules
shared = [
- core # the "sane" default shared across systems
- options
- sharedModules
- cat # for the quick themeing
- secrets
+ core # default shared across all system configuratons
+ options # amazing quick settings module
+ sharedModules # sharing is careing, this mainly contains: hm and nixos (if any) modules
+ cat # catppucin for the quick themeing
+ secrets # shh
];
- # extraSpecialArgs that all hosts need
+ # extraSpecialArgs that are on all machines
sharedArgs = {inherit inputs self lib;};
in {
- # fuck nvidia - Linus "the linux" Torvalds
- amatarasu = mkNixosSystem {
+ hydra = mkNixosSystem {
inherit withSystem;
system = "x86_64-linux";
modules =
[
- ./amatarasu
+ ./hydra
workstation
+ laptop
]
- ++ concatLists [shared homes];
+ ++ concatLists [
+ shared
+ homes
+ /*
+ hybrid
+ */
+ ];
specialArgs = sharedArgs;
};
- hydra = mkNixosSystem {
+ amatarasu = mkNixosSystem {
inherit withSystem;
system = "x86_64-linux";
modules =
[
- ./hydra
+ ./amatarasu
+ desktop
workstation
]
- ++ concatLists [shared homes hybrid];
+ ++ concatLists [shared homes];
specialArgs = sharedArgs;
};
bernie = mkNixosSystem {
inherit withSystem;
- system = "aarch64-linux";
+ system = "x86_64-linux";
modules =
[
./bernie
@@ -83,6 +92,19 @@ in {
specialArgs = sharedArgs;
};
+ /*
+ beta = mkNixosSystem {
+ inherit withSystem;
+ system = "x86_64-linux";
+ modules = [
+ ./beta
+ server
+ ]
+ ++ concatLists [shared homes];
+ specialArgs = sharedArgs;
+ };
+ */
+
lilith = mkNixosIso {
system = "x86_64-linux";
modules = [
diff --git a/hosts/hydra/default.nix b/hosts/hydra/default.nix
index 8c96ef903..563b5a106 100644
--- a/hosts/hydra/default.nix
+++ b/hosts/hydra/default.nix
@@ -1,33 +1,39 @@
-{config, ...}: {
+_: {
imports = [./hardware-configuration.nix];
config = {
modules = {
device = {
- type = "hybrid";
+ type = "laptop";
cpu = "intel";
gpu = null;
- hasTPM = true;
monitors = ["eDP-1"];
+ hasTPM = true;
hasBluetooth = true;
hasSound = true;
};
system = {
mainUser = "isabel";
-
hostname = "hydra";
boot = {
loader = "systemd-boot";
+ secureBoot = false;
enableKernelTweaks = true;
enableInitrdTweaks = true;
loadRecommendedModules = true;
};
+ fs = ["ext4" "vfat"];
video.enable = true;
sound.enable = true;
bluetooth.enable = true;
printing.enable = false;
+ security = {
+ fixWebcam = false;
+ auditd.enable = true;
+ };
+
networking = {
optimizeTcp = true;
};
@@ -45,40 +51,35 @@
desktop = "Hyprland";
useHomeManager = true;
};
- services = {
- smb = {
- enable = true;
- recive = {
- media = true;
- general = true;
- };
- };
- vscode-server.enable = true;
- cloudflare = {
- enable = true;
- id = "32f941a8-e557-4d8a-bafd-52a7d65a5daf";
- };
- jellyfin = {
- enable = true;
- asDockerContainer = false;
- };
- };
+
programs = {
git.signingKey = "CFF897835DD77813";
- cli.enable = true;
+ cli = {
+ enable = true;
+ modernShell.enable = true;
+ };
tui.enable = true;
gui.enable = true;
- default = {
+ zathura.enable = true;
+
+ defaults = {
bar = "ags";
};
+ };
- nur = {
- enable = true;
- bella = true;
- nekowinston = true;
+ services = {
+ smb = {
+ enable = false;
+ recive = {
+ media = false;
+ general = false;
+ };
};
+ vscode-server.enable = true;
+ cloudflared.enable = false;
+ jellyfin.enable = false;
};
};
diff --git a/hosts/lilith/boot.nix b/hosts/lilith/boot.nix
new file mode 100644
index 000000000..bd8c57573
--- /dev/null
+++ b/hosts/lilith/boot.nix
@@ -0,0 +1,25 @@
+{
+ pkgs,
+ lib,
+ ...
+}: {
+ boot = {
+ kernelParams = lib.mkAfter ["noquiet"];
+ # we have no need for systemd in initrd installation media
+ initrd.systemd = {
+ enable = lib.mkImageMediaOverride false;
+ emergencyAccess = lib.mkImageMediaOverride true;
+ };
+ kernelPackages = pkgs.linuxPackages_latest;
+
+ # https://github.com/NixOS/nixpkgs/issues/58959
+ supportedFilesystems = lib.mkForce [
+ "btrfs"
+ "vfat"
+ "f2fs"
+ "xfs"
+ "ntfs"
+ "cifs"
+ ];
+ };
+}
diff --git a/hosts/lilith/default.nix b/hosts/lilith/default.nix
index a2aa27710..e70a74785 100644
--- a/hosts/lilith/default.nix
+++ b/hosts/lilith/default.nix
@@ -2,32 +2,89 @@
config,
lib,
pkgs,
+ modulesPath,
...
-}: {
- # Secure defaults
- nixpkgs.config = {allowBroken = true;}; # false breaks zfs kernel
- # Always copytoram so that, if the image is booted from, e.g., a
- # USB stick, nothing is mistakenly written to persistent storage.
- boot.kernelParams = ["copytoram"];
- boot.tmp.cleanOnBoot = true;
- boot.kernel.sysctl = {"kernel.unprivileged_bpf_disabled" = 1;};
-
- # make sure we are air-gapped
- networking.wireless.enable = true;
- networking.dhcpcd.enable = true;
-
- services.getty.helpLine = "The 'root' account has an empty password.";
-
- services.openssh.enable = true;
- users.users.root.openssh.authorizedKeys.keys = [
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZmzCZrKIdTSUf1GFWB9bF2nDRfjdWI4+jfcZbsscsSdNHBBaYnDjQftj8lVUMmSzjKasIeU3yKmuai6t2GBnIfxZq+5L/uvIZhYfgJwcjhLkXZL2CCG1UtxFV6Gwe2RJWA7VrGzhfU+Kjx6O7oCKlwy0M6cknUU+G17rqoGlOwDtMiDR+as6UoxeEf//xIdvBdEb3A+JGo4WVx1+/8XedKM5ngyY0zH6vKb12kudVMjJsqQ4cES8JozuL4LMEExsPRALPVGYQ69ulMLl4zkbbP2Ne5UO9Uf/BsBF2DJU3uWVIG6nAUIeNr4NXaa7h4/cnlpP+f4H/7MvOeif85TYU2WK+yiy11z7N6wxbB1/Mtq2sMldMq3Csb7A0GkeF1qXazG0yp4Oa0sene0JfPI3AsYSFOHuByVRkb6kI3f+d/xogwoLJ645olZLcobsqWoS4TQZHj44CTRseXzCQiUGBKV9Bb/7hqY7TbcwRd7cEW91lbXIzO6PUDhi1E59VqYE= isabel"
+}:
+with lib; {
+ imports = [
+ "${modulesPath}/profiles/minimal.nix"
+ "${modulesPath}/installer/cd-dvd/installation-cd-base.nix"
+
+ ./boot.nix
+ ./iso.nix
+ ./networking.nix
+ ./nix.nix
+ ];
+
+ # FIXME: for some reason, we cannot boot off ventoy
+ # and have to burn the iso to an entire USB with dd
+ # dd if=result/iso/*.iso of=/dev/sdX status=progress
+
+ users.extraUsers.root.password = "";
+
+ console = let
+ variant = "u24n";
+ in {
+ # hidpi terminal font
+ font = "${pkgs.terminus_font}/share/consolefonts/ter-${variant}.psf.gz";
+ keyMap = "en";
+ };
+
+ # fix: "too many open files"
+ security.pam.loginLimits = [
+ {
+ domain = "*";
+ item = "nofile";
+ type = "-";
+ value = "65536";
+ }
];
- isoImage.isoBaseName = lib.mkForce config.networking.hostName;
- boot.kernelPackages = pkgs.linuxPackages_latest;
+ services.getty.helpLine =
+ ''
+ The "nixos" and "root" accounts have empty passwords.
+ An ssh daemon is running. You then must set a password
+ for either "root" or "nixos" with `passwd` or add an ssh key
+ to /home/nixos/.ssh/authorized_keys be able to login.
+ If you need a wireless connection, you may use networkmanager
+ by invoking `nmcli` or `nmtui`, the ncurses interface.
+ ''
+ + optionalString config.services.xserver.enable ''
+ Type `sudo systemctl start display-manager' to
+ start the graphical user interface.
+ '';
+
+ # Use environment options, minimal profile, to save space
+ environment = {
+ noXlibs = mkDefault true;
+
+ # no packages other, other then the ones i provide
+ defaultPackages = [];
+
+ # needed packages for the installer
+ systemPackages = with pkgs; [
+ nixos-install-tools
+ gitMinimal
+ neovim
+ netcat
+ ];
+
+ # fix annoying warning
+ etc."mdadm.conf".text = ''
+ MAILADDR root
+ '';
+ };
+
+ # disable documentation to save space
+ documentation = {
+ enable = mkDefault false;
+ doc.enable = mkDefault false;
+ info.enable = mkDefault false;
+ };
- services.gvfs.enable = true;
+ # disable fontConfig to save space, not like we have a GUI anyways
+ fonts.fontconfig.enable = lib.mkForce false;
- services.autorandr.enable = true;
- programs.nm-applet.enable = true;
+ # disable sound related programs, saving more space
+ sound.enable = false;
}
diff --git a/hosts/lilith/iso.nix b/hosts/lilith/iso.nix
new file mode 100644
index 000000000..15295364a
--- /dev/null
+++ b/hosts/lilith/iso.nix
@@ -0,0 +1,21 @@
+{
+ self,
+ config,
+ lib,
+ pkgs,
+ ...
+}: {
+ networking.hostName = lib.mkImageMediaOverride "lilith";
+
+ isoImage = let
+ rev = self.shortRev or "dirty";
+ in {
+ # lilith-$rev-$arch.iso
+ isoName = lib.mkImageMediaOverride "lilith-${config.system.nixos.release}-${rev}-${pkgs.stdenv.hostPlatform.uname.processor}.iso";
+ # lilith-$release-$rev-$arch
+ volumeID = "lilith-${config.system.nixos.release}-${rev}-${pkgs.stdenv.hostPlatform.uname.processor}";
+
+ # faster compression in exchange for larger iso size
+ squashfsCompression = "gzip -Xcompression-level 1";
+ };
+}
diff --git a/hosts/lilith/networking.nix b/hosts/lilith/networking.nix
new file mode 100644
index 000000000..772a52e0a
--- /dev/null
+++ b/hosts/lilith/networking.nix
@@ -0,0 +1,14 @@
+{
+ pkgs,
+ lib,
+ ...
+}: {
+ # use networkmanager in the live environment
+ networking.networkmanager.enable = lib.mkForce true;
+ networking.wireless.enable = lib.mkForce false;
+
+ systemd.services.sshd.wantedBy = pkgs.lib.mkForce ["multi-user.target"];
+ users.users.root.openssh.authorizedKeys.keys = [
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZmzCZrKIdTSUf1GFWB9bF2nDRfjdWI4+jfcZbsscsSdNHBBaYnDjQftj8lVUMmSzjKasIeU3yKmuai6t2GBnIfxZq+5L/uvIZhYfgJwcjhLkXZL2CCG1UtxFV6Gwe2RJWA7VrGzhfU+Kjx6O7oCKlwy0M6cknUU+G17rqoGlOwDtMiDR+as6UoxeEf//xIdvBdEb3A+JGo4WVx1+/8XedKM5ngyY0zH6vKb12kudVMjJsqQ4cES8JozuL4LMEExsPRALPVGYQ69ulMLl4zkbbP2Ne5UO9Uf/BsBF2DJU3uWVIG6nAUIeNr4NXaa7h4/cnlpP+f4H/7MvOeif85TYU2WK+yiy11z7N6wxbB1/Mtq2sMldMq3Csb7A0GkeF1qXazG0yp4Oa0sene0JfPI3AsYSFOHuByVRkb6kI3f+d/xogwoLJ645olZLcobsqWoS4TQZHj44CTRseXzCQiUGBKV9Bb/7hqY7TbcwRd7cEW91lbXIzO6PUDhi1E59VqYE= isabel"
+ ];
+}
diff --git a/hosts/lilith/nix.nix b/hosts/lilith/nix.nix
new file mode 100644
index 000000000..bd1ebb2f0
--- /dev/null
+++ b/hosts/lilith/nix.nix
@@ -0,0 +1,13 @@
+_: {
+ nix = {
+ settings = {
+ experimental-features = ["nix-command" "flakes" "repl-flake"];
+ log-lines = 30;
+ extra-experimental-features = ["ca-derivations"];
+ warn-dirty = false;
+ http-connections = 50;
+ accept-flake-config = true;
+ auto-optimise-store = true;
+ };
+ };
+}
diff --git a/lib/builders.nix b/lib/builders.nix
index 72e324fac..22cbc7ec8 100644
--- a/lib/builders.nix
+++ b/lib/builders.nix
@@ -3,16 +3,14 @@
inputs,
...
}: let
- # inherit self from inputs
inherit (inputs) self;
- # just an alias to nixpkgs.lib.nixosSystem, lets me avoid adding
- # nixpkgs to the scope in the file it is used in
+ # just an alias to nixpkgs.lib.nixosSystem
mkSystem = lib.nixosSystem;
- # mkNixosSystem wraps mkSystem (a.k.a lib.nixosSystem) with flake-parts' withSystem to provide inputs' and self' from flake-parts
- # it also acts as a template for my nixos hosts with system type and modules being imported beforehand
- # specialArgs is also defined here to avoid defining them for each host and lazily merged if the host defines any other args
+ # mkNixosSystem wraps mkSystem (or lib.nixosSystem) with flake-parts' withSystem to give us inputs' and self' from flake-parts
+ # which can also be used as a template for nixos hosts with system type and modules to be imported with ease
+ # specialArgs is also defined here to avoid defining them for each host
mkNixosSystem = {
modules,
system,
@@ -29,9 +27,8 @@
specialArgs = {inherit lib inputs self inputs' self';} // args.specialArgs or {};
});
- # mkIso is should be a set that extends mkSystem with necessary modules
- # to create an Iso image
- # we do not use mkNixosSystem because it overcomplicates things, an ISO does not require what we get in return for those complications
+ # mkIso is should be a set that extends mkSystem (again) with necessary modules to create an Iso image
+ # don't use mkNixosSystem as it is complelty overkill for an iso and will have too much data, we need a light weight image
mkNixosIso = {
modules,
system,
diff --git a/lib/hardware.nix b/lib/hardware.nix
new file mode 100644
index 000000000..315d1a3df
--- /dev/null
+++ b/lib/hardware.nix
@@ -0,0 +1,12 @@
+_: let
+ # check if the host platform is linux and x86
+ # (isx86Linux pkgs) -> true
+ isx86Linux = pkgs: with pkgs.stdenv; hostPlatform.isLinux && hostPlatform.isx86;
+
+ # assume the first monitor in the list of monitors is primary
+ # get its name from the list of monitors
+ # `primaryMonitor osConfig` -> "DP-1"
+ primaryMonitor = config: builtins.elemAt config.modules.device.monitors 0;
+in {
+ inherit isx86Linux primaryMonitor;
+}
diff --git a/lib/helpers.nix b/lib/helpers.nix
index f6ac0360a..db69c0db2 100644
--- a/lib/helpers.nix
+++ b/lib/helpers.nix
@@ -1,9 +1,7 @@
{lib, ...}: let
inherit (lib) lists mapAttrsToList filterAttrs hasSuffix;
- primaryMonitor = config: builtins.elemAt config.modules.device.monitors 0;
-
- # filter files that have the .nix suffix
+ # filter files for the .nix suffix
filterNixFiles = k: v: v == "regular" && hasSuffix ".nix" k;
# import files that are selected by filterNixFiles
@@ -12,7 +10,7 @@
(filterAttrs filterNixFiles (builtins.readDir path))))
import;
- # return an int (1/0) based on boolean value
+ # return an int based on boolean value
boolToNum = bool:
if bool
then 1
@@ -21,15 +19,26 @@
# a basic function to fetch a specified user's public keys from github .keys url
fetchKeys = username: (builtins.fetchurl "https://github.com/${username}.keys");
- # a helper function that checks if a list contains a list of given strings
+ indexOf = list: elem: let
+ f = f: i:
+ if i == (builtins.length list)
+ then null
+ else if (builtins.elemAt list i) == elem
+ then i
+ else f f (i + 1);
+ in
+ f f 0;
+
+ # a function to go from normal text to lower snake case
+ # "A Normal String" -> "a-normal-string"
+ serializeTheme = inputString: lib.strings.toLower (builtins.replaceStrings [" "] ["-"] inputString);
+
+ # a function that checks if a list contains a list of given strings
containsStrings = {
list,
targetStrings,
}:
builtins.all (s: builtins.any (x: x == s) list) targetStrings;
-
- # replace whitespaces with hyphens
- serializeTheme = inputString: lib.strings.toLower (builtins.replaceStrings [" "] ["-"] inputString);
in {
- inherit primaryMonitor filterNixFiles importNixFiles boolToNum fetchKeys containsStrings serializeTheme;
+ inherit filterNixFiles importNixFiles boolToNum fetchKeys containsStrings serializeTheme indexOf;
}
diff --git a/lib/validators.nix b/lib/validators.nix
index 75ff379fe..5b3570cd3 100644
--- a/lib/validators.nix
+++ b/lib/validators.nix
@@ -4,6 +4,23 @@
# a function that returns a boolean based on whether or not the groups exist
ifGroupsExist = config: groups: lib.any (group: builtins.hasAttr group config.users.groups) groups;
+
+ # convenience function check if the declared device type is of an accepted type
+ # takes config and a list of accepted device types
+ # `isAcceptedDevice osConfig ["foo" "bar"];`
+ isAcceptedDevice = conf: list: builtins.elem conf.modules.device.type list;
+
+ # assert if the device is wayland-ready by checking sys.video and env.isWayland options
+ # `(lib.isWayland config)` where config is in scope
+ # `isWayland osConfig` -> true
+ isWayland = conf: conf.modules.system.video.enable && conf.modules.usrEnv.isWayland;
+
+ # ifOneEnabled takes a parent option and 3 child options and checks if at least one of them is enabled
+ # `ifOneEnabled config.modules.services "service1" "service2" "service3"`
+ ifOneEnabled = cfg: a: b: c: (cfg.a || cfg.b || cfg.c);
+
+ # check if modernshell and cli are both enabled
+ isModernShell = conf: conf.modules.programs.cli.enable && conf.modules.programs.cli.modernShell.enable;
in {
- inherit ifTheyExist ifGroupsExist;
+ inherit ifTheyExist ifGroupsExist isAcceptedDevice isWayland ifOneEnabled isModernShell;
}
diff --git a/modules/common/core/default.nix b/modules/common/core/default.nix
index 3aad5f876..7a792d219 100644
--- a/modules/common/core/default.nix
+++ b/modules/common/core/default.nix
@@ -1,6 +1,6 @@
_: {
imports = [
- ./nix # configuration for the nix package manager and build tool
- ./system # system configurations, from bootloader to desktop environment
+ ./gaming # super cool procrastinations related things
+ ./system # system configurations
];
}
diff --git a/modules/common/core/gaming/default.nix b/modules/common/core/gaming/default.nix
new file mode 100644
index 000000000..a91902b91
--- /dev/null
+++ b/modules/common/core/gaming/default.nix
@@ -0,0 +1,6 @@
+_: {
+ imports = [
+ ./gamemode.nix # cool scripts, and programs to imporve gaming preformance
+ ./steam.nix # steam, the gaming platform
+ ];
+}
diff --git a/modules/common/core/gaming/gamemode.nix b/modules/common/core/gaming/gamemode.nix
new file mode 100644
index 000000000..db380a5a6
--- /dev/null
+++ b/modules/common/core/gaming/gamemode.nix
@@ -0,0 +1,62 @@
+{
+ config,
+ lib,
+ pkgs,
+ inputs,
+ ...
+}: let
+ inherit (lib) makeBinPath mkIf optionalString;
+
+ env = config.modules.usrEnv;
+
+ programs = makeBinPath (with pkgs; [
+ inputs.hyprland.packages.${stdenv.system}.default
+ coreutils
+ power-profiles-daemon
+ systemd
+ ]);
+
+ startscript = pkgs.writeShellScript "gamemode-start" ''
+ ${optionalString (env.desktop == "Hyprland") ''
+ export PATH=$PATH:${programs}
+ export HYPRLAND_INSTANCE_SIGNATURE=$(ls -w1 /tmp/hypr | tail -1)
+ hyprctl --batch 'keyword decoration:blur 0 ; keyword animations:enabled 0 ; keyword misc:vfr 0'
+ ''}
+
+ powerprofilesctl set performance
+ ${pkgs.libnotify}/bin/notify-send -a 'Gamemode' 'Optimizations activated'
+ '';
+
+ endscript = pkgs.writeShellScript "gamemode-end" ''
+ ${optionalString (env.desktop == "Hyprland") ''
+ export PATH=$PATH:${programs}
+ export HYPRLAND_INSTANCE_SIGNATURE=$(ls -w1 /tmp/hypr | tail -1)
+ hyprctl --batch 'keyword decoration:blur 1 ; keyword animations:enabled 1 ; keyword misc:vfr 1'
+ ''}
+
+ powerprofilesctl set power-saver
+ ${pkgs.libnotify}/bin/notify-send -a 'Gamemode' 'Optimizations deactivated'
+ '';
+
+ cfg = config.modules.programs.gaming;
+in {
+ imports = [./steam.nix];
+ config = mkIf cfg.enable {
+ programs = {
+ gamemode = {
+ enable = true;
+ enableRenice = true;
+ settings = {
+ general = {
+ softrealtime = "auto";
+ renice = 15;
+ };
+ custom = {
+ start = startscript.outPath;
+ end = endscript.outPath;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/core/gaming/steam.nix b/modules/common/core/gaming/steam.nix
new file mode 100644
index 000000000..b40eb6541
--- /dev/null
+++ b/modules/common/core/gaming/steam.nix
@@ -0,0 +1,24 @@
+{
+ pkgs,
+ lib,
+ config,
+ inputs,
+ ...
+}: let
+ cfg = config.modules.programs.gaming;
+in {
+ imports = [inputs.nix-gaming.nixosModules.steamCompat];
+ # enable steam
+ programs.steam = lib.mkIf cfg.enable {
+ enable = true;
+ # Open ports in the firewall for Steam Remote Play
+ remotePlay.openFirewall = true;
+ # Open ports in the firewall for Source Dedicated Server
+ dedicatedServer.openFirewall = true;
+ # Compatibility tools to install
+ # this option used to be provided by modules/shared/nixos/steam
+ extraCompatPackages = [
+ inputs.nix-gaming.packages.${pkgs.system}.proton-ge
+ ];
+ };
+}
diff --git a/modules/common/core/system/activation/default.nix b/modules/common/core/system/activation/default.nix
index 610b312b9..1fd45f26e 100644
--- a/modules/common/core/system/activation/default.nix
+++ b/modules/common/core/system/activation/default.nix
@@ -2,10 +2,8 @@
config,
lib,
...
-}: let
- inherit (lib) mkIf;
-in {
- system.activationScripts.diff = mkIf config.modules.system.activation.diffGenerations {
+}: {
+ system.activationScripts.diff = lib.mkIf config.modules.system.activation.diffGenerations {
supportsDryActivation = true;
text = ''
if [[ -e /run/current-system ]]; then
diff --git a/modules/common/core/system/boot/generic/default.nix b/modules/common/core/system/boot/generic/default.nix
deleted file mode 100644
index 8194462e0..000000000
--- a/modules/common/core/system/boot/generic/default.nix
+++ /dev/null
@@ -1,161 +0,0 @@
-{
- lib,
- config,
- ...
-}:
-with lib; let
- sys = config.modules.system;
-in {
- config = {
- boot = {
- consoleLogLevel = 0;
-
- # always use the latest kernel instead of the old-ass lts one
- kernelPackages = lib.mkOverride 500 sys.boot.kernel;
-
- extraModulePackages = with config.boot.kernelPackages; [acpi_call];
- extraModprobeConfig = "options hid_apple fnmode=1";
-
- # settings shared between bootloaders
- # they are set unless system.boot.loader != none
- loader = {
- # if set to 0, space needs to be held to get the boot menu to appear
- timeout = mkForce 2;
- generationsDir.copyKernels = true;
-
- # allow installation to modify EFI variables
- efi.canTouchEfiVariables = true;
- };
-
- # instructions on how /tmp should be handled
- # if your system is low on ram, you should avoid tmpfs to prevent hangups while compiling
- tmp = {
- # /tmp on tmpfs, lets it live on your ram
- useTmpfs = mkDefault true;
-
- # If not using tmpfs, which is naturally purged on reboot, we must clean
- # /tmp ourselves. /tmp should be volatile storage!
- cleanOnBoot = mkDefault (!config.boot.tmp.useTmpfs);
- };
-
- # initrd and kernel tweaks
- # if you intend to copy paste this section, read what each parameter or module does before doing so
- # I am not responsible for your broken system
- initrd = mkMerge [
- (mkIf sys.boot.enableInitrdTweaks {
- # Verbosity of the initrd
- # disabling verbosity removes only the mandatory messages generated by the NixOS
- verbose = false;
-
- # strip copied binaries and libraries from inframs
- # saves 30~ mb space according to the nix derivation
- systemd.strip = true;
-
- # extremely experimental, just the way I like it on a production machine
- systemd.enable = true;
- })
-
- (mkIf sys.boot.enableKernelTweaks {
- # List of modules that are always loaded by the initrd
- kernelModules = [
- "xhci_pci"
- "ahci"
- "btrfs"
- "cifs"
- "sd_mod"
- "dm_mod"
- "usb_storage"
- "rtsx_pci_sdmmc"
- ];
-
- # the set of kernel modules in the initial ramdisk used during the boot process
- availableKernelModules = [
- "nvme"
- "usbhid"
- "sd_mod"
- "dm_mod"
- ];
- })
- ];
-
- # https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
- kernelParams =
- [
- # https://en.wikipedia.org/wiki/Kernel_page-table_isolation
- # auto means kernel will automatically decide the pti state
- "pti=auto" # on | off
-
- # make stack-based attacks on the kernel harder
- "randomize_kstack_offset=on"
-
- # this has been defaulted to none back in 2016 - break really old binaries for security
- "vsyscall=none"
-
- # https://tails.boum.org/contribute/design/kernel_hardening/
- "slab_nomerge"
-
- # only allow signed modules
- "module.sig_enforce=1"
-
- # blocks access to all kernel memory, even preventing administrators from being able to inspect and probe the kernel
- "lockdown=confidentiality"
-
- # enable buddy allocator free poisoning
- "page_poison=1"
-
- # performance improvement for direct-mapped memory-side-cache utilization, reduces the predictability of page allocations
- "page_alloc.shuffle=1"
-
- # for debugging kernel-level slab issues
- "slub_debug=FZP"
-
- # always-enable sysrq keys. Useful for debugging
- "sysrq_always_enabled=0"
-
- # save power on idle by limiting c-states
- # https://gist.github.com/wmealing/2dd2b543c4d3cff6cab7
- "processor.max_cstate=5"
-
- # disable the intel_idle driver and use acpi_idle instead
- "idle=nomwait"
-
- # ignore access time (atime) updates on files, except when they coincide with updates to the ctime or mtime
- "rootflags=noatime"
-
- # enable IOMMU for devices used in passthrough and provide better host performance
- "iommu=pt"
-
- # disable usb autosuspend
- "usbcore.autosuspend=-1"
- # linux security modules
- "lsm=landlock,lockdown,yama,apparmor,bpf"
-
- # isables resume and restores original swap space
- "noresume"
-
- # allows systemd to set and save the backlight state
- "acpi_backlight=native" # none | vendor | video | native
-
- # prevent the kernel from blanking plymouth out of the fb
- "fbcon=nodefer"
-
- # disable boot logo if any
- "logo.nologo"
-
- # tell the kernel to not be verbose
- # "quiet"
-
- # disable systemd status messages
- # rd prefix means systemd-udev will be used instead of initrd
- "rd.systemd.show_status=auto"
-
- # lower the udev log level to show only errors or worse
- "rd.udev.log_level=3"
-
- # disable the cursor in vt to get a black screen during intermissions
- "vt.global_cursor_default=0"
- ]
- ++ optionals (sys.boot.extraKernelParams != []) sys.boot.extraKernelParams;
- };
- };
-}
diff --git a/modules/common/core/system/default.nix b/modules/common/core/system/default.nix
index ef19199a2..0b8368bb8 100644
--- a/modules/common/core/system/default.nix
+++ b/modules/common/core/system/default.nix
@@ -1,11 +1,14 @@
_: {
imports = [
- ./hardware # hardware - i.e bluetooth, sound, tpm etc.
- ./media # enable multimedia
- ./boot # boot and bootloader configurations
- ./os # system configurations
- ./smb # host and recive smb shares
./activation # activation system for nixos-rebuild
- ./virtualization # hypervisor and virtualisation related options - docker, QEMU, waydroid etc.
+ ./emulation # emulation setup
+ ./encryption # keeping my stuff hidden from you strange people
+ ./hardware # hardware - bluetooth etc.
+ ./media # sound and video
+ ./nix # nix the package manger options
+ ./os # system configurations
+ ./security # keeping the system safe
+ ./smb # host and recive smb shares TODO move
+ ./virtualization # docker, QEMU, waydroid etc.
];
}
diff --git a/modules/common/core/system/emulation/default.nix b/modules/common/core/system/emulation/default.nix
new file mode 100644
index 000000000..b4032a439
--- /dev/null
+++ b/modules/common/core/system/emulation/default.nix
@@ -0,0 +1,28 @@
+{
+ config,
+ pkgs,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf;
+ sys = config.modules.system;
+in {
+ config = mkIf sys.emulation.enable {
+ nix.settings.extra-sandbox-paths = ["/run/binfmt" "${pkgs.qemu}"];
+
+ boot.binfmt = {
+ emulatedSystems = sys.emulation.systems;
+ registrations = {
+ # aarch64 interpreter
+ aarch64-linux = {
+ interpreter = "${pkgs.qemu}/bin/qemu-aarch64";
+ };
+
+ # i686 interpreter
+ i686-linux = {
+ interpreter = "${pkgs.qemu}/bin/qemu-i686";
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/core/system/encryption/default.nix b/modules/common/core/system/encryption/default.nix
new file mode 100644
index 000000000..f770726f6
--- /dev/null
+++ b/modules/common/core/system/encryption/default.nix
@@ -0,0 +1,34 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ cfg = config.modules.system.encryption;
+in {
+ config = mkIf cfg.enable {
+ # mildly improves performance for the disk encryption
+ boot.initrd.availableKernelModules = [
+ "aesni_intel"
+ "cryptd"
+ "usb_storage"
+ ];
+
+ services.lvm.enable = true;
+
+ # TODO: account for multiple encrypted devices
+ boot.initrd.luks.devices."${cfg.device}" = {
+ # improve performance on ssds
+ bypassWorkqueues = true;
+ preLVM = true;
+
+ # the device with the maching id will be searched for the key file
+ keyFile = mkIf (cfg.keyFile != null) "${cfg.keyFile}";
+ keyFileSize = cfg.keySize;
+
+ # if keyfile is not there, fall back to cryptsetup password
+ fallbackToPassword = cfg.fallbackToPassword; # IMPLIED BY config.boot.initrd.systemd.enable
+ };
+ };
+}
diff --git a/modules/common/core/system/hardware/cpu/amd/default.nix b/modules/common/core/system/hardware/cpu/amd/default.nix
index 1c721a612..5b554cab3 100644
--- a/modules/common/core/system/hardware/cpu/amd/default.nix
+++ b/modules/common/core/system/hardware/cpu/amd/default.nix
@@ -2,12 +2,15 @@
config,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.modules) device;
+ inherit (lib) mkIf;
in {
config = mkIf (device.cpu == "amd" || device.cpu == "vm-amd") {
hardware.cpu.amd.updateMicrocode = true;
- boot.kernelModules = ["kvm-amd"];
+ boot.kernelModules = [
+ "kvm-amd"
+ "amd-pstate"
+ ];
};
}
diff --git a/modules/common/core/system/hardware/gpu/amd/default.nix b/modules/common/core/system/hardware/gpu/amd/default.nix
index 9cc0a4803..00a602160 100644
--- a/modules/common/core/system/hardware/gpu/amd/default.nix
+++ b/modules/common/core/system/hardware/gpu/amd/default.nix
@@ -8,7 +8,7 @@ with lib; let
device = config.modules.device;
in {
config = mkIf (device.gpu == "amd" || device.gpu == "hybrid-amd") {
- # enable amdgpu xorg drivers in case Hyprland breaks again
+ # enable amdgpu xorg drivers
services.xserver.videoDrivers = ["amdgpu"];
# enable amdgpu kernel module
diff --git a/modules/common/core/system/hardware/gpu/intel/default.nix b/modules/common/core/system/hardware/gpu/intel/default.nix
index c4f40301a..480bb80b5 100644
--- a/modules/common/core/system/hardware/gpu/intel/default.nix
+++ b/modules/common/core/system/hardware/gpu/intel/default.nix
@@ -8,13 +8,13 @@ with lib; let
device = config.modules.device;
in {
config = mkIf (device.gpu == "intel" || device.gpu == "hybrid-nv") {
- # enable the i915 kernel module
+ # i915 kernel module
boot.initrd.kernelModules = ["i915"];
- # better performance than the actual Intel driver
+ # better performance than the actual Intel driver, lol
services.xserver.videoDrivers = ["modesetting"];
nixpkgs.config.packageOverrides = pkgs: {
- # let me play youtube videos without h.264, please and thank you
+ # let me play youtube videos without h.264
vaapiIntel = pkgs.vaapiIntel.override {enableHybridCodec = true;};
};
diff --git a/modules/common/core/system/hardware/gpu/nvidia/default.nix b/modules/common/core/system/hardware/gpu/nvidia/default.nix
index 01f3cc8bf..a2b257e4e 100644
--- a/modules/common/core/system/hardware/gpu/nvidia/default.nix
+++ b/modules/common/core/system/hardware/gpu/nvidia/default.nix
@@ -5,7 +5,7 @@
...
}:
with lib; let
- # use the latest possible nvidia package
+ # only the newest nvidia package
nvStable = config.boot.kernelPackages.nvidiaPackages.stable.version;
nvBeta = config.boot.kernelPackages.nvidiaPackages.beta.version;
@@ -14,11 +14,11 @@ with lib; let
then config.boot.kernelPackages.nvidiaPackages.stable
else config.boot.kernelPackages.nvidiaPackages.beta;
- device = config.modules.device;
+ inherit (config.modules) device;
env = config.modules.usrEnv;
in {
config = mkIf (device.gpu == "nvidia" || device.gpu == "hybrid-nv") {
- # nvidia drivers are unfree software
+ # nvidia drivers kinda are unfree software
nixpkgs.config.allowUnfree = true;
services.xserver = mkMerge [
@@ -44,8 +44,7 @@ in {
];
boot = {
- # blacklist nouveau module so that it does not conflict with nvidia drm stuff
- # also the nouveau performance is godawful, I'd rather run linux on a piece of paper than use nouveau
+ # blacklist nouveau module as otherwise it conflicts with nvidia drm
blacklistedKernelModules = ["nouveau"];
};
@@ -55,13 +54,13 @@ in {
LIBVA_DRIVER_NAME = "nvidia";
}
- (mkIf (env.isWayland) {
+ (mkIf env.isWayland {
WLR_NO_HARDWARE_CURSORS = "1";
- #__GLX_VENDOR_LIBRARY_NAME = "nvidia";
- #GBM_BACKEND = "nvidia-drm"; # breaks firefox apparently
+ __GLX_VENDOR_LIBRARY_NAME = "nvidia";
+ GBM_BACKEND = "nvidia-drm"; # breaks firefox apparently (not that i use it lol)
})
- (mkIf ((env.isWayland) && (device.gpu == "hybrid-nv")) {
+ (mkIf (env.isWayland && device.gpu == "hybrid-nv") {
#__NV_PRIME_RENDER_OFFLOAD = "1";
#WLR_DRM_DEVICES = mkDefault "/dev/dri/card1:/dev/dri/card0";
})
@@ -80,15 +79,13 @@ in {
package = mkDefault nvidiaPackage;
modesetting.enable = mkDefault true;
prime.offload.enableOffloadCmd = device.gpu == "hybrid-nv";
- #powerManagement = {
- # enable = mkDefault true;
- # finegrained = mkDefault true;
- #};
+ powerManagement = {
+ enable = mkDefault true;
+ finegrained = mkDefault true;
+ };
- # use open source drivers by default, hosts may override this option if their gpu is
- # not supported by the open source drivers
- open = mkDefault true;
- nvidiaSettings = false; # add nvidia-settings to pkgs, useless on nixos
+ open = mkDefault true; # use open source drivers by default
+ nvidiaSettings = false; # adds nvidia-settings to pkgs, so useless on nixos
nvidiaPersistenced = true;
forceFullCompositionPipeline = true;
};
diff --git a/modules/common/core/system/media/sound/default.nix b/modules/common/core/system/media/sound/default.nix
index 5855836e5..2e837ed5d 100644
--- a/modules/common/core/system/media/sound/default.nix
+++ b/modules/common/core/system/media/sound/default.nix
@@ -2,35 +2,48 @@
lib,
config,
pkgs,
+ inputs,
...
-}:
-with lib; let
+}: let
+ inherit (lib) mkIf mkDefault;
+ inherit (pkgs.stdenv) hostPlatform;
+
+ isx86Linux = hostPlatform.isLinux && hostPlatform.isx86;
+
cfg = config.modules.system.sound;
- device = config.modules.device;
+ inherit (config.modules) device;
in {
+ imports = [inputs.nix-gaming.nixosModules.pipewireLowLatency];
+
config = mkIf (cfg.enable && device.hasSound) {
# enable sound support and media keys if device has sound
sound = {
enable = true;
mediaKeys.enable = true;
};
+
# able to change scheduling policies, e.g. to SCHED_RR
security.rtkit.enable = config.services.pipewire.enable;
- # we replace pulseaudio with the incredibly based pipewire
+ # pipewire is newer and just better
services.pipewire = {
enable = mkDefault true;
+ wireplumber.enable = true;
+ pulse.enable = true;
+ jack.enable = true;
alsa = {
enable = true;
- support32Bit = with pkgs; (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isx86);
+ support32Bit = isx86Linux;
+ };
+
+ lowLatency = {
+ enable = true;
+ quantum = 64;
+ rate = 48000;
};
- pulse.enable = true;
- jack.enable = true;
- wireplumber.enable = true;
};
- # if for some reason pipewire is disabled, we may enable pulseaudio as backup
- # I don't like PA, but I won't discard it altogether
+ # pulseaudio backup
hardware.pulseaudio.enable = !config.services.pipewire.enable;
# write bluetooth rules if and only if pipewire is enabled AND the device has bluetooth
environment.etc = mkIf (config.services.pipewire.enable && device.hasBluetooth) {
diff --git a/modules/common/core/nix/default.nix b/modules/common/core/system/nix/default.nix
similarity index 68%
rename from modules/common/core/nix/default.nix
rename to modules/common/core/system/nix/default.nix
index 5c7cc92bb..bf27f6287 100644
--- a/modules/common/core/nix/default.nix
+++ b/modules/common/core/system/nix/default.nix
@@ -6,8 +6,7 @@
inputs',
self,
...
-}:
-with lib; {
+}: {
system = {
autoUpgrade.enable = false;
stateVersion = lib.mkDefault "23.05";
@@ -24,12 +23,12 @@ with lib; {
"nixos/flake".source = self;
};
- # we need git for flakes, don't we
+ # git is reqired for flakes
systemPackages = [pkgs.git];
};
nixpkgs = {
- pkgs = self.legacyPackages.${config.nixpkgs.system};
+ #pkgs = self.legacyPackages.${config.nixpkgs.system};
config = {
allowUnfree = true;
@@ -38,27 +37,16 @@ with lib; {
permittedInsecurePackages = [];
};
- overlays = with inputs; let
- nurOpt = config.modules.programs.nur;
- in
- [
- rust-overlay.overlays.default
- ]
- ++ optionals (nurOpt.enable) [
- (final: prev: {
- nur = import nur {
- nurpkgs = prev;
- pkgs = prev;
- repoOverrides =
- {}
- // lib.optionalAttrs (nurOpt.bella) {bella = inputs'.bella-nur.packages;}
- // lib.optionalAttrs (nurOpt.nekowinston) {nekowinston = inputs'.nekowinston-nur.packages;};
- };
- })
- ];
+ overlays = [
+ inputs.rust-overlay.overlays.default
+
+ (_: _: {
+ nixSchemas = inputs'.nixSchemas.packages.default;
+ })
+ ];
};
- # faster rebuilding
+ # faster rebuilding, plus i don't use the docs anyways
documentation = {
doc.enable = false;
nixos.enable = false;
@@ -70,33 +58,27 @@ with lib; {
};
nix = let
- mappedRegistry = mapAttrs (_: v: {flake = v;}) inputs;
+ mappedRegistry = lib.mapAttrs (_: v: {flake = v;}) inputs;
in {
- # pin the registry to avoid downloading and evaluating a new nixpkgs
- # version everytime
- # this will add each flake input as a registry
- # to make nix3 commands consistent with your flake
+ # pin the registry to avoid downloading and evaluating a new nixpkgs version everytime
registry = mappedRegistry // {default = mappedRegistry.nixpkgs;};
- # This will additionally add your inputs to the system's legacy channels
- # Making legacy nix commands consistent as well, awesome!
- nixPath = mapAttrsToList (key: _: "${key}=flake:${key}") config.nix.registry;
+ # We love legacy support (for now)
+ nixPath = lib.mapAttrsToList (key: _: "${key}=flake:${key}") config.nix.registry;
- # Make builds run with low priority so my system stays responsive
+ # Make builds run with a low priority, keeping the system fast
daemonCPUSchedPolicy = "idle";
daemonIOSchedClass = "idle";
daemonIOSchedPriority = 7;
- # set up garbage collection to run daily,
- # removing unused packages after three days
+ # set up garbage collection to run daily, and removing packages after 3 days
gc = {
automatic = true;
dates = "Mon *-*-* 03:00";
options = "--delete-older-than 3d";
};
- # automatically optimize nix store my removing hard links
- # do it after the gc
+ # automatically optimize /nix/store by removing hard links
optimise = {
automatic = true;
dates = ["04:00"];
@@ -106,7 +88,7 @@ with lib; {
# specify the path to the nix registry
flake-registry = "/etc/nix/registry.json";
# Free up to 20GiB whenever there is less than 5GB left.
- # this setting is in bytes, so we multiply with 1024 thrice
+ # this setting is in bytes, so we multiply with 1024 by 3
min-free = "${toString (5 * 1024 * 1024 * 1024)}";
max-free = "${toString (20 * 1024 * 1024 * 1024)}";
# automatically optimise symlinks
@@ -121,15 +103,13 @@ with lib; {
sandbox = true;
# supported system features
# TODO: "gccarch-core2" "gccarch-haswell"
- system-features = ["nixos-tests" "kvm" "recursive-nix" "big-parallel"];
- # extra architectures supported by my builders
+ system-features = ["nixos-test" "kvm" "recursive-nix" "big-parallel"];
extra-platforms = config.boot.binfmt.emulatedSystems;
- # continue building derivations if one fails
+ # continue building derivations even if one fails
keep-going = true;
- # show more log lines for failed builds
+ # show more log lines for failed builds, as this happens alot and is useful
log-lines = 30;
- # enable new nix command and flakes
- # and also "unintended" recursion as well as content addresssed nix
+ # enable new nix command and flakes and also "unintended" recursion as well as content addresssed nix
extra-experimental-features = [
"flakes"
"nix-command"
@@ -138,7 +118,7 @@ with lib; {
"repl-flake"
"auto-allocate-uids"
];
- # don't warn me that my git tree is dirty, I know
+ # ignore dirty working tree
warn-dirty = false;
# maximum number of parallel TCP connections used to fetch imports and binary caches, 0 means no limit
http-connections = 50;
@@ -151,15 +131,16 @@ with lib; {
# substituters to use
substituters = [
- "https://cache.ngi0.nixos.org" # content addressed nix cache (TODO)
+ "https://cache.ngi0.nixos.org" # content addressed nix cache
"https://cache.nixos.org" # funny binary cache
- "https://nixpkgs-wayland.cachix.org" # automated builds of *some* wayland packages
+ "https://nixpkgs-wayland.cachix.org" # some wayland packages
"https://nix-community.cachix.org" # nix-community cache
"https://hyprland.cachix.org" # hyprland
"https://nix-gaming.cachix.org" # nix-gaming
"https://nixpkgs-unfree.cachix.org" # unfree-package cache
"https://numtide.cachix.org" # another unfree package cache
"https://isabelroses.cachix.org" # precompiled binarys from my NUR
+ "https://neovim-flake.cachix.org" # a cache for notashelf's neovim flake
];
trusted-public-keys = [
@@ -172,6 +153,7 @@ with lib; {
"nixpkgs-unfree.cachix.org-1:hqvoInulhbV4nJ9yJOEr+4wxhDV4xq2d1DK7S6Nj6rs="
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
"isabelroses.cachix.org-1:mXdV/CMcPDaiTmkQ7/4+MzChpOe6Cb97njKmBQQmLPM="
+ "neovim-flake.cachix.org-1:iyQ6lHFhnB5UkVpxhQqLJbneWBTzM8LBYOFPLNH4qZw="
];
};
};
diff --git a/modules/common/core/system/boot/default.nix b/modules/common/core/system/os/boot/default.nix
similarity index 100%
rename from modules/common/core/system/boot/default.nix
rename to modules/common/core/system/os/boot/default.nix
index 8529c980b..c48141432 100644
--- a/modules/common/core/system/boot/default.nix
+++ b/modules/common/core/system/os/boot/default.nix
@@ -1,8 +1,8 @@
_: {
imports = [
+ ./generic
./loader
- ./secure-boot
./plymouth
- ./generic
+ ./secure-boot
];
}
diff --git a/modules/common/core/system/os/boot/generic/default.nix b/modules/common/core/system/os/boot/generic/default.nix
new file mode 100644
index 000000000..64863bd62
--- /dev/null
+++ b/modules/common/core/system/os/boot/generic/default.nix
@@ -0,0 +1,126 @@
+{
+ lib,
+ config,
+ ...
+}: let
+ inherit (lib) mkDefault mkForce mkOverride mkMerge mkIf optionals;
+ sys = config.modules.system;
+in {
+ config = {
+ boot = {
+ consoleLogLevel = 0;
+
+ # always use the latest kernel, love the unstablity
+ kernelPackages = mkOverride 500 sys.boot.kernel;
+
+ extraModulePackages = mkDefault sys.boot.extraModulePackages;
+ extraModprobeConfig = mkDefault sys.boot.extraModprobeConfig;
+ # whether to enable support for Linux MD RAID arrays
+ # as of 23.11>, this throws a warning if neither MAILADDR nor PROGRAM are set
+ swraid.enable = mkDefault false;
+
+ # shared config between bootloaders
+ # they are set unless system.boot.loader != none
+ loader = {
+ # if set to 0, space needs to be held to get the boot menu to appear
+ timeout = mkForce 2;
+ generationsDir.copyKernels = true;
+
+ # we need to allow installation to modify EFI variables
+ efi.canTouchEfiVariables = true;
+ };
+
+ # if you have a lack of ram, you should avoid tmpfs to prevent hangups while compiling
+ tmp = {
+ # /tmp on tmpfs, lets it live on your ram
+ useTmpfs = sys.boot.tmpOnTmpfs;
+
+ # If not using tmpfs, which is naturally purged on reboot, we must clean
+ # we have to clean /tmp
+ cleanOnBoot = mkDefault (!config.boot.tmp.useTmpfs);
+ };
+
+ # initrd and kernel tweaks
+ # read what each parameter or module does before doing so, it will defo break something otherwise
+ initrd = mkMerge [
+ (mkIf sys.boot.enableInitrdTweaks {
+ # Verbosity of the initrd
+ # disabling verbosity removes only the mandatory messages generated by the NixOS
+ verbose = false;
+
+ # strip copied binaries and libraries from inframs
+ # saves some nice space
+ systemd.strip = true;
+
+ # enable systemd in initrd (experimental)
+ systemd.enable = true;
+
+ # List of modules that are loaded by the initrd
+ kernelModules = [
+ "nvme"
+ "xhci_pci"
+ "ahci"
+ "btrfs"
+ "cifs"
+ "sd_mod"
+ "dm_mod"
+ "tpm"
+ ];
+
+ # the set of kernel modules in the initial ramdisk used during the boot process
+ availableKernelModules = [
+ "usbhid"
+ "sd_mod"
+ "dm_mod"
+ "uas"
+ "usb_storage"
+ "rtsx_pci_sdmmc" # Realtek SD card interface (btw i hate realtek)
+ ];
+ })
+ ];
+
+ # https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
+ kernelParams =
+ (optionals sys.boot.enableKernelTweaks [
+ # https://en.wikipedia.org/wiki/Kernel_page-table_isolation
+ # auto means kernel will automatically decide the pti state
+ "pti=auto" # on || off
+
+ # disable the intel_idle (it stinks anyway) driver and use acpi_idle instead
+ "idle=nomwait"
+
+ # enable IOMMU for devices used in passthrough and provide better host performance
+ "iommu=pt"
+
+ # disable usb autosuspend
+ "usbcore.autosuspend=-1"
+
+ # isables resume and restores original swap space
+ "noresume"
+
+ # allow systemd to set and save the backlight state
+ "acpi_backlight=native"
+
+ # prevent the kernel from blanking plymouth out of the fb
+ "fbcon=nodefer"
+
+ # disable boot logo
+ "logo.nologo"
+
+ # disable systemd status messages
+ # rd prefix means systemd-udev will be used instead of initrd
+ "rd.systemd.show_status=auto"
+
+ # lower the udev log level to show only errors or worse
+ "rd.udev.log_level=3"
+
+ # disable the cursor in vt to get a black screen during intermissions
+ "vt.global_cursor_default=0"
+ ])
+ ++ (optionals sys.boot.silentBoot [
+ # tell the kernel to not be verbose, the voices are too loud
+ "quite"
+ ]);
+ };
+ };
+}
diff --git a/modules/common/core/system/boot/loader/default.nix b/modules/common/core/system/os/boot/loader/default.nix
similarity index 100%
rename from modules/common/core/system/boot/loader/default.nix
rename to modules/common/core/system/os/boot/loader/default.nix
diff --git a/modules/common/core/system/boot/loader/grub/default.nix b/modules/common/core/system/os/boot/loader/grub/default.nix
similarity index 100%
rename from modules/common/core/system/boot/loader/grub/default.nix
rename to modules/common/core/system/os/boot/loader/grub/default.nix
diff --git a/modules/common/core/system/boot/loader/none/default.nix b/modules/common/core/system/os/boot/loader/none/default.nix
similarity index 100%
rename from modules/common/core/system/boot/loader/none/default.nix
rename to modules/common/core/system/os/boot/loader/none/default.nix
diff --git a/modules/common/core/system/boot/loader/systemd-boot/default.nix b/modules/common/core/system/os/boot/loader/systemd-boot/default.nix
similarity index 66%
rename from modules/common/core/system/boot/loader/systemd-boot/default.nix
rename to modules/common/core/system/os/boot/loader/systemd-boot/default.nix
index f6f8e0e75..bedff3b8d 100644
--- a/modules/common/core/system/boot/loader/systemd-boot/default.nix
+++ b/modules/common/core/system/os/boot/loader/systemd-boot/default.nix
@@ -13,14 +13,12 @@ in {
{
enable = mkDefault true;
configurationLimit = null;
- consoleMode = mkDefault "max"; # the default is "keep", can be overriden per host if need be
+ consoleMode = mkDefault "max"; # the default is "keep"
- # Fix a security hole in place for backwards compatibility. See desc in
- # nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+ # Fix a security hole. See desc in nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
editor = false;
}
// optionalAttrs cfg.memtest.enable {
- # https://matrix.to/#/!sgkZKRutwatDMkYBHU:nixos.org/$iKnJUt1L_7E5bq7hStDPwv6_2HTBvNjwfcWxlKlF-k8?via=nixos.org&via=matrix.org&via=nixos.dev
extraFiles."efi/memtest86plus/memtest.efi" = "${cfg.boot.memtest.package}/memtest.efi";
extraEntries."memtest86plus.conf" = ''
title MemTest86+
diff --git a/modules/common/core/system/boot/plymouth/default.nix b/modules/common/core/system/os/boot/plymouth/default.nix
similarity index 86%
rename from modules/common/core/system/boot/plymouth/default.nix
rename to modules/common/core/system/os/boot/plymouth/default.nix
index 40f0f314c..3020fc1e7 100644
--- a/modules/common/core/system/boot/plymouth/default.nix
+++ b/modules/common/core/system/os/boot/plymouth/default.nix
@@ -1,6 +1,7 @@
{
config,
lib,
+ self',
pkgs,
...
}: let
@@ -16,7 +17,7 @@ in {
}
// lib.optionalAttrs cfg.withThemes {
theme = "catppuccin-mocha";
- themePackages = [pkgs.nur.repos.nekowinston.plymouth-theme-catppuccin];
+ themePackages = [self'.packages.plymouth-theme-catppuccin];
};
# make plymouth work with sleep
diff --git a/modules/common/core/system/boot/secure-boot/default.nix b/modules/common/core/system/os/boot/secure-boot/default.nix
similarity index 54%
rename from modules/common/core/system/boot/secure-boot/default.nix
rename to modules/common/core/system/os/boot/secure-boot/default.nix
index 3bcca5b8f..22500ea02 100644
--- a/modules/common/core/system/boot/secure-boot/default.nix
+++ b/modules/common/core/system/os/boot/secure-boot/default.nix
@@ -6,22 +6,19 @@
...
}:
with lib; let
- sys = config.modules.system.security;
+ sys = config.modules.system.boot;
in {
imports = [
inputs.lanzaboote.nixosModules.lanzaboote
];
- config = mkIf (sys.secureBoot) {
+ config = mkIf sys.secureBoot {
environment.systemPackages = [
- # For debugging and troubleshooting Secure Boot.
+ # Secure Boot, my love keeping my valorant working on windows
pkgs.sbctl
];
- # Lanzaboote currently replaces the systemd-boot module.
- # This setting is usually set to true in configuration.nix
- # generated at installation time. So we force it to false
- # for now.
+ # Lanzaboote replaces the systemd-boot module.
boot.loader.systemd-boot.enable = lib.mkForce false;
boot = {
diff --git a/modules/common/core/system/os/default.nix b/modules/common/core/system/os/default.nix
index 6881df3ac..d9d389e4d 100644
--- a/modules/common/core/system/os/default.nix
+++ b/modules/common/core/system/os/default.nix
@@ -1,12 +1,12 @@
_: {
imports = [
- ./display
- ./environment
- ./locale
- ./network
- ./programs
- ./security
- ./services
- ./users
+ ./boot # boot and bootloader configurations
+ ./display # display protocol
+ ./environment # system enviroment
+ ./fs # file system confiurations
+ ./network # networking
+ ./programs # common programs
+ ./services # common services
+ ./users # who is on the system
];
}
diff --git a/modules/common/core/system/os/display/wayland/default.nix b/modules/common/core/system/os/display/wayland/default.nix
index 8a01a41da..5e872f11a 100644
--- a/modules/common/core/system/os/display/wayland/default.nix
+++ b/modules/common/core/system/os/display/wayland/default.nix
@@ -5,5 +5,6 @@ _: {
./environment.nix
./portals.nix
./overlay.nix
+ ./services.nix
];
}
diff --git a/modules/common/core/system/os/display/wayland/environment.nix b/modules/common/core/system/os/display/wayland/environment.nix
index 174604f28..f832b478e 100644
--- a/modules/common/core/system/os/display/wayland/environment.nix
+++ b/modules/common/core/system/os/display/wayland/environment.nix
@@ -2,12 +2,17 @@
config,
lib,
...
-}:
-with lib; let
+}: let
+ inherit (lib) mkIf;
sys = config.modules.system.video;
env = config.modules.usrEnv;
in {
config = mkIf (sys.enable && env.isWayland) {
+ environment.etc."greetd/environments".text = mkIf config.services.greetd.enable ''
+ ${lib.optionalString (env.desktop == "Hyprland") "Hyprland"}
+ fish
+ '';
+
environment = {
variables = {
NIXOS_OZONE_WL = "1";
diff --git a/modules/common/core/system/os/display/wayland/portals.nix b/modules/common/core/system/os/display/wayland/portals.nix
index 5533aac36..28cd9f449 100644
--- a/modules/common/core/system/os/display/wayland/portals.nix
+++ b/modules/common/core/system/os/display/wayland/portals.nix
@@ -8,15 +8,14 @@
env = config.modules.usrEnv;
inherit (lib) mkForce mkIf;
in {
- config = mkIf (sys.video.enable) {
+ config = mkIf sys.video.enable {
xdg.portal = {
enable = true;
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
- # xdg-desktop-wlr (this section) is no longer needed, xdg-desktop-portal-hyprland
- # will (and should) override this one, set to false or remove this section
+
wlr = {
enable = mkForce (env.isWayland && env.desktop != "Hyprland");
settings = {
diff --git a/modules/common/core/system/os/display/wayland/services.nix b/modules/common/core/system/os/display/wayland/services.nix
new file mode 100644
index 000000000..5f991d3bd
--- /dev/null
+++ b/modules/common/core/system/os/display/wayland/services.nix
@@ -0,0 +1,27 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf getExe;
+
+ cfg = config.modules.system.video;
+ env = config.modules.usrEnv;
+in {
+ config = mkIf (cfg.enable && env.isWayland) {
+ systemd.services = {
+ seatd = {
+ enable = true;
+ description = "Seat management daemon";
+ script = "${getExe pkgs.seatd} -g wheel";
+ serviceConfig = {
+ Type = "simple";
+ Restart = "always";
+ RestartSec = "1";
+ };
+ wantedBy = ["multi-user.target"];
+ };
+ };
+ };
+}
diff --git a/modules/common/core/system/os/display/wayland/wm/hyprland.nix b/modules/common/core/system/os/display/wayland/wm/hyprland.nix
index 2536a5dcc..9f693ed86 100644
--- a/modules/common/core/system/os/display/wayland/wm/hyprland.nix
+++ b/modules/common/core/system/os/display/wayland/wm/hyprland.nix
@@ -17,11 +17,7 @@ in {
xdg.portal = {
extraPortals = [
- (inputs'.xdg-portal-hyprland.packages.xdg-desktop-portal-hyprland.override {
- hyprland-share-picker = inputs'.xdg-portal-hyprland.packages.hyprland-share-picker.override {
- hyprland = inputs'.hyprland.packages.default;
- };
- })
+ inputs'.xdg-portal-hyprland.packages.xdg-desktop-portal-hyprland
];
};
};
diff --git a/modules/common/core/system/os/environment/default.nix b/modules/common/core/system/os/environment/default.nix
index 9a4a03f18..e2fbdf33d 100644
--- a/modules/common/core/system/os/environment/default.nix
+++ b/modules/common/core/system/os/environment/default.nix
@@ -3,17 +3,23 @@
pkgs,
...
}: {
+ imports = [
+ ./locale.nix # locale settings
+ ];
+
environment = {
- # variables that I want to set globally on all systems
+ # the below can be done for faster shell reponse time but it can break things, and it did
+ # binsh = "${pkgs.dash}/bin/dash";
+
variables = {
EDITOR = "nvim";
- VISUAL = "nvim";
+ VISUAL = "vscodium";
SYSTEMD_PAGERSECURE = "true";
PAGER = "less -FR";
FLAKE = "${config.modules.system.flakePath}";
};
- # packages I want pre-installed on all systems
+ # packages that should be on all deviecs
systemPackages = with pkgs; [
git
curl
@@ -22,8 +28,15 @@
lshw
];
- # disable all packages installed by default, so that my system doesn't have anything
- # that I myself have added
+ # disable all packages installed by default, i prefer my own packages
defaultPackages = [];
+
+ # enable completions for system packages
+ pathsToLink = ["/share/zsh" "/share/nushell" "/share/fish" "/share/bash-completion" "/share/nix-direnv"];
+
+ # https://github.com/NixOS/nixpkgs/issues/72394#issuecomment-549110501
+ etc."mdadm.conf".text = ''
+ MAILADDR root
+ '';
};
}
diff --git a/modules/common/core/system/os/locale/default.nix b/modules/common/core/system/os/environment/locale.nix
similarity index 95%
rename from modules/common/core/system/os/locale/default.nix
rename to modules/common/core/system/os/environment/locale.nix
index 1770d187f..0d26af089 100644
--- a/modules/common/core/system/os/locale/default.nix
+++ b/modules/common/core/system/os/environment/locale.nix
@@ -21,5 +21,6 @@
variant = "u24n";
in {
font = "${pkgs.terminus_font}/share/consolefonts/ter-${variant}.psf.gz";
+ keyMap = "en";
};
}
diff --git a/modules/common/core/system/os/fs/default.nix b/modules/common/core/system/os/fs/default.nix
new file mode 100644
index 000000000..22ff93473
--- /dev/null
+++ b/modules/common/core/system/os/fs/default.nix
@@ -0,0 +1,51 @@
+{
+ lib,
+ config,
+ ...
+}:
+with lib; let
+ sys = config.modules.system;
+in {
+ config = mkMerge [
+ (mkIf (builtins.elem "btrfs" sys.fs) {
+ # clean btrfs devices
+ services.btrfs.autoScrub = {
+ enable = true;
+ fileSystems = ["/"];
+ };
+
+ # fix: initrd.systemd.enable
+ boot = {
+ supportedFilesystems = ["btrfs"];
+ initrd = {
+ supportedFilesystems = ["btrfs"];
+ };
+ };
+ })
+
+ (mkIf (builtins.elem "ext4" sys.fs) {
+ boot = {
+ supportedFilesystems = ["ext4"];
+ initrd = {
+ supportedFilesystems = ["ext4"];
+ };
+ };
+ })
+
+ (mkIf (builtins.elem "exfat" sys.fs) {
+ boot = {
+ supportedFilesystems = ["exfat"];
+ initrd = {
+ supportedFilesystems = ["exfat"];
+ };
+ };
+ })
+
+ # accept both ntfs and ntfs3 as valid values
+ (mkIf ((builtins.elem "ntfs" sys.fs) || (builtins.elem "ntfs3" sys.fs)) {
+ boot = {
+ supportedFilesystems = ["ntfs"];
+ };
+ })
+ ];
+}
diff --git a/modules/common/core/system/os/network/blocker.nix b/modules/common/core/system/os/network/blocker.nix
index fb63da0d6..2890dafe7 100644
--- a/modules/common/core/system/os/network/blocker.nix
+++ b/modules/common/core/system/os/network/blocker.nix
@@ -1,14 +1,12 @@
{config, ...}: let
device = config.modules.device;
in {
- # this should block *most* junk sites
- networking = {
- stevenblack = {
- enable = device.type != "server";
- block = [
- "fakenews"
- "gambling"
- ];
- };
+ # remove stupid sites that i just don't want to see
+ networking.stevenblack = {
+ enable = device.type != "server";
+ block = [
+ "fakenews"
+ "gambling"
+ ];
};
}
diff --git a/modules/common/core/system/os/network/default.nix b/modules/common/core/system/os/network/default.nix
index 472a150de..77aa6d5d0 100644
--- a/modules/common/core/system/os/network/default.nix
+++ b/modules/common/core/system/os/network/default.nix
@@ -2,8 +2,11 @@
lib,
config,
...
-}:
-with lib; {
+}: let
+ inherit (lib) mkIf mkDefault mkForce genAttrs;
+
+ dev = config.modules.device;
+in {
imports = [
./blocker.nix
./firewall.nix
@@ -17,22 +20,21 @@ with lib; {
};
networking = {
+ # generate a host ID by hashing the hostname
+ hostId = builtins.substring 0 8 (
+ builtins.hashString "md5" config.networking.hostName
+ );
+
hostName = config.modules.system.hostname;
- # global dhcp has been deprecated upstream
- # use networkd instead
- # individual interfaces are still managed through dhcp in hardware configurations
+ # global dhcp has been deprecated upstream, so we use networkd instead
+ # however individual interfaces are still managed through dhcp in hardware configurations
useDHCP = mkDefault false;
useNetworkd = mkDefault true;
# dns
nameservers = [
- # cloudflare, yuck
- # shares data
"1.1.1.1"
"1.0.0.1"
-
- # quad9, said to be the best
- # shares *less* data
"9.9.9.9"
];
@@ -41,21 +43,26 @@ with lib; {
plugins = [];
dns = "systemd-resolved";
unmanaged = ["docker0" "rndis0"];
+
wifi = {
+ # The below is disabled as my uni hated me for it
+ # macAddress = "random"; # use a random mac address on every boot, this can scew with static ip
powersave = true;
- #macAddress = "random"; # use a random mac address on every boot
+ scanRandMacAddress = true; # MAC address randomization of a Wi-Fi device during scanning
};
+
+ ethernet.macAddress = mkIf (dev.type != "server") "random";
};
};
- # enable wireless database, it helps with finding the right channels
+ # enable wireless database, it helps keeping wifi speedy
hardware.wirelessRegulatoryDatabase = true;
# allow for the system to boot without waiting for the network interfaces are online
- # speeds up boot times
systemd = let
ethernetDevices = [
"wlp1s0f0u8" # wifi dongle
+ "enp7s0" # ethernet interface on the motherboard
];
in {
network.wait-online.enable = false;
@@ -67,10 +74,10 @@ with lib; {
systemd-networkd.stopIfChanged = false;
systemd-resolved.stopIfChanged = false;
}
- // lib.concatMapAttrs (_: v: v) (lib.genAttrs ethernetDevices (device: {
+ // lib.concatMapAttrs (_: v: v) (genAttrs ethernetDevices (device: {
# Assign an IP address when the device is plugged in rather than on startup. Needed to prevent
# blocking the boot sequence when the device is unavailable, as it is hotpluggable.
- "network-addresses-${device}".wantedBy = lib.mkForce ["sys-subsystem-net-devices-${device}.device"];
+ "network-addresses-${device}".wantedBy = mkForce ["sys-subsystem-net-devices-${device}.device"];
}));
};
}
diff --git a/modules/common/core/system/os/network/firewall.nix b/modules/common/core/system/os/network/firewall.nix
index d1359a6e4..87cc1cb8c 100644
--- a/modules/common/core/system/os/network/firewall.nix
+++ b/modules/common/core/system/os/network/firewall.nix
@@ -4,9 +4,31 @@
config,
...
}: let
- inherit (lib) mkDefault mkForce;
- device = config.modules.device;
+ inherit (lib) mkDefault mkForce mkIf;
+ inherit (config.modules) device;
in {
+ environment.etc."fail2ban/filter.d/vaultwarden.conf" = {
+ inherit (config.services.vaultwarden) enable;
+ text = ''
+ [INCLUDES]
+ before = common.conf
+ [Definition]
+ failregex = ^.*Username or password is incorrect\. Try again\. IP: \. Username:.*$
+ ignoreregex =
+ '';
+ };
+
+ environment.etc."fail2ban/filter.d/vaultwarden-admin.conf" = {
+ inherit (config.services.vaultwarden) enable;
+ text = ''
+ [INCLUDES]
+ before = common.conf
+ [Definition]
+ failregex = ^.*Invalid admin token\. IP: .*$
+ ignoreregex =
+ '';
+ };
+
services = {
# enable opensnitch firewall
# inactive until opensnitch UI is opened
@@ -19,6 +41,7 @@ in {
maxretry = 7;
ignoreIP = [
"127.0.0.0/8"
+ "10.0.0.0/8"
"192.168.86.0/16"
];
@@ -28,6 +51,27 @@ in {
port = 22
mode = aggressive
'';
+
+ vaultwarden = ''
+ enabled = true
+ port = 80,443,8822
+ filter = vaultwarden
+ banaction = %(banaction_allports)s
+ logpath = /var/log/vaultwarden.log
+ maxretry = 3
+ bantime = 14400
+ findtime = 14400
+ '';
+ vaultwarden-admin = ''
+ enabled = true
+ port = 80,443
+ filter = vaultwarden-admin
+ banaction = %(banaction_allports)s
+ logpath = /var/log/vaultwarden.log
+ maxretry = 3
+ bantime = 14400
+ findtime = 14400
+ '';
};
bantime-increment = {
@@ -44,15 +88,18 @@ in {
firewall = {
enable = mkDefault true;
package = mkDefault pkgs.iptables-nftables-compat;
- allowedTCPPorts = [];
+ allowedTCPPorts = [
+ 443
+ 8080
+ ];
allowedUDPPorts = [];
- allowedTCPPortRanges = [
+ allowedTCPPortRanges = mkIf (device.type != "server") [
{
from = 1714;
to = 1764;
} #KDEconnect
];
- allowedUDPPortRanges = [
+ allowedUDPPortRanges = mkIf (device.type != "server") [
{
from = 1714;
to = 1764;
diff --git a/modules/common/core/system/os/network/optimise.nix b/modules/common/core/system/os/network/optimise.nix
index ea222197b..4f00c3870 100644
--- a/modules/common/core/system/os/network/optimise.nix
+++ b/modules/common/core/system/os/network/optimise.nix
@@ -51,7 +51,6 @@ in {
"net.ipv4.tcp_congestion_control" = "bbr";
"net.core.default_qdisc" = "cake";
- # Other stuff I am too lazy to document
"net.core.optmem_max" = 65536;
"net.core.rmem_default" = 1048576;
"net.core.rmem_max" = 16777216;
diff --git a/modules/common/core/system/os/network/ssh.nix b/modules/common/core/system/os/network/ssh.nix
index e1537b435..85fc6119d 100644
--- a/modules/common/core/system/os/network/ssh.nix
+++ b/modules/common/core/system/os/network/ssh.nix
@@ -34,7 +34,6 @@ in {
];
};
- # the ssh port(s) should be automatically passed to the firewall's allowedTCPports
openFirewall = true;
# the port(s) openssh daemon should listen on
ports = [22];
diff --git a/modules/common/core/system/os/programs/default.nix b/modules/common/core/system/os/programs/default.nix
index cb289be90..d2be97cf7 100644
--- a/modules/common/core/system/os/programs/default.nix
+++ b/modules/common/core/system/os/programs/default.nix
@@ -10,7 +10,6 @@
'';
};
# less pager
- # TODO: package moar for nix
less.enable = true;
fish.enable = true;
diff --git a/modules/common/core/system/os/security/default.nix b/modules/common/core/system/os/security/default.nix
deleted file mode 100644
index 199953ace..000000000
--- a/modules/common/core/system/os/security/default.nix
+++ /dev/null
@@ -1,140 +0,0 @@
-{
- config,
- pkgs,
- lib,
- ...
-}:
-with lib; let
- sys = config.modules.system;
-in {
- security = {
- protectKernelImage = true;
- lockKernelModules = false; # breaks virtd, wireguard and iptables
-
- # force-enable the Page Table Isolation (PTI) Linux kernel feature
- forcePageTableIsolation = true;
-
- # User namespaces are required for sandboxing. Better than nothing imo.
- allowUserNamespaces = true;
-
- apparmor = {
- enable = true;
- killUnconfinedConfinables = true;
- packages = [pkgs.apparmor-profiles];
- };
-
- virtualisation = {
- # flush the L1 data cache before entering guests
- flushL1DataCache = "always";
- };
-
- auditd.enable = true;
- audit = {
- enable = true;
- rules = [
- "-a exit,always -F arch=b64 -S execve"
- ];
- };
-
- pam = {
- loginLimits = [
- {
- domain = "@wheel";
- item = "nofile";
- type = "soft";
- value = "524288";
- }
- {
- domain = "@wheel";
- item = "nofile";
- type = "hard";
- value = "1048576";
- }
- ];
-
- services = {
- swaylock.text = "auth include login";
- gtklock.text = "auth include login";
- };
- };
-
- sudo = {
- wheelNeedsPassword = false;
- enable = mkDefault true;
- execWheelOnly = true;
- extraConfig = ''
- # rollback results in sudo lectures after each reboot
- Defaults lecture = never
- Defaults pwfeedback
- Defaults env_keep += "EDITOR PATH"
- Defaults timestamp_timeout = 300
- Defaults passprompt="[31m sudo: password for %p@%h, running as %U:[0m "
- '';
- };
- };
-
- boot.kernel.sysctl = {
- # The Magic SysRq key is a key combo that allows users connected to the
- # system console of a Linux kernel to perform some low-level commands.
- # Disable it, since we don't need it, and is a potential security concern.
- "kernel.sysrq" = 0;
- # Restrict ptrace() usage to processes with a pre-defined relationship
- # (e.g., parent/child)
- "kernel.yama.ptrace_scope" = 2;
- # Hide kptrs even for processes with CAP_SYSLOG
- "kernel.kptr_restrict" = 2;
- # Disable bpf() JIT (to eliminate spray attacks)
- "net.core.bpf_jit_enable" = false;
- # Disable ftrace debugging
- "kernel.ftrace_enabled" = false;
- };
-
- boot.blacklistedKernelModules =
- [
- # Obscure network protocols
- "ax25"
- "netrom"
- "rose"
- # Old or rare or insufficiently audited filesystems
- "adfs"
- "affs"
- "bfs"
- "befs"
- "cramfs"
- "efs"
- "erofs"
- "exofs"
- "freevxfs"
- "f2fs"
- "vivid"
- "gfs2"
- "ksmbd"
- "nfsv4"
- "nfsv3"
- "nfs"
- "cramfs"
- "freevxfs"
- "jffs2"
- "hfs"
- "hfsplus"
- "squashfs"
- "udf"
- "hpfs"
- "jfs"
- "minix"
- "nilfs2"
- "omfs"
- "qnx4"
- "qnx6"
- "sysv"
- ]
- ++ lib.optionals (!sys.security.fixWebcam) [
- "uvcvideo" # this is why your webcam no worky
- ]
- ++ lib.optionals (!sys.bluetooth.enable) [
- "btusb" # let bluetooth dongles work
- ]
- ++ lib.optionals (!config.modules.services.smb.enable) [
- "cifs" # allows smb to work
- ];
-}
diff --git a/modules/common/core/system/os/services/default.nix b/modules/common/core/system/os/services/default.nix
index ea07d7c0a..bcee7a383 100644
--- a/modules/common/core/system/os/services/default.nix
+++ b/modules/common/core/system/os/services/default.nix
@@ -1,6 +1,7 @@
{
config,
inputs,
+ lib,
...
}: {
imports = [
@@ -11,14 +12,12 @@
vscode-server.enable = config.modules.services.vscode-server.enable;
# monitor and control temparature
thermald.enable = true;
- # handle ACPI events
- acpid.enable = true;
# discard blocks that are not in use by the filesystem, good for SSDs
fstrim.enable = true;
# firmware updater for machine hardware
fwupd.enable = true;
- # I don't use lvm, can be disabled
- lvm.enable = false;
+ # Not using lvm
+ lvm.enable = lib.mkDefault false;
# enable smartd monitoering
smartd.enable = true;
# limit systemd journal size
diff --git a/modules/common/core/system/os/services/systemd.nix b/modules/common/core/system/os/services/systemd.nix
index 404bfd3d0..91f856b7e 100644
--- a/modules/common/core/system/os/services/systemd.nix
+++ b/modules/common/core/system/os/services/systemd.nix
@@ -16,7 +16,6 @@
}
// lib.optionalAttrs config.security.auditd.enable {
# a systemd timer to clean /var/log/audit.log daily
- # this can probably be weekly, but daily means we get to clean it every 2-3 days instead of once a week
timers."clean-audit-log" = {
description = "Periodically clean audit log";
wantedBy = ["timers.target"];
diff --git a/modules/common/core/system/os/users/isabel.nix b/modules/common/core/system/os/users/isabel.nix
index 65b2bc8a5..44b168794 100644
--- a/modules/common/core/system/os/users/isabel.nix
+++ b/modules/common/core/system/os/users/isabel.nix
@@ -5,7 +5,7 @@
...
}: let
keys = [
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3AeKdY2eQmK78Ll3bms8yxmqe7BPWMph+QLZ2Fy33XGVDyxTSAK3LJWwfEmjEoQE/4UiFxnrzslrIsIuRYV//tV+aPfmyoBkAxbaWaJ3aujZYGpxD86MtnFwdfNRcl2fKJnTbPSAY0VM5p08A/eNe40WVwXAbXFHyJLbMn5Se1WGuZrWOtoD9reVjRNOh1EkpZVrbjv3rWpK4SDcJCdA9dGxxVXMsy7ErIOzit/g/4IQ+F8zEQRRbSToZYCU2+bFQP5Y1ujPMCxwtYfNEq0rrvgI73ejwhJAdjRHoKv2q8qN9HzYLm3nVipcj6mpV9T3ENHpKuyz1oB735lUh7vcJzu+cgix91RO3bKUtQ0yaUc1nogf8pceGTCbByHxy0qeNy9IgXfW1ZMJ7H1GttzUIsa4q1HLmj1MfbSvbdP4uU+gLflZgm1/9+N0IA4md4Ljpwgik9CsaVucaC/0vPnzASVTrvpMDNu/TlKLytdLKpbQ6Yk1YZPvUbVUZ3xfvJOE= isabel"
+ ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQDiHbMSinj8twL9cTgPOfI6OMexrTZyHX27T8gnMj2 isabel@isabelroses.com''
];
in {
boot.initrd.network.ssh.authorizedKeys = keys;
diff --git a/modules/common/core/system/os/users/root.nix b/modules/common/core/system/os/users/root.nix
index 7a8b9b2f3..672bcefa2 100644
--- a/modules/common/core/system/os/users/root.nix
+++ b/modules/common/core/system/os/users/root.nix
@@ -1,5 +1,9 @@
_: {
users.users.root = {
initialPassword = "changeme";
+
+ openssh.authorizedKeys.keys = [
+ ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQDiHbMSinj8twL9cTgPOfI6OMexrTZyHX27T8gnMj2''
+ ];
};
}
diff --git a/modules/common/core/system/security/auditd.nix b/modules/common/core/system/security/auditd.nix
new file mode 100644
index 000000000..974b8daeb
--- /dev/null
+++ b/modules/common/core/system/security/auditd.nix
@@ -0,0 +1,16 @@
+{config, ...}: let
+ cfg = config.modules.system.security;
+in {
+ security = {
+ # system audit
+ auditd.enable = cfg.auditd.enable;
+ audit = {
+ enable = cfg.auditd.enable;
+ backlogLimit = 8192;
+ failureMode = "printk";
+ rules = [
+ "-a exit,always -F arch=b64 -S execve"
+ ];
+ };
+ };
+}
diff --git a/modules/common/core/system/security/clamav.nix b/modules/common/core/system/security/clamav.nix
new file mode 100644
index 000000000..d52cc36ed
--- /dev/null
+++ b/modules/common/core/system/security/clamav.nix
@@ -0,0 +1,77 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ sys = config.modules.system;
+in {
+ config = mkIf sys.security.clamav.enable {
+ services.clamav = {
+ daemon = {enable = true;} // sys.security.clamav.daemon;
+ updater = {enable = true;} // sys.security.clamav.updater;
+ };
+
+ systemd = {
+ tmpfiles.rules = [
+ "D /var/lib/clamav 755 clamav clamav"
+ ];
+
+ services = {
+ clamav-daemon = {
+ serviceConfig = {
+ PrivateTmp = lib.mkForce "no";
+ PrivateNetwork = lib.mkForce "no";
+ Restart = "always";
+ };
+
+ unitConfig = {
+ # only start clamav when required database files are present
+ # especially useful if you are deploying headlessly and don't want a service fail instantly
+ ConditionPathExistsGlob = [
+ "/var/lib/clamav/main.{c[vl]d,inc}"
+ "/var/lib/clamav/daily.{c[vl]d,inc}"
+ ];
+ };
+ };
+
+ clamav-init-database = {
+ wantedBy = ["clamav-daemon.service"];
+ before = ["clamav-daemon.service"];
+ serviceConfig.ExecStart = "systemctl start clamav-freshclam";
+ unitConfig = {
+ # opposite condition of clamav-daemon: only run this service if
+ # database files are not present in the database directory
+ ConditionPathExistsGlob = [
+ "!/var/lib/clamav/main.{c[vl]d,inc}"
+ "!/var/lib/clamav/daily.{c[vl]d,inc}"
+ ];
+ };
+ };
+
+ clamav-freshclam = {
+ wants = ["clamav-daemon.service"];
+ serviceConfig = {
+ ExecStart = let
+ message = "Updating ClamAV database";
+ in ''
+ ${pkgs.coreutils}/bin/echo -en ${message}
+ '';
+ SuccessExitStatus = lib.mkForce [11 40 50 51 52 53 54 55 56 57 58 59 60 61 62];
+ };
+ };
+ };
+
+ timers.clamav-freshclam.timerConfig = {
+ # the default is to run the timer hourly but we do not want our entire infra to be overloaded
+ # trying to run clamscan at the same time. randomize the timer to something around an hour
+ # so that the window is consistent, but the load is not
+ RandomizedDelaySec = "60m";
+ FixedRandomDelay = true;
+ Persistent = true;
+ };
+ };
+ };
+}
diff --git a/modules/common/core/system/security/default.nix b/modules/common/core/system/security/default.nix
new file mode 100644
index 000000000..d6425872a
--- /dev/null
+++ b/modules/common/core/system/security/default.nix
@@ -0,0 +1,11 @@
+_: {
+ imports = [
+ ./auditd.nix # auditd
+ ./clamav.nix # clamav antivirus
+ ./kernel.nix # kernel hardening
+ ./pam.nix # pam configuration
+ ./polkit.nix # polkit configuration
+ ./sudo.nix # sudo rules and configuration
+ ./virtualization.nix # hypervisor hardening
+ ];
+}
diff --git a/modules/common/core/system/security/kernel.nix b/modules/common/core/system/security/kernel.nix
new file mode 100644
index 000000000..3c2ca6393
--- /dev/null
+++ b/modules/common/core/system/security/kernel.nix
@@ -0,0 +1,142 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ sys = config.modules.system;
+ inherit (lib) optionals concatLists;
+in {
+ security = {
+ protectKernelImage = true;
+ lockKernelModules = false; # breaks virtd, wireguard and iptables
+
+ # force-enable the Page Table Isolation (PTI) Linux kernel feature
+ forcePageTableIsolation = true;
+
+ # User namespaces are required for sandboxing.
+ allowUserNamespaces = true;
+
+ # Disable unprivileged user namespaces, unless containers are enabled
+ unprivilegedUsernsClone = config.virtualisation.containers.enable;
+
+ # apparmor configuration
+ apparmor = {
+ enable = true;
+ killUnconfinedConfinables = true;
+ packages = [pkgs.apparmor-profiles];
+ };
+ };
+
+ boot = {
+ kernel.sysctl = {
+ # The Magic SysRq key is a key combo that allows users connected to the
+ # system console of a Linux kernel to perform some low-level commands.
+ # Disable it, since we don't need it, and is a potential security concern.
+ "kernel.sysrq" = 0;
+ # Restrict ptrace() usage to processes with a pre-defined relationship
+ # (e.g., parent/child)
+ "kernel.yama.ptrace_scope" = 2;
+ # Hide kptrs even for processes with CAP_SYSLOG
+ "kernel.kptr_restrict" = 2;
+ # Disable bpf() JIT (to eliminate spray attacks)
+ "net.core.bpf_jit_enable" = false;
+ # Disable ftrace debugging
+ "kernel.ftrace_enabled" = false;
+ # Avoid kernel memory address exposures via dmesg (this value can also be set by CONFIG_SECURITY_DMESG_RESTRICT).
+ "kernel.dmesg_restrict" = 1;
+ };
+
+ # https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
+ kernelParams = [
+ # make stack-based attacks on the kernel harder
+ "randomize_kstack_offset=on"
+
+ # controls the behavior of vsyscalls. this has been defaulted to none back in 2016 - break really old binaries for security
+ "vsyscall=none"
+
+ # reduce most of the exposure of a heap attack to a single cache
+ "slab_nomerge"
+
+ # only allow signed modules
+ "module.sig_enforce=1"
+
+ # blocks access to all kernel memory, even preventing administrators from being able to inspect and probe the kernel
+ "lockdown=confidentiality"
+
+ # enable buddy allocator free poisoning
+ "page_poison=1"
+
+ # performance improvement for direct-mapped memory-side-cache utilization, reduces the predictability of page allocations
+ "page_alloc.shuffle=1"
+
+ # for debugging kernel-level slab issues
+ "slub_debug=FZP"
+
+ # disable sysrq keys. sysrq is seful for debugging, but also insecure
+ "sysrq_always_enabled=0" # 0 | 1 # 0 means disabled
+
+ # ignore access time (atime) updates on files, except when they coincide with updates to the ctime or mtime
+ "rootflags=noatime"
+
+ # linux security modules
+ "lsm=landlock,lockdown,yama,apparmor,bpf"
+
+ # prevent the kernel from blanking plymouth out of the fb
+ "fbcon=nodefer"
+ ];
+
+ blacklistedKernelModules = concatLists [
+ [
+ # Obscure network protocols
+ "ax25"
+ "netrom"
+ "rose"
+ ]
+ [
+ # Old or rare or insufficiently audited filesystems
+ "adfs"
+ "affs"
+ "bfs"
+ "befs"
+ "cramfs"
+ "efs"
+ "erofs"
+ "exofs"
+ "freevxfs"
+ "f2fs"
+ "vivid"
+ "gfs2"
+ "ksmbd"
+ "nfsv4"
+ "nfsv3"
+ "cifs"
+ "nfs"
+ "cramfs"
+ "freevxfs"
+ "jffs2"
+ "hfs"
+ "hfsplus"
+ "squashfs"
+ "udf"
+ "hpfs"
+ "jfs"
+ "minix"
+ "nilfs2"
+ "omfs"
+ "qnx4"
+ "qnx6"
+ "sysv"
+ ]
+ (optionals (!sys.security.fixWebcam) [
+ "uvcvideo" # this is why your webcam no worky
+ ])
+ (optionals (!sys.bluetooth.enable) [
+ "btusb" # let bluetooth dongles work
+ ])
+ (optionals (!config.modules.services.smb.enable) [
+ "cifs" # allows smb to work
+ ])
+ ];
+ };
+}
diff --git a/modules/common/core/system/security/pam.nix b/modules/common/core/system/security/pam.nix
new file mode 100644
index 000000000..c80560e98
--- /dev/null
+++ b/modules/common/core/system/security/pam.nix
@@ -0,0 +1,29 @@
+_: {
+ security = {
+ pam = {
+ # fix "too many files open" errors while writing a lot of data at once
+ # was previously a huge issue when rebuilding
+ loginLimits = [
+ {
+ domain = "@wheel";
+ item = "nofile";
+ type = "soft";
+ value = "524288";
+ }
+ {
+ domain = "@wheel";
+ item = "nofile";
+ type = "hard";
+ value = "1048576";
+ }
+ ];
+
+ # allow screen lockers to also unlock the screen
+ # (e.g. swaylock, gtklock)
+ services = {
+ swaylock.text = "auth include login";
+ gtklock.text = "auth include login";
+ };
+ };
+ };
+}
diff --git a/modules/common/core/system/security/polkit.nix b/modules/common/core/system/security/polkit.nix
new file mode 100644
index 000000000..5d9c7a053
--- /dev/null
+++ b/modules/common/core/system/security/polkit.nix
@@ -0,0 +1,20 @@
+{
+ config,
+ lib,
+ ...
+}: {
+ # have polkit log all actions
+ security.polkit = {
+ enable = true;
+ debug = lib.mkDefault true;
+
+ # the below configuration depends on security.polkit.debug being set to true
+ # so we have it written only if debugging is enabled
+ extraConfig = lib.mkIf config.security.polkit.debug ''
+ /* Log authorization checks. */
+ polkit.addRule(function(action, subject) {
+ polkit.log("user " + subject.user + " is attempting action " + action.id + " from PID " + subject.pid);
+ });
+ '';
+ };
+}
diff --git a/modules/common/core/system/security/sudo.nix b/modules/common/core/system/security/sudo.nix
new file mode 100644
index 000000000..b15c9ebd7
--- /dev/null
+++ b/modules/common/core/system/security/sudo.nix
@@ -0,0 +1,68 @@
+{
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkDefault;
+in {
+ security = {
+ # sudo-rs is still a feature-incomplete sudo fork that can and will mess things up
+ sudo-rs.enable = lib.mkForce false;
+
+ sudo = {
+ enable = true;
+
+ # wheelNeedsPassword = false means wheel group can execute commands without a password
+ # so just disable it, it only hurt security, BUT ... see below what commands can be run without password
+ wheelNeedsPassword = mkDefault false;
+
+ # only allow members of the wheel group to execute sudo
+ execWheelOnly = true;
+
+ # i dont like lectures
+ extraConfig = ''
+ Defaults lecture = never
+ Defaults pwfeedback
+ Defaults env_keep += "EDITOR PATH DISPLAY"
+ Defaults timestamp_timeout = 300
+ '';
+
+ extraRules = [
+ {
+ # allow wheel group to run nixos-rebuild without password
+ groups = ["sudo" "wheel"];
+ commands = let
+ currentSystem = "/run/current-system/";
+ storePath = "/nix/store/";
+ in [
+ {
+ command = "${storePath}/*/bin/switch-to-configuration";
+ options = ["SETENV" "NOPASSWD"];
+ }
+ {
+ command = "${currentSystem}/sw/bin/nix-store";
+ options = ["SETENV" "NOPASSWD"];
+ }
+ {
+ command = "${currentSystem}/sw/bin/nix-env";
+ options = ["SETENV" "NOPASSWD"];
+ }
+ {
+ # let wheel group collect garbage without password
+ command = "${currentSystem}/sw/bin/nix-collect-garbage";
+ options = ["SETENV" "NOPASSWD"];
+ }
+ {
+ command = "${pkgs.nixos-rebuild}/bin/nixos-rebuild";
+ options = ["SETENV" "NOPASSWD"];
+ }
+ {
+ command = "/nix/var/nix/profiles/system/specialisation/*/bin/switch-to-configuration";
+ options = ["SETENV" "NOPASSWD"];
+ }
+ ];
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/common/core/system/security/virtualization.nix b/modules/common/core/system/security/virtualization.nix
new file mode 100644
index 000000000..f3e3107ea
--- /dev/null
+++ b/modules/common/core/system/security/virtualization.nix
@@ -0,0 +1,6 @@
+_: {
+ security.virtualisation = {
+ # flush the L1 data cache before entering guests
+ flushL1DataCache = "always";
+ };
+}
diff --git a/modules/common/core/system/smb/default.nix b/modules/common/core/system/smb/default.nix
index 64ed5ec6b..b53a14e84 100644
--- a/modules/common/core/system/smb/default.nix
+++ b/modules/common/core/system/smb/default.nix
@@ -9,7 +9,6 @@ with lib; let
in {
imports = [
./recive
- ./host
];
config = mkIf (smb.enable) {
diff --git a/modules/common/core/system/smb/host/default.nix b/modules/common/core/system/smb/host/default.nix
deleted file mode 100644
index 0967ef424..000000000
--- a/modules/common/core/system/smb/host/default.nix
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/modules/common/core/system/virtualization/default.nix b/modules/common/core/system/virtualization/default.nix
index 742f62f16..dfaad8cf7 100644
--- a/modules/common/core/system/virtualization/default.nix
+++ b/modules/common/core/system/virtualization/default.nix
@@ -3,30 +3,39 @@
config,
pkgs,
...
-}:
-with lib; let
- sys = config.modules.system.virtualization;
+}: let
+ inherit (lib) optionals mkIf concatLists;
+ sys = config.modules.system;
+ cfg = sys.virtualization;
in {
- config = mkIf sys.enable {
+ config = mkIf cfg.enable {
environment.systemPackages = with pkgs;
- []
- ++ optionals sys.qemu.enable [
- virt-manager
- virt-viewer
- ]
- ++ optionals sys.docker.enable [
- docker
- docker-compose
- ]
- ++ optionals sys.distrobox.enable [
- distrobox
- ]
- ++ optionals sys.waydroid.enable [
- waydroid
+ concatLists [
+ (optionals cfg.qemu.enable [
+ virt-manager
+ virt-viewer
+ ])
+ (optionals cfg.docker.enable [
+ podman
+ podman-compose
+ ])
+ (optionals (cfg.docker.enable && sys.video.enable) [
+ lxd
+ ])
+ (optionals cfg.distrobox.enable [
+ distrobox
+ ])
+ (optionals cfg.waydroid.enable [
+ waydroid
+ ])
];
- virtualisation = mkIf sys.enable {
- libvirtd = {
+ virtualisation = {
+ # qemu
+ kvmgt.enable = true;
+ spiceUSBRedirection.enable = true;
+
+ libvirtd = mkIf cfg.qemu.enable {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
@@ -38,17 +47,45 @@ in {
};
};
- docker = mkIf sys.docker.enable {
+ # podman
+ podman = mkIf (cfg.docker.enable || cfg.podman.enable) {
enable = true;
-
+ dockerCompat = true;
+ dockerSocket.enable = true;
+ defaultNetwork.settings = {
+ dns_enabled = true;
+ };
enableNvidia = builtins.any (driver: driver == "nvidia") config.services.xserver.videoDrivers;
-
autoPrune = {
enable = true;
flags = ["--all"];
dates = "weekly";
};
};
+
+ waydroid.enable = cfg.waydroid.enable;
+ lxd.enable = cfg.waydroid.enable;
+ };
+ systemd.user = mkIf cfg.distrobox.enable {
+ timers."distrobox-update" = {
+ enable = true;
+ wantedBy = ["timers.target"];
+ timerConfig = {
+ OnBootSec = "1h";
+ OnUnitActiveSec = "1d";
+ Unit = "distrobox-update.service";
+ };
+ };
+
+ services."distrobox-update" = {
+ enable = true;
+ script = ''
+ ${pkgs.distrobox}/bin/distrobox upgrade --all
+ '';
+ serviceConfig = {
+ Type = "oneshot";
+ };
+ };
};
};
}
diff --git a/modules/common/options/device/default.nix b/modules/common/options/device/default.nix
deleted file mode 100644
index 60e8d34b1..000000000
--- a/modules/common/options/device/default.nix
+++ /dev/null
@@ -1,53 +0,0 @@
-{lib, ...}:
-with lib; {
- options.modules.device = {
- type = mkOption {
- type = types.enum ["laptop" "desktop" "server" "hybrid" "lite" "vm"];
- default = null;
- };
-
- # the type of cpu your system has - vm and regular cpus currently do not differ
- # as I do not work with vms, but they have been added for forward-compatibility
- cpu = mkOption {
- type = types.enum ["pi" "intel" "vm-intel" "amd" "vm-amd" null];
- default = null;
- };
-
- gpu = mkOption {
- type = types.enum ["amd" "intel" "nvidia" null];
- default = null;
- description = "the manifacturer/type of the primary system gpu";
- };
-
- hasTPM = mkEnableOption "Whether the system has tpm support";
-
- monitors = mkOption {
- type = with types; listOf str;
- default = [];
- description = ''
- this does not affect any drivers and such, it is only necessary for
- declaring things like monitors in window manager configurations
- you can avoid declaring this, but I'd rather if you did declare
- '';
- };
-
- # bluetooth is an insecure protocol if left unchedked, so while this defaults to true
- # but the bluetooth.enable option does and should not.
- hasBluetooth = mkOption {
- type = types.bool;
- default = true;
- description = "Whether or not the system has bluetooth support";
- };
-
- hasSound = mkOption {
- type = types.bool;
- default = true;
- description = "Whether the system has sound support (usually true except for servers)";
- };
-
- keyboard = mkOption {
- type = types.enum ["us" "gb"];
- default = "gb";
- };
- };
-}
diff --git a/modules/common/options/programs/default.nix b/modules/common/options/programs/default.nix
deleted file mode 100644
index 4715b8dbb..000000000
--- a/modules/common/options/programs/default.nix
+++ /dev/null
@@ -1,91 +0,0 @@
-{lib, ...}:
-with lib; {
- imports = [./services.nix];
- # this module provides overrides for certain defaults and lets you set
- # default programs for referencing in other config files.
- options.modules = {
- programs = {
- # "override" is a simple option that sets the programs' state to the oppossite of their default
- override = {
- # override basic desktop applications
- # an example override for the libreoffice program
- # if set to true, libreoffice module will not be enabled as it is by default
- libreoffice = mkEnableOption "Override Libreoffice suite";
- };
-
- # TODO: turn those into overrides
- # load GUI and CLI programs by default, but check if those overrides are enabled
- # so that they can be disabled at will
- cli = {
- enable = mkEnableOption "Enable CLI programs";
- };
- tui = {
- enable = mkEnableOption "Enable TUI programs";
- };
- gui = {
- enable = mkEnableOption "Enable GUI programs";
- };
-
- gaming = {
- enable = mkEnableOption "Enable packages required for the device to be gaming-ready";
- gamescope.enable = mkEnableOption "Gamescope compositing manager" // {default = config.modules.programs.gaming.enable;};
- };
-
- git = {
- signingKey = mkOption {
- type = types.str;
- default = "";
- description = "The default gpg key used for signing commits";
- };
- };
-
- nur = {
- enable = mkEnableOption "Use nur for extra packages";
- bella = mkEnableOption "Enable the isabelroses nur extra packages";
- nekowinston = mkEnableOption "Enables the nekowinston nur extra packages";
- };
-
- # default program options
- default = {
- # what program should be used as the default terminal
- terminal = mkOption {
- type = types.enum ["alacritty" "kitty" "wezterm" "foot"];
- default = "kitty";
- };
-
- fileManager = mkOption {
- type = types.enum ["thunar" "dolphin" "nemo"];
- default = "thunar";
- };
-
- browser = mkOption {
- type = types.enum ["firefox" "chromium"];
- default = "chromium";
- };
-
- editor = mkOption {
- type = types.enum ["nvim" "codium"];
- default = "nvim";
- };
-
- launcher = mkOption {
- type = types.enum ["rofi" "wofi"];
- default = "rofi";
- };
-
- bar = mkOption {
- type = types.enum ["eww" "waybar" "ags"];
- default = "eww";
- };
-
- screenLock = mkOption {
- type = with types; nullOr (enum ["swaylock" "gtklock"]);
- default = "gtklock";
- description = lib.mdDoc ''
- The lockscreen module to be loaded by home-manager.
- '';
- };
- };
- };
- };
-}
diff --git a/modules/common/options/programs/services.nix b/modules/common/options/programs/services.nix
deleted file mode 100644
index 3bc5a4522..000000000
--- a/modules/common/options/programs/services.nix
+++ /dev/null
@@ -1,43 +0,0 @@
-{lib, ...}:
-with lib; {
- options.modules.services = {
- smb = {
- enable = mkEnableOption "Enables smb shares";
- host.enable = mkEnableOption "Enables hosting of smb shares";
-
- # should smb shares be enabled as a recpient machine
- recive = {
- general = mkEnableOption "genral share";
- media = mkEnableOption "media share";
- };
- };
-
- jellyfin = {
- enable = mkEnableOption "Enables the jellyfin service";
- asDockerContainer = mkEnableOption "Enables the service as a docker container";
- };
-
- cloudflare = {
- enable = mkEnableOption "Enables cloudflared tunnels";
- id = mkOption {
- type = types.str;
- default = "";
- description = "The cloudflared tunnel id";
- };
- };
-
- mailserver.enable = mkEnableOption "Enable the mailserver service";
-
- gitea.enable = mkEnableOption "Enable the gitea service";
-
- vaultwarden.enable = mkEnableOption "Enable the vaultwarden service";
-
- photoprism.enable = mkEnableOption "Enable the photoprism service";
-
- vscode-server.enable = mkEnableOption "Enables remote ssh vscode server";
-
- isabelroses-web.enable = mkEnableOption "Enables my website";
-
- searxng.enable = mkEnableOption "Enables searxng search engine service";
- };
-}
diff --git a/modules/common/options/system/activation.nix b/modules/common/options/system/activation.nix
deleted file mode 100644
index 93647096c..000000000
--- a/modules/common/options/system/activation.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{lib, ...}: let
- inherit (lib) mkEnableOption;
-in {
- options.modules.system.activation = {
- diffGenerations = mkEnableOption "diff view between rebuilds";
- };
-}
diff --git a/modules/common/options/system/boot.nix b/modules/common/options/system/boot.nix
deleted file mode 100644
index 716b0e0ea..000000000
--- a/modules/common/options/system/boot.nix
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- lib,
- pkgs,
- ...
-}:
-with lib; {
- options.modules.system.boot = {
- enableKernelTweaks = mkEnableOption "security and performance related kernel parameters";
- enableInitrdTweaks = mkEnableOption "quality of life tweaks for the initrd stage";
- recommendedLoaderConfig = mkEnableOption "tweaks for common bootloader configs per my liking";
- loadRecommendedModules = mkEnableOption "kernel modules that accommodate for most use cases";
-
- extraKernelParams = mkOption {
- type = with types; listOf str;
- default = [];
- };
-
- kernel = mkOption {
- type = types.raw;
- default = pkgs.linuxPackages_latest;
- };
-
- # the bootloader that should be used
- loader = mkOption {
- type = types.enum ["none" "grub" "systemd-boot"];
- default = "none";
- description = "The bootloader that should be used for the device.";
- };
-
- device = mkOption {
- type = with types; nullOr str;
- default = "nodev";
- description = "The device to install the bootloader to.";
- };
-
- plymouth = {
- enable = mkEnableOption "plymouth boot splash";
- withThemes = mkEnableOption "plymouth theme";
- };
-
- memtest = {
- enable = mkEnableOption "memtest86+";
- package = mkOption {
- type = types.package;
- default = pkgs.memtest86plus;
- description = "The memtest package to use.";
- };
- };
- };
-}
diff --git a/modules/common/options/system/default.nix b/modules/common/options/system/default.nix
deleted file mode 100644
index ca998407b..000000000
--- a/modules/common/options/system/default.nix
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- lib,
- config,
- ...
-}:
-with lib; {
- imports = [
- ./activation.nix
- ./boot.nix
- ./networking.nix
- ./security.nix
- ./virtualization.nix
- ];
-
- options.modules.system = {
- # the default user (not users) you plan to use on a specific device
- # this will dictate the initial home-manager settings if home-manager is
- # enabled in usrenv
- users = mkOption {
- type = with types; listOf str;
- default = ["isabel"];
- description = "The users of your system";
- };
-
- mainUser = mkOption {
- type = types.enum config.modules.system.users;
- description = "The username of the main user for your system";
- default = builtins.elemAt config.modules.system.users 0;
- };
-
- hostname = mkOption {
- type = types.str;
- description = "The name of the device for the system";
- };
-
- # the path to the flake
- flakePath = mkOption {
- type = types.str;
- default = "/home/isabel/.setup";
- description = "The path to the configuration";
- };
-
- # should sound related programs and audio-dependent programs be enabled
- sound = {
- enable = mkEnableOption "sound";
- };
-
- # should the device enable graphical programs
- video = {
- enable = mkEnableOption "video";
- };
-
- # should the device load bluetooth drivers and enable blueman
- bluetooth = {
- enable = mkEnableOption "bluetooth";
- };
-
- # should the device enable printing module and try to load common printer modules
- # you might need to add more drivers to the printing module for your printer to work
- printing = {
- enable = mkEnableOption "printing";
- };
- };
-}
diff --git a/modules/common/options/system/security.nix b/modules/common/options/system/security.nix
deleted file mode 100644
index f974aaec0..000000000
--- a/modules/common/options/system/security.nix
+++ /dev/null
@@ -1,8 +0,0 @@
-{lib, ...}:
-with lib; {
- # should we optimize tcp networking
- options.modules.system.security = {
- fixWebcam = mkEnableOption "Fix the purposefully broken webcam by un-blacklisting the related kernel module.";
- secureBoot = mkEnableOption "Enable secure-boot and load necessary packages.";
- };
-}
diff --git a/modules/common/options/themes/default.nix b/modules/common/options/themes/default.nix
deleted file mode 100644
index 7987ff8f1..000000000
--- a/modules/common/options/themes/default.nix
+++ /dev/null
@@ -1,139 +0,0 @@
-{
- lib,
- pkgs,
- config,
- ...
-}: let
- inherit (lib) mkOption mkEnableOption types mdDoc;
- cfg = config.modules.style;
-in {
- options = {
- modules = {
- style = {
- forceGtk = mkEnableOption "Force GTK applications to use the GTK theme";
- useKvantum = mkEnableOption "Use Kvantum to theme QT applications";
-
- # choose a colorscheme
- colorScheme = {
- # "Name Of The Scheme"
- name = mkOption {
- type = with types; nullOr (enum ["Catppuccin Mocha" "Tokyo Night"]);
- description = "The colorscheme that should be used globally to theme your system.";
- default = "Catppuccin Mocha";
- };
-
- # "name-of-the-scheme"
- slug = mkOption {
- type = types.str;
- default = lib.serializeTheme "${cfg.colorScheme.name}";
- description = mdDoc ''
- The serialized slug for the colorScheme you are using. Defaults to a lowercased version of the theme name with spaces
- replaced with hyphens. Only change if the slug is expected to be different."
- '';
- };
- };
-
- pointerCursor = {
- package = mkOption {
- type = types.package;
- description = "The package providing the cursors";
- default = pkgs.catppuccin-cursors.mochaDark;
- };
-
- name = mkOption {
- type = types.str;
- description = "The name of the cursor inside the package";
- default = "Catppuccin-Mocha-Dark-Cursors";
- };
-
- size = mkOption {
- type = types.int;
- description = "The size of the cursor";
- default = 24;
- };
- };
-
- # qt specific options
- qt = {
- theme = {
- package = mkOption {
- type = types.package;
- default = pkgs.catppuccin-kde.override {
- flavour = ["mocha"];
- accents = ["sapphire"];
- winDecStyles = ["modern"];
- };
- description = "The theme package to be used for QT programs";
- };
- name = mkOption {
- type = types.str;
- default = "Catppuccin-Mocha-Dark";
- description = "The name for the QT theme package";
- };
- };
-
- kdeglobals.source = mkOption {
- type = types.path;
- default = "${cfg.qt.theme.package}/share/color-schemes/CatppuccinMochaSapphire.colors";
- };
- };
-
- # gtk specific options
- gtk = {
- usePortal = mkEnableOption "native desktop portal use for filepickers";
-
- theme = {
- name = mkOption {
- type = types.str;
- default = "Catppuccin-Mocha-Standard-Sapphire-dark";
- description = "The name for the GTK theme package";
- };
-
- package = mkOption {
- type = types.package;
- description = "The theme package to be used for GTK programs";
- default = pkgs.catppuccin-gtk.override {
- size = "standard";
- accents = ["sapphire"];
- variant = "mocha";
- tweaks = ["normal"];
- };
- };
- };
-
- iconTheme = {
- name = mkOption {
- type = types.str;
- description = "The name for the icon theme that will be used for GTK programs";
-
- default = "Papirus-Dark";
- };
-
- package = mkOption {
- type = types.package;
- description = "The GTK icon theme to be used";
- default = pkgs.catppuccin-papirus-folders.override {
- accent = "sapphire";
- flavor = "mocha";
- };
- };
- };
-
- font = {
- name = mkOption {
- type = types.str;
- description = "The name of the font that will be used for GTK applications";
- default = "RobotoMono Nerd Font";
- };
-
- size = mkOption {
- type = types.int;
- description = "The size of the font";
- default = 13;
- };
- };
- };
- };
- };
- };
-}
diff --git a/modules/common/secrets/default.nix b/modules/common/secrets/default.nix
index d93d365f7..8dca4b139 100644
--- a/modules/common/secrets/default.nix
+++ b/modules/common/secrets/default.nix
@@ -1,9 +1,13 @@
{
config,
pkgs,
+ lib,
inputs,
...
-}: {
+}: let
+ inherit (lib) mkIf;
+ inherit (config.modules) services;
+in {
imports = [inputs.sops.nixosModules.sops];
environment.systemPackages = with pkgs; [sops age];
@@ -14,30 +18,71 @@
age.keyFile = "/home/${config.modules.system.mainUser}/.config/sops/age/keys.txt";
secrets = let
- mainUser = config.modules.system.mainUser;
+ inherit (config.modules.system) mainUser;
homeDir = config.home-manager.users.${mainUser}.home.homeDirectory;
sshDir = homeDir + "/.ssh";
-
- ### servers ###
- secretsPath = "/run/secrets.d/";
- mailserverPath = secretsPath + "/mailserver";
in {
- ### server ###
- cloudflared-hydra = {
- #path = secretsPath + "/cloudflared/hydra";
- owner = mainUser;
+ # server
+ cloudflared-hydra = mkIf services.cloudflared.enable {
+ owner = "cloudflared";
group = "cloudflared";
};
# mailserver
- mailserver-isabel.path = mailserverPath + "/isabel";
- mailserver-gitea.path = mailserverPath + "/gitea";
- mailserver-vaultwarden.path = mailserverPath + "/vaultwarden";
+ rspamd-web = {};
+ mailserver-isabel = {};
+ mailserver-vaultwarden = {};
+ mailserver-database = {};
+ mailserver-grafana = {};
+ mailserver-git = {};
+ mailserver-noreply = {};
+ mailserver-spam = {};
+
+ mailserver-grafana-nohash = mkIf services.monitoring.grafana.enable {
+ owner = "grafana";
+ group = "grafana";
+ };
+
+ mailserver-git-nohash = mkIf services.forgejo.enable {
+ owner = "forgejo";
+ group = "forgejo";
+ };
+
+ isabelroses-web-env = {};
+
+ nextcloud-passwd = mkIf services.nextcloud.enable {
+ owner = "nextcloud";
+ group = "nextcloud";
+ };
# vaultwarden
- vaultwarden-env.path = secretsPath + "/vaultwarden/env";
+ vaultwarden-env = {};
+
+ # miniflux
+ miniflux-env = mkIf services.miniflux.enable {
+ owner = "miniflux";
+ group = "miniflux";
+ };
- ### user ###
+ # matrix
+ matrix = mkIf services.matrix.enable {
+ owner = "matrix-synapse";
+ mode = "400";
+ };
+
+ docker-hub = {};
+
+ #wakapi
+ wakapi = mkIf services.wakapi.enable {
+ owner = "wakapi";
+ group = "wakapi";
+ };
+
+ mongodb-passwd = mkIf services.database.mongodb.enable {
+ mode = "400";
+ };
+
+ # user
git-credentials = {
path = homeDir + "/.git-credentials";
owner = mainUser;
@@ -66,11 +111,8 @@
path = sshDir + "/openvpn";
owner = mainUser;
};
- # Luz and Edalyn are now dead replaced by bernie
- #luz-key.path = sshDir + "/luz";
- #edalyn-key.path = sshDir + "/edalyn";
- bernie-key = {
- path = sshDir + "/bernie";
+ amity-key = {
+ path = sshDir + "/amity";
owner = mainUser;
};
king-key = {
@@ -78,21 +120,13 @@
owner = mainUser;
};
- # my local servers / clients
- alpha-key = {
- path = sshDir + "/alpha";
- owner = mainUser;
- };
- alpha-key-pub = {
- path = sshDir + "/alpha.pub";
- owner = mainUser;
- };
- hydra-key = {
- path = sshDir + "/hydra";
+ # All nixos machines
+ nixos-key = {
+ path = sshDir + "/nixos";
owner = mainUser;
};
- hydra-key-pub = {
- path = sshDir + "/hydra.pub";
+ nixos-key-pub = {
+ path = sshDir + "/nixos.pub";
owner = mainUser;
};
};
diff --git a/modules/common/secrets/secrets.yaml b/modules/common/secrets/secrets.yaml
index 6d3f1e385..95069d90b 100644
--- a/modules/common/secrets/secrets.yaml
+++ b/modules/common/secrets/secrets.yaml
@@ -1,22 +1,32 @@
cloudflared-hydra: ENC[AES256_GCM,data:XXOt3t4FgbmSvtBrwPZRo/8xSg2BxUUYs2zAjQ2GuXVNiGEOP3YlJrHipKyS1HddNrTiiff4JkZ44XdknSFY/9HuS3Go3nzW8a9meuT9QYIM8uhu4qZxJp2m/PZirVo4sdB+0X+mkJ2hKaYQv7Y2YbclKbVUIpHR5J6jO0p5FY3ElbIJk9wmzzWfXWhgirWQiOTmqvoj+rSoZwpYePtwoRt/,iv:E7tfKiECbLoXo7z0Y/Cc/BI9jBGzECHWDSbFMKEICbw=,tag:2ptEB9HZQqyDnYnhDA/5Lw==,type:str]
-mailserver-isabel: ENC[AES256_GCM,data:ebjWB7VzqNQJZNd/MYn+zg==,iv:f4KkiKRZp2nDNe8fc3M+pK8jpootv54KryOVOa2hPEo=,tag:80waQs2PAjpQnRDAsyGzAQ==,type:str]
-mailserver-gitea: ENC[AES256_GCM,data:g8MSFZeWnna7nH9pkhAvCnzvRZClW/HNJVPHJQMjovk=,iv:i7yw3l5ABc63jfRZgMAkwFhvfqgckR3DN/fS4z67JfA=,tag:ZTGDQHs/oGQFlbEgsYZ4cQ==,type:str]
-mailserver-vaultwarden: ENC[AES256_GCM,data:B+5hxL+tO6Kpi8sxYtXM7WwOtaKp+sO6MTcqm4hKWbw=,iv:DvdYuisz2C3iy+FEjWVte26XDnH9SBW6EfrgrjBjUqw=,tag:vHzTKGfkNeb8LlgHe6bWnw==,type:str]
-vaultwarden-env: ENC[AES256_GCM,data:AymALRm+yJYvV9QLIuVH38rBQaPOboGOvr9djLJrujjccGKS2yuBxIdBO3N0/jeSIKVgDUuY9YvPuf0qUi4TgPWLCpTTyXvaXAFmKg==,iv:5Y2zwhc8q5L0YOQz73DSTRbvOle1tLy+WKV6+80+aWQ=,tag:Rfwp/BICqycgR/hnxuSyDw==,type:str]
+mailserver-isabel: ENC[AES256_GCM,data:uNP6R523G13QJECxiOvB+VYlQxaoa0s/KHZNqju2vKk8hmwVO15q2bju3ReSLXEdlJgnztHQlYawmGUJlQ==,iv:l0NJJbuGdrZlcj13q3E6hiyZ5CQnzniVEH8wcE/Bm2s=,tag:MoYXL64pBvLH3GbjpNAY0g==,type:str]
+mailserver-git: ENC[AES256_GCM,data:zHazBIRM8nZl0oZtbGaZknetYLpBWpQJ9dGarLeMpN3oGcYvmrNAcRXlEEBLH+6FHZrlpXSutGysn+h1qA==,iv:F6s5GesS9XnvYe3J8n8Ryey3ozAhptLZqUgvaJGVHDk=,tag:kRt+g8jXCSQkGPMUpzUNew==,type:str]
+mailserver-git-nohash: ENC[AES256_GCM,data:xl+iPzMOhI1M04z6v2ZQdqDPR4jnJwklAdqM9VGQ2I/s,iv:1VLO+aPuja5vSWR8iC74T8bvyVx03MYyY19ydO7GAWA=,tag:w9KgfCVyPxD8n5hw6AbILg==,type:str]
+mailserver-grafana: ENC[AES256_GCM,data:8jLMabqJ7TkIOJGzYyBkkt+iyc7nXQOGXP+N7TyfRuEKaU0YP+zoAzSv4jM31wQyjl5/QrMvSwE13AS1Vw==,iv:cjkGDdJvT7DrZSB7htgVLp+TsHyFqX0eeFRjB5lbfPI=,tag:7j0tw/39/Z3tUGci2IKTPw==,type:str]
+mailserver-grafana-nohash: ENC[AES256_GCM,data:SAHerwdB0jFI5PNX5Ot9liqVPl0WQn/ZL1xerzODMjLi,iv:/2L/f9rx8pHRiK/4a7fzPBt6yMIU1yZaz7BO1jiBUq8=,tag:nhCWGLnCwKW/vyOD6dZHbA==,type:str]
+mailserver-vaultwarden: ENC[AES256_GCM,data:/rvxrhm3TZza3dFuz2aFp06W7iDG/whjxreg3+kJuAufIYNS46Hl6pLoZDbKelXFkn+1Ugvykef9DBEL3Q==,iv:ny/H1R7cHKmp3r+4YtFbZbC+1MACn3KVX5ROd80iYKM=,tag:4h7FrCFTRRD7sePfOAzhqw==,type:str]
+mailserver-noreply: ENC[AES256_GCM,data:NgOZ1JI6cXRQG2AH2Rx3zXai/MYtZvrJ7DpwknTTCuPi7bYBwAiRyOBynUltnItjZb/MDmM5tJ6cX30P2g==,iv:F/vkLAbtNVpa2/1o6cz05OFcQnsBFZuZZ8rG4E7gS70=,tag:CX2/7SmiH6qu5i/Oi/hL2A==,type:str]
+mailserver-spam: ENC[AES256_GCM,data:QJKHyzY/GAwsc0sJfoCR7IEJAoakJ5KS94qIbi4fIoH4CqhJ+qjaLLvuI39Mu2Hrp2gCSvfBJ3oQlN5brQ==,iv:Acashw2STfzbzGBaXrFtHwlEc/AqSkBHKYXwVHOKC6Q=,tag:2Z6UXbe4fTxZq095vbKAZA==,type:str]
+mailserver-database: ENC[AES256_GCM,data:HR+U0nieGQjWX9iws2awtw==,iv:+Vc+3xGrZibBXZSBx6REW3u//0tzUi6a8ODNJhngS5w=,tag:oKyi1s7FzLYzEieGzuLR5Q==,type:str]
+rspamd-web: ENC[AES256_GCM,data:jgwF2Pix4QpWGJBKNibPXfh1yfs+5z2oq9XQ1B/C3xZ4BYAQ2aBIZcNoJj1U,iv:8mPIjqC47fX+8Zi5946aLMkGIeTbhVMHSpp7bTx58AA=,tag:e5hYLkgTULd1hJ/XTDwmSg==,type:str]
+nextcloud-passwd: ENC[AES256_GCM,data:2XRFDsIU4D6KgneafD9SurL3pA/9g0RN4egMo209fhnp,iv:aAPGBJDlTeoVHneDiQ2FQAsadzB5uzfdEAf2dG3ubYw=,tag:5n63TU3oor6VEMkRxHIzhg==,type:str]
+vaultwarden-env: ENC[AES256_GCM,data:RZltkcbeTObbSVPIx4x2yP/e6o/WvAuChfmLki8gkX0L5NXYbm3hBOfA1cKMN34git1xNfPyckHm1zV4ZumTfeWtyBOvUZd1TqZxCObh0v67jZUH2pXWybot+LAd+MWf4dYphxiq8/yvvmOwH5WG82HAudOKcnkQ0qDjv47gEbD87IRgeFod3su2h8zd60iMIHTb6G+ErV06XpWizEsnDxWZzpl3k1WO2V30coVY48D/Sh3FQSrEceL4xMBZzRmVhu8Xh3cOqcSejEjS/PkNUYf+7IwDMn5hFXC6/yzgHHva4w==,iv:w6u+8ME93rGbXirMIS/hSSDwiRBKFbSEcLFQjxTHGak=,tag:rDY68+rvgzvVC29Ko+69bw==,type:str]
+isabelroses-web-env: ENC[AES256_GCM,data:pw5+wVbZXkqp4jvUIGqLkiJcbIJ8pMG31Py237TKu3Fml/kYyV5NuvwZIBvvzryTfT1f1ElefVrtaQyEbV1uA5MEZYZ1h4K7Aw3iWWCzZAyMUhEUUJP5ti46YIc6hyaQeuoWkLQkLmHbazg=,iv:Dcsnj6riFUM/CWljcQeMF/YgI2M3uUf/ZFVWpbSxyI0=,tag:JxNh5LESxMtiNaL8mHxL6g==,type:str]
+miniflux-env: ENC[AES256_GCM,data:v7miyr71dg2fcMHKtmBlnlFQXafkfXLQBPOGfIA2EYs8Ew3VzhFMDfPe+zZ6upVACIZlXNcd,iv:s2SQno1o0ZyV/aZlUsXDwlOHckvTmdq41VXHzdAPaQ8=,tag:/0vFN4sR5gebiHYjPd/QXw==,type:str]
+wakapi: ENC[AES256_GCM,data:UvEIqRA=,iv:HAlUVfWN/Ge6yVPJAD8hPGO9RqHOpZXUJrfoMpw1SXk=,tag:7iiqY4c23BPXK1/YQOF+dg==,type:str]
+docker-hub: ENC[AES256_GCM,data:FQDe9QSUzneP2fqMnLbzLJm8EE8nN1kTb0ihfWmtv01VSG9YIQ==,iv:Se0zdr/FHRjXvg0XtAIqUG5L8Qt5nOq3VqjmS6jXJO8=,tag:d9cr2Z7U3Xu6Ygrbk45jag==,type:str]
+matrix: ENC[AES256_GCM,data:LEUjNHM6aANmKERyoNupklMev2ulWJ259wSmqBaaX3dyNZJ7DrddATPEd6MpM6t2b0l7mm3XQdu2f2ar3VGUqjxi7hpTMv/TtbvVG5BIlCK8w6g06sYSI0nt7BXd,iv:PBwnavu02rk10eJQA6hCpoOzG6mzrrPHvTCOQYpFFaM=,tag:LtxowRBRB9OFBhTuv+zMiA==,type:str]
+mongodb-passwd: ENC[AES256_GCM,data:DRekPgzwmERBvA==,iv:bnC5IGKFnTYFofYDqPn73InWxP2vWeO1SFeXB8ba/BU=,tag:IQGL1p70tq0u92uWay12/g==,type:str]
git-credentials: ENC[AES256_GCM,data:MEqWBzmGoAi1H88oXQ17Az7J4FLfS9sXryCCFjh6btOZHdURZ4M5gGf2xErjiWdlwTGa95EsS0Ez2WY3sZR8iMxlws04MWc=,iv:hjgqCiiGFBY2ypX6ZZO5t5HWlCvPvFzZzzxIGBQwMr0=,tag:hSra3Wasnod0OQRqTbHJ6A==,type:str]
gh-key: ENC[AES256_GCM,data:MZdpFYTLeYOifCe2dpyON62PjWad0mdgZLAwFYCW2tp7tv+l2s+qUgKnvQdyrAWeI4PdGTlcPWyYhoY3a4R6OV9kYX6HYy2RbNRwHFKJiDlQB22ZA69E41ur9GjLjSMzSvKb8I8OGacihAEx5JeDjGxZHjeBypWIgdunolvY6SfDs85kEG+bMlPkuA3kgWKGb5DN9QNVl6cJTLjg9DJW71f+C5tKZKlgVJCeaXDXfVXlmHdliNoZ1YwR4xheAXPTqT1c4F57AaJ7ZrH6lanzb40bwTK4FsTvBLdWOazxt68AoYCNJYExZz//z2ZKAyHQdUtpilM8xMuYj6sFN4+hMIX13ZQQ/BpGcUAPChKi13i728WhU54UzK8IkiBTAnix1luvuD4fCPaHU/sn5AkCHkt+rGTX53ZzzMUzXsyYuLFYPpPOFenBB4ft6BBYCNEePeUjlreInkG4IX8myBFbFy6ciXHkwtqXXNq+Wh3MbIs40tA45k2nFqZeoyC1br+vhz8LRejdTN7PCz3pIgCGC8h0ZNwumf7gTQhcO36gq2NsDS8=,iv:648FzsZqu6SJAzG4kdITPovXHnDukKMJyuZL03xoET4=,tag:apqEhJlLUrC2E/bJL97mNg==,type:str]
gh-key-pub: ENC[AES256_GCM,data:MJy8bIwRp1F6mPT/WhMTN89t63SlMn8dfp3NhLVcwHwPtPc0Og2LnWlCR3XanL0x5Bxn6QBedOM+V9cwzXJNHBsA93ZGeJkQSgqtq/Avsv+9CWPVV5U3bPMOj22lbsPhdfwKNraeug==,iv:SyJTUHwE6mxXADCXGBD4e6ag9Mdnl7mkac2TdU1Kkfw=,tag:CSKUFOJsKG/tMhizHRjYww==,type:str]
-alpha-key: ENC[AES256_GCM,data:pfYUpPUSALll+js8GegDaTZ+dW56drx2MgVUc4d7mLjUPrj0+ofR+jfaOiitw5VRMqKLVwjej6XD4aPsxThgVt37Yvc0Y3vtTCgnBsut2wZL6H1sf8JkcvMxFMnDkxcZTber9aFCfkghaeiqcSztq3RJUdrl7jWx3/4MtIOwHzFnT+Tv9L99egGH5SwL75evPBacsVgpAva2/or1TrFPNalNRzAlXUtyOS2Qc0+P1Fx2crObJnIW8pjv21DIrYtFlXOuaa7Nq4bFGYonLfTvdgxOchd1RIvhmBm7oX719JJrmHFN2Tj27zjRxn8L2VFmXddHxSklmug/LG7lkz58YaUixAz+ora+cfS61a4NNI2h7aitqAlLV0eSn4n9j8lAaGwCtfIPtpHDSdN2iJ/qTmogXyT25KnMCWeDZ7VxXavzs1OZyPT/GfyShH6gOWdVTINuJyy8sKpaC4aAHvi7HldjfDz6KQonfKN+KODALc2N9V2id3XrFLx6t62S01OQ3uSP7n5yL/zbh97kxTu6aFaCKkIbg0dAeR3K7WZMTU0DOM5vuNTmjd0GdYqKXXBDRp8PZlsZtEAB74hkfnm6dMvnE7i1vCp2JUPu+LuxQ+mYrhuwXkxs0VI1dCHiPRkPfHjtvlqrjalT/EotEOOfIUw+fo986XiT4k6LDIhG3ZdS7WeUNvpVh8kGuE/HubuoCcY5W3iYXwHN4QrIxWf5KXSeid8quhuUssG8+XPy8ARqqaheXhtpOIWf9ib+e7auDgNpPqCLsPjJhtbwcZtrhGw7lWh/UCHfv45S8zzXdI3/IKu4cJlFL9n70jEqHhXDQpRSeLEXkr0Ldh7iv3QrbEtMYcNh4KKZFv5Uueg9LzhhNQTpYRFUAX3h0caCRIuLKDf6G8E/BbwauYVgObNj7RniLjhteZag3tbx3Drb+EIqyZX4rCCh8655BTwQYpEDDnWDB67QMznIyWXO0ujc0O/jyLzOzZUbslvlrvA2P5NbTfHYcM2GGyifTBajKh/Bp6sokVmHYU12Sh+YaWpIrWX/kCyR4pZ97/Kw2VYZaRFp4lOPPbHyLvB6DtMdfnLQ3rOBLfrWxTHmW9PprOJFl+dnC+l6XTV38LzS1WA4hMlKqUYXU9HbueRIpkFX+9lm2l09+MqpBc9N6vy5aA1tM/owxcGU5vbKYOphIi/cgrv2vD4WGrlWTZbnTkGGRwQ2UTAKBaTom4RnipwyS793IRVRXjS4PzEeZRemeOgPRsJ163n49KzzG+xG3FtwRTtzetwFCQLmCJlj3F3BIpM8UvljoXSqZlOZSHJrliFvFU3uAcMBFONHLL34xN9b/cUiSRoMn8OqEiJO6kBVUQx/uqRLn0KmIub1gr7KWNtW5/uQIbyj102WrfWpiMbkGK3wIw5gBihHL9L2of8GLhxuIoCiyQ/cBx7/GMrYNsGYIg5bXbZoW4xpkKx2nxyiYJcGBrFiKDKHYuYy5acV/TSSUpHUI+kCiFE4272+rum3lXwGplpQlOPlsPQuKn3CgXqAiuRhl6PW0PzRL5590ljInd0yjePX8c6uN7z/i4gpCjH5O5uvCJqJtWRtsssxChXkyRGnJkAHunBgw48IoDW0iQw6SV28klDpVxX0CipFrJO6SbyuMblGdMRIu/4N8l6zxqWeB4K5rnnHTWywE5lRncDIKwr9+DJppLl7EyeSpRDTF0x2LbclLba9hWaRVs3h/BtyJeDuuM1iahhwHJ02ZuVMQ/OdZLuUYcNEcHRtHjCwDImXfUp8yNKTuxW0H5nEFmn1vfwv++xl0T+pdUxBRIiQLN71xdT6iQsqsCkrps+jom5M41jUeca+WYRkMgPZLNnYA5/A4FlHzoLIe2TVW8m3k6csQtIfZz80LjX8l4sc2B/6+Rbyt4AZVSiOYTYBhkGFnMnAFqBkd2ucBoY8KlmThk32imo+v8eR19klMoSiUx2RdNab18nHkN2xcLX1OR5T6WEqiLilUHOsGBms0KMQtAx6EL/mWrxzZ2vL+UQJpkG4aPDX0UFbgWnUUM5HFkY/Jv3tDSzTKXnIGn/hBMESOZd/i7nJbG34Wtp5a8b53cEoH2Med0lizSS2DDfq8/4k0Oryg3WzKoLrAroppYYVGQG8TmpAeubY/2v+ur7e6F5fSD1gbcDDxr5dM6nu77ILj06eUSFmPdpn5Rg+h5pNC6aEDsHb7ljdciUpOiEHZ3MOcMdl0mtKbsSr6RJyWLuEbEedtNwMzceW/2he0breEKvtPS1ekDxGadWi74BbURc9Q8ABDtTyJusyB3Kd7Y2nc7VaLQGLQ0m8zVTLb9+5F1zsuuF1PoTRevvCra8bGttL5XtFvzBMg4R4i3OFyioAEKtSonHO2cF38idzIPaqvZVN9BOLBT9xu42VpHdUMMghkimE9PWrbodV9qlYoEO3Q7v3xnkpjteTxKWPL1r1fzb5fM3mH/e8coHdbnm/9pMy14bn/bhyF/ypheJj3hXXDaID1U0pA8aFiINAJnmlwEiYobgY8UFtQeVwnwrh0lBWAia4C8kuihvflRJ8xYtr6upWUy7Cv8Wte/etlA2yByQ4+SWWktilYkCsw+K96tc7U/9xrVWIpUyWfND40iIPX6FHinDC3WfYefqlhC3ZCcE3SdZp/wmoSn/t+SfBvK0U6DXjHtLJ4gvx69a2h74zz4biIAS7ZHC3goNC2ohQaqOv5A7c2NtGdAi9QOglY3y7YJEzc7DYxbLvfM1kWBEPCfE5NbKHanF51BIepnOUmFxIfboICC+F3ow0n/LhomoIDcS2mfUszdKFLyyspOixykfDbKXPeRL6tFwbrHwx+aV+vU2/uR5B1BZtbQ5A5h8VbMMduUa0pZrVUhTFHhcv8h5FcM1712gPkA0cfLWsgoOLRY03rfjfhaiRCfibh5R9vC2CPVoNUKuIFqjulpTSH74/MB8ebzuRSjjjEhoBQtnBDGLn4WQrLfN/OrJ+vtMbuFNciauErM+y2u+WL2nCAHUDusIlgOFS9fVbJUYQH7d3dAbB16azYrknRQ/dgGH0GesYuDwWXViWviOMjhvgAVZizggnOfm01VXXW0Cco9Keu6G4gkd+ePTPdZKJ59qWv+O+RH9OSf1KNBOtawyKnT1WnohSpau4fRiqkNzsjXNM3TEjDPVipAJJGj97MwZuKRDwj3zh6vrC1fEkEWqcLJs0UEKBXpNcmXdGn/7UJqugAwz5LzX23OAFGEdYH2tcvPRbz9geF6zh9GnHkCcGUIXNglEuSXBXstF/rYcG7lZl3LKbhbG6Wd258VK6NPd8EV2vaDl5Cojjgyd+N331UrkUo6aTo1ucfK7pIssoSCP64ozL6We840T6IPIhzO3bZCO2Ku+AOhzp3/nliIMAUfRL7OtLbv6nrLJJ9hKC20SuAWsHQNGmzMktWvbq9K3ww1SzwTusJU/G/HwUjbT1HTIJT/Ot/JYnPO+9Ds6dKFXdfULGLqDOvyZT29It5obORiWx9mwRPM3ky+TL9Tl6jyj3XWROPhGADm1it0NkaIqblVSUjJHejll6v6kFaaeJJ+cTLoN4pRNX/84HAFyJcMaelsCxyX9ybqFgVo0C8mIrypM1vN+frKmJdhlkqFImAK4EjKxlRTDThGCSmz9w+RVuZvTkTqIzkMl3BqRYF3w0Qu3LSdZSkaORz2GoaMHSN+EBbrdtNOxOQhLR96gotbphBbS2qQR3QxB3TIfL9ojxcA1z9WOVjrAgyA9uCU3BYvMpxNTBzX26tigHYHawG1/lvwUTViZMaVm4ri1qyN+UwtEQH3YDxm3n98qolRLRnuDD8ax6rKVHIPoaRAnndqVuBOE45PH9wcuaG/IRcxz4b+LEuJJlVexAw4J+3U1Dt2+yh/b4rvbpa4ADIsb4nA5HG5DUhlabzfXWMpNzxKqg4Ps9izcWTPuLXukAFVI1avRkk2J9Qo9YRam1s+BoLKeeEFHnTbVI9Hd6hSYQXNQsvD6kyp9l8L8wVgXkWZmn1OZcO/iDD4wkbQ++MKKXPoJSVRut+QXNNcxCPc4DFSvu7MUpMOBkBzYkm85p9NxteZrmYNB7GReUEt49uvpOyFwyWbwD4sPd9UVcMX38K9+W4LNyItwogoGUtN6gbH8wY2qqueyJ2DLYGCrMM/sUdNtBJHHMrDeIoNLVXc5VvUofjNzkwvBvlcUVMRnM4gmNbI7U5CQoIJsVQ3+yJl72KMwotYBcdi6EYIYCK7dEjjto0KO/wU/c15OtZbhPci28Icv+KgWbU0ChoTbIJZXf2A7SJW/o8KaJv8t1aCrJHj4CJBFh0p8hTd0ntb+5UZVZuH7sddLl+sr7S07lupAcNI5Twt0d2VTbI2CZlTTHkuhOeU6TeVM+r1+WzsqDkXuM6cWnSettl+lu88ecuC0vKYZ4EzUIFmDFBP1o8Xn+O01M36JcINDA2lg2oq/qVdjc6Suwp4iMGnse/0clFHNIHvvWu82ERMgMuHBErSyS7JAg,iv:vzuvBC/9wxHlmPCV3jHIK4dB9Qvo0vqSgOvTRpc+9zc=,tag:1VT4dmDiqv+QjnlVElbEPQ==,type:str]
-alpha-key-pub: ENC[AES256_GCM,data:ffvo7e9jCnlPgX+A0QpaJBjzpBHyJjR2+NhideXvFCazEBXXOTXgWfwG1HscDvyQfLCI2nztldUOHnX3SrM0Q+aCXapyc7cBaf+vgZ76XIC2dzmyR1NrRQDdAxr1KOWXKEs+y6ce320em31fxXlTiGQrajrDewiSlYZE1PdyptyqMrjzqHYJ7H8k/gM/HoGK84LE/7ZlyhnCRQpAOlBKFIqrkLXOu6x5LfsQM17WkXDGRuKX362yPspx/y6gIqfR3D/hVX8sKGarkHSGu6aQP25qoCXJ0fshOdGA7eXYEOZ5QDc3pKkh6zM/M9zLbYdur3mnrolZ45SpOOIOLRM7ahEER8IZ1JeSIysa5IqE66OXKCGMubVdOPMQOCeaDY0LGjzSGJQzC3YP71VauHidTX3fJQP72SOXaMYgKda0Ht2JleEwLlEo+xRcEqgBH2nCOPCqOy/R08mhe7FUZebRz5VulM9UmIXkOXeMUC7fQYgSVX4h1DSPTZAjn3z/lNNn1G6KRwd2e2yiWrV9FTJjdhMJoEgKcrBM765wFo1VkE4p8s26KTo1nhpWx32kVvPW0HGdwbKOXB6aSKHr3m3H90PZYUe73ljpp8cDxiykIedRMoPUz1AeoxJscLE3Ia+r3BLkL0CVAHrVKDfnSUDmEBBZLXtwsQdZpcTOaB1BWjpNDD/z1GBVikcXpjgUYZi5Kc95mqApuhDdpfW64qSrz69UvFzuTKlsXnHgTTZWB7q8VMPJDHO8m603cU1bWMsMFIGd10LoewwLvzH7zji7LTAatvaSaYcw0QQ9RJd5Up7Y7S8EuUVKYRFxJbNBrptjmwZ/S9EwLJ0umzo+Wlp5hNWzDw5Uzk83GiNvLGxEcngPplmLfrbK98NGAmpLeoZ/nKpngXr9q4rD3vXjtOBooNn6r8VBw4kpWpeREAg9/jtdEwfxNdCVKsDF9STZ0mTe80un9nX2h/R9nlY=,iv:o/DHr0lb0dDKv78RczQqDwy8t14ql7RLUP0DdGS4P2Y=,tag:uJjGY2jgdSoUCRVQVnXLBw==,type:str]
aur-key: ENC[AES256_GCM,data:Bo52EEI/tjH8+hXx5cguTWYofDSsWWq+Nmph8uiMfelKYkPMy8wcmB7nQFp8vTwfMXObh8R6tP5Tj5Hgg/psoRMQy9qNbW9PKUfrZj7XeNAEUSFfTYzLqOc+Y1iPjVSQey5G4fMaCSNNDWXdjsl4g0StrjLeoziCLf6Ms/mlK96RNkPJvY3bfBtNe7mEvj9GnXP/4qJGD8X6pbp+/BCwW0pPfELcNz88ng2CDZJanCDZHovl4C0UsKlqS2Teb5APBZyjVj7postCsRTM3j45rPAyBX4l/e2Q1iC03bcmrBlxf27+3nyYf6eCeXLpgvnQ6DUD8kF1nnrnuK0yJWpXhXx8YWuFJqcnGIkI0+ehN77/fXWjVG0go41vOMMvZvMOezGObGPrlfGQ30P2dfgREunSS5NAGdNqezxw2grYVwwI5SAH3oYxHYkzV7J0rSOw8YAPucyJaOeH+3q9BlGmzMyGJ5dh8GecQHAICqMeNfisc4VZSkiRVwT1R1Sczn1EC+MIEXwDnp/DKOUcbOp4Brw/wRTWH+wDbMI9h0iLfPdHdhHvbFI+oJa+jZ1aymgkrEvGVB2eWEOv7Sq/YOdiAK8uAFEflo3W7smPo6wlgs6Htw/nRFEiHY7u4WavIx256qVxO2QGSD1xkdAHdroDPy695DX9I5DR+rwRQ+0U/BaZuqcE42fh4zZf5Njq+sY7eBI7yWvzW9BqWp6COIXjbzqdv7TBXxI8hFTTfX0eF5n5l7cqLQcLvxJksPemXC+JlHb8ICKT3GfF5UZxj0JPdsSGbj0x6PYjPkuv+C0JPF34UkN+/V0s5Rx5TQLacQsHAnytZVrwAK4+Akzv9VZYMxDy36p7PUpnsZ4J4XPLPSGtXktrOsM4DYAel054YSGhVExLqrMiQzDv3nuJmBMoh//bKBC7myNLt9wmUI15aiXx+gGSVoqUSyxqzXfAsAae1TBbSW14F2blLEMxIiHSENCk6OFrMyrXWjYOSaAUivgKpzPi6dDp5tgKlTfidW3l1Sj+qBBb51mPDZG11uCHwM6Vuhxtuds/JSB7+UFRZNLYQI1HBMbXBt9d55XZ0AFHATPkZ/gLpVB8WjEikbfbPLURCU/OktanIck2Pgwsv/6jbudBCwwqWWYWYlZciB95R7rx5xpbtMWBIfeJxeYWp1E+/27mALoJdJymHqqUpLRs31AFfHmpUE6qzqEWnJGDKQ2HY5/W6sGjVi9BVOtWTB1Bz078eAiiA6vXcj/T6wm6qbI+cixlXHRfONGTVDVCb3zMukwO0NOb1mD3dpd1HAXoNq29J7Ya09v7iY73AywPk4/Zh0GbyiXKMFPfak9NPu2brWTTMGjyvrCuk7i99UTUDcuzG8Jio6/tC89+5UvnK9OWYtcIo3WFw2OUD2IxGoSMlosIEUJgvYERhGdvIBPSTqC2lHcQd1zJwBJPYfkRL4sNBgbkJ1XSkYMmN40hxbA5+/IpQ4EzO5LjoUH8afWeFED0zF5/qJ8zidbC2An8FdEP1Y3xcCLNY9kgLzXBHW+vfW2oGlBAEow98SuAfdP9R/VYO9VXuUAmGx/eV/OYmM6v17yb7BUs6/5qqssQ3ijRki25OsOSZMx4GZjWFo8py1g96LS9N6ZWK6vU+6ka7RrQ8GmK3F0QY03+WDlg9SchCeWp++OwYueqCtRUKxdJnxhxSIuAhRQqOJt8ncM3FBQC3c4RnotPEJo3OttuPRWt+EB9M/eeDbXkgxsR6tW5N42NsSLdWw5rUCvAsNUjTRw7qfQ51CelGWoNMxLB9dsE77Q929q1SsirbF1b3WMa8avJKxYQnKfb9Thw6lrHKr2lKHbYdjqzUPKSnrVSWhvfzEpUyBtbQHGNHZbl10fZUmi+80myIgXf3k19u9HSQ/OrgVXqVMhNmp2DaB6UKoF6izI+7wMtRCGbSNiE7cDiFqt+8lwOH3VTZULe8lWngf/ijMIr2PRCS030ffJ+/KhDZUBFxSbBsKKzbA+aN7STEZxlid79cscey4Be2SXOS+5I4YyPZHubye7ZMa9UNi6Osl4RoU26LbGro/Efu3jZ8hTL5hNknPv8U5cgnViqOXq2tyfk1GQVhXwFVTsh15/n0UjeAY2m9ZjzAzIWVsqLgX1dh4/ASv1j6eftVTVAA9lShnOGawl/CZZnIdNMAl9TA29t+cuJ0+I3QXnkxa9KgFluPLKN4pZT56zbLqpfOYiDA2dqIfjKavrsZ6z+d791f2vcCgo9HxnCf8S2pc6ruNJA6nwwxod/rSg76N4Si6PDtmFrd/ZfRfqDP3XUJNupHfe2MXzP8gbcCcu9gN/tvMtF9vJsrDTPuojEcQzWFHsElcQN5NYPlXElkkt/IYCnznJh7xE0fCdsZTyEAGAgIQQmG4OU/iPQT0EKh56HsikRwXoUFWOcowgz65rWbJJZbkGoEni0qzlfiZ9oDwG1WfGaouIzt6N5xIGA2C2iagvhIG01khD/e5pGQm4AQuQ9p8VtSTMoQ0mfIpNNh9eLNBoFBOyLnIVFBszGIA3Bi0t3cGeu65A98mIoTzyBEBpFlPEu0pgOzGfCqxoP4dyLET4To3UNpZqNqSVSQ6qY4WH52bW4l0nqgggGsSrT0381WQ9Ua2tkouRTuj0lJ2DAPHDmGzNpnZzIOa4XHaNVhlOyHn3GAJw9RIxDcjMaNomBSyxFUEP8/IIt7Fj5v3B8CLsgZPhf7/E1dR/+JnjJyHovMbcs2r77cuggXw/HzEKBlyCCefzTsUbTUI94w+7yX6DIEg8WdWtlez8uS87Bk57pFrG4lwElETt2klWycsGrVfw0tSsJj+s6Bwl3awXYGCI2TsIYvZWnOOlaVoEjoG3oN+SrVz4QMsu60E58uXfPT+8A+RZCkF5c3rzXhShqsjHknjQiS5FirVewRQfmWSCghQEUwCRuAVpgBdJOkpgtfPvjeVghDeVCQ1Z/RkAHyciOfqJYkIqihWuOlhSQLTymfH2ZHFNiZPX8tXSsNg06gccbmfOuJgx3C2d1zWamWYcNXmVNtAGtVrsyKKwNOxuPrqApQm8ZVwZSFnvRr/O6MwKY9Ay58qstanrJTU+vqrM4nSaD5K2eS54sPa5s2AiuZaBR/fjgoJwtQGnQFgwofK/1kCr+bxjiA6O7zpQ0s3UaHyYZXYTOXhYt59XIL9dDe/AYV6/H+4DKxbhs5+pxfKP9+R5H2WwCa9r1rI4CFV887ohbofv4jq/NkXbXdMZqb72+ZaNtZfrL54H1Q8vLm4h2viCO+8KJIVjDeceDvdmCx6mZtjkC4Yemmid37NSvCEWZrekH2JyiSB7PtnMcAYjXiCO1W+kR2vnRriyDQGSbx1P+QaJLIVb1QXwXTRgCCrgdeCKEBuEzawZhYtQeGNnuJiQugrMW4A+fbkqCs4qY9XhMBKgo1rFfK/0uRXZ2KepvUnACyVD+AfsCh7do9VNDRjLFiA==,iv:J0tWeNW5JMlKnNhN/5MP3fTVJnRSkNTU/AMmZ0yrGdw=,tag:q+bVtSKlhfcotKmNme4i9w==,type:str]
aur-key-pub: ENC[AES256_GCM,data:bQCNAQaZp4YPVTrUHJM2IUH2hR1rXI3BHCguEK0G5em9Tq6g8CVS7BcDIB5zmUs53dUJikI0CToTTLTZ97JUwR0i7WmueE2d20nvrnyPXo6QaC18KUvWKDafjXuGyrMoZr4jkWe5csH5wew3u6H3xMPsLRBNexIYE3ogTKpiijr2sHCGsU3NMesDRMP5ufNm8/P1/nuEbbg/y17EDdgk+fE0oR+VePpve4xN0v4SdCwZlnCWu7WthWkMWwnKNmSRzbbRc2M2YLx5Cec052hhSjjBbglqlfWFFaoSa2//q8ElE/4hs28uTPM/6hxpagTxKwqBs7khfed6S5mrFf+68A0yyctSXeXEmxlnnH4q9WsMHOv9pOWz8I23P4vciNXk48UF0iU1TvfAQDVj+89OO48ZWFCQSNLfRjxaWg30xocYoJoPxMRE3OpL94FdUc9HgMXMadgB+QU/0xsUVTZps5UeymRKcLb0M7/BGlef8Nmzz/Jfk1Z4IFxwWZoqFviOzAdgXSpuGPLFbGlDwTDE1YjTo2EEyvsfwe02XeB2WVO3dXOTW68aM3Mpf7v4YSVGsC4eyLg+CawqVRQ9YFMWJfI7kUxDwkLBdpYZoiUp4c+Q/CtNEzouuxdp0QwHKqPfZ4RvQa1uRaFYXcXevWvz0aifCj6zil+9Va7J8VX5Nm8ynbFFEUMO86Gn2tLY1xMWdGlFSluMWuryrHzSbiQ2qdod5GEXR/fcXYOT7zWDbw==,iv:M0JJGDqM8pr27VvUvR6qWqc9+js/ZaWVTwhrhc2pwQM=,tag:1aDACQ1orj7lu2CAp4Ylmg==,type:str]
king-key: ENC[AES256_GCM,data:lW9ChEUE3rY7v6FyGUolHF9KoSNTKW5LDOC2eCONbpGN253KXNa3aamyYxBnZFF7QHEVEtUL52atGxTKKlY5oHARH4D593mruTe+ePMitfipUOJUYZDWZ/UshOo3ozcXSio9Mj0U5l7FqYn8Mtvu3Kewe0/BYw3axovcO7n+l98f/uWOEX1HijlD1xtEqyAEHR66Vx+N4dIC1YgrWFhIBiX40RVo0Ydn51DewbfxgwE++LkEjApxosCyhrfO0SGSuh7H9HAq89wUVyeNEzBkqU+Lwg74BOcqF+CGFVTqjfthHXHTFEc6GCGp7d5M2RrKhBpbNeRhb8WzD0gipwYozkg622Jt0p3vi5tpwbKWIroZna5Jwz0BVWhJEOeNeBJv2G/hPYzxz4RJ91w6YHIuX1m3cVHkLEfKErAw4d8yyR5TyQPpJjxHQ8/FvqZgd/1Pv04u40bbfhUBdDs0ToEi8jfJgy9m2mETdyryrnA5BmpUHKh2tiBXA8COch1wbTNuagmF6XYdT1yeSHyNcN3dRcnK1ntenmWf3Z0NfOaKLffdEaS+CE75lmgMKWk/BsQ1JUBY89HlE/wzfgSRYEHCzMKQjV3ilJKLyYGqVw/0QqXz8Wakx2xyNsawyuqCVnPTuaEq065sq+GEpw7iSz/4gAf1CQEvIBVZhkcY6ebaFBMVgQYl8mGg0pj/YaU5Mb6zTNz/vdDuweVFdzYAiOX0qs87sO5YOQ1xhbHTBjTihr0zBpIkJ/iSTADSxvxOlE5XaTlc2ODwfO05CXx6I5B50m4v2NggZ5A/HzEGJCPl3LpxXWefcnCqf7U+eRuJTF4zNxVXlkBeXFGUqi3s3Af1Z/Xi6RM7GMkSrH59npJATpf3IUqJcM+pKKWWVOu5Ugfh+/aaMO3yBnFSj0L4mQXNAZ6CCamkfj2IEDLz1zjAdOBUsLrMURPpstNyh+Dd1Rtf5AmYxVZbdYbmRhryjNK0Ushb0HvZ1yJa7knybMyu/l79ddVR3SsF2DsxlevxEZK69NruKyebN1mnm31zKZRIHx49K4M4OUSdF9UnuFuTpOy9l1FdytD61CzRIwzxRvlMddaMvKdVM1AduvQUtiBPDsAE8AP9twalad/NGFwgMxTqiTSBhd7fsSsGvgiMx60lcZcSCZXAtfpFBASFpDXRAZNGmkB+gzzWceuTq6D3KkSRue+WFwAIq3zBqvK2cSxgTn0EifhQ9l7qF9px09WJuY/stOuoceYt56gzspMOttXUlpA9X6kcNrHTeX+nyDd0eQLgUuxQj04Ek0lDlceHHOpUhvws9mGfCOl9BPrps3dm8qxkrWoghACYp7ZfYovf6jmqX/x9rtvgdv1AOwhjvk9kn6z7kV3T7XJSK5/zDBAI53Lk1940cmJAIk+BrILFL65ZnHu+pxK9dGbk/wuMx3E6r8byd211w6nnqp9jBqChT49WO6VlwQHxiYH0ERDD9aPUrWvEsWZjZBAHrfT89w5ERdgxy5koc2oX6uzmeN6EdM4HY7iiGfZF04i3PKhy3M5n9IMCdqH6D54mu52X3T0Bt2Fe5nATqFpooavVocJ57zbo1CKcaexEu4I3blzUd//K9SY8FXBzAjwJRy0+PeGbUjjbMlvtjfPIK7vVeXK+8hED8qO2USBiVQo41WF+3djn2cJQjaV8zgM+rPn19zyZWUvDeal5EAyQQvVCd3Q9qPZCozMJeO4z9b7PZPR1CsygZm4P7ZMNq9Zn6Mkc4CVjeOH+MXpF9V1o1rB9T2QnFSxNS2TE/gOaPgXjbAk0KDxY4/fY1LB4JlybD9DxAaWO9Q+oRix8hScHmS79ToDU4y6700jUYT6NhTe6tirHwPMloOmbIASOfd1/6unk+jOv2Ge1D6cWOqKnq7AHRsFBwneO1X7Xwg7+8LepHNAyFWHhd17gW2ZSwSuFfdrg4sTTqGsKv7beHcu7pLXMWkvCLcf9J/IicSsl26sCcb/SgbkWeCEppQFMhcb6/3v8VaIY5ICtrVto7G6xiLdJi9qOV+6t3nZU+ESXR5yLiKiP42IwlstZCfeYccUHFpmkSW/G0kUAPya2bnjXIKcKsKEH1V+8YWSuLyGrddRd47cpwvK8alvSFOIB6itiv+icIMHXkkiMO4Jc+KWSW2wJZozmoDVeT/FvscHVnOB1QU+QkmJ5/srtgnLSwdRNaB9tNatY10VWcBBDIh1HVBlyrWN+8+67IYtWN9xGZ4M2t1s=,iv:Oz7POALgJhk00p0vq8fToeT3p3GP822/omuiX08lRvE=,tag:jnqVNKSax9hlGkIEoAOgtw==,type:str]
-edalyn-key: ENC[AES256_GCM,data:wrUcLsS6Wh5Xe613qNDpkH4WDa3Nc5fADM0TtA8Mt5S8u43kFcwDAZ8bgDSI2tAwu20VIxP+GRqLcRfq+A2v2PvqhxtBM5ctcMgNh50fZnefkaQX23XXw72DJer9tDFq4TgX2NvO5wVY4BMRa+/itvnmlYPJlL33hWKuupxH1ss2ZKyCcX/tcwvO+YDc1eEvVnSgfzJaB/k4FV1AYfm2AMsm9eiOSYnBQXFBHdW/pVU5d4ZcYYFYxbygTlsP98uHTMGT2AndAvK+QNNmkCk9TlSsVrVBUi/h9JhJwkaQW6YxE/Nx/dvj7uEbR8zxL/xNHKI1vwykR/XV8JgJQCk2U3dIzCzcZgy7MUo9EkPnxy5t1N5m3Ie1cGS3bzZqztD1BD5ZAvsHST/AvEzdIv6yWz9XPYFAB6GQ8CxPufyL1JCzUleliRvO0V2Ut1zwBoiqXxpVeSY+Wk0xgVxcPCI4+obfsRcLSyq3cUNW6lJx3es1SJbbIVn908uYNfHbUXNrll00OPWhCJu9cpWKDA96Oaj8RKR3gxsHUADLAqx0imu6BEWfKp8sZBhEjT03XkZ1gjWQSZHA0qvIzNRcavGImSlKZwLmg5ceCfFVJ/1km9L4mM/BVTJ47DwBMgHwKjbFZWTsZqDRj2cHi2CVJFE3gzoc+iot1UE4YDVR2dV60TkbFr+N5iFeTBf85H8B2bhCQYY7k8NaXM9Q0Kt73sX77X9amEAtB4jG3a1r49RPmjlCxbtaJ7zcvtFQEdqUamzvK8tuMjNnV5URI72bVe8o8jgv50zasslW9AgGNdqtCO+j+/nLXM+5e7Nlo53aLnR2udij70YrTSScyf5vIin3BhQXyTK8OhnjyKE59v3dO89/E3xVlTlTNUCjd8+Khs0S2pCrbBCQPB3LQZGj4jFGx3roozAedoha5qG4FJqpFonIFG5I0wEAWs6fRsGYpba7vqDWNTqyo5iB/05K4JsVbswBicHktflFzLCGUXCXLcHNs2fsewKBfIIfFGY2W6Ay1or4pU0EvKgVm34t2rjfixeIZhD9xIW8gDnk5UiVmjwXwMZjt7FypM+EnKyOhxSDbBmLbS0JT9YWH0mR5DONH9hSjwZYxqDbkXU5bKYniIYLzFgcTVnEu82LxfdZpH5Ls6L/HQSeY6rSfYG+6eO30Th6r11ocwEEVp7fnI1aapX3DSQh44uI6RrnXeHHlYc876Kyjjg3PSw0hbUSOTbw506AsdY9n/twDwo/a3XHTPvYtT/We0xsYTKiRhipbgR1Z08phBsmzoGpHpywCKixKLzzRVB1AyStzIh9cINGl6a4ckTxXq/opNSUvZ7u9U6mIhq4cgtZmGUe1ZGR1KbEmEh7XGZ12CPdhpDejBTwswyLnLBHKhh9LynmdPXsr+iOr37asUqvcAU4vqmMAsdaj37Bq2nxTFOTMhBkXXvDpLCJIhzJ14vn4luzai+MTkkmiv8jn+MXwmUme/vSptYCY0XO23pOoRlSJN6XSgxsSSokHrgLI6gO4feZmOoQh86wBpK96zGiKx7YSdV3H30Q30HH6KCB4awhKMhpVW80wzBHETWivl9QNOv9l+UdTFqeNuHWa6Y5TYAPzHiOBEo2GXFzgCaZXe3AvZl+OPXTl7D8jgD3FKFyUlwVDunYAKEDjg/bL5ygv2tfapassOBn2ifLjtQYIF7VlWOSQc5m28E0ALy4Ef2oHAyP0pLwjbHWg67ZkiUnXZmloGX9LW2b7ewEtMLO6MzZP+4GMzQj2k8qBphDj1iCrdYxDwK7Ashlifcypi9gFSAexZ6IkrAw71/GHvVbohRyhUndIsn7L3JnndFiGD8kk6/mw5B6TIA/UEJNziYFYwPHEoLZfULGQ4p0zSX6kXsss5hlIpNn2NSuREG1xL7eF85pRxii+COtp7DBzqOChgTKOjv1BKsQipZ3L+e/9TfN/K/IYlHv8PcrIHLLoMDswwKZeoVZ1PQWnfR+t3BMVeJT04gGmp1Kh2T6H29OCNgj2sbh381rbICoLjA4dxXwzU0FJ6oUoqbsR6ct+L5diViWo39Rs0A+sY9Yqink1qvRpacy+KLy/ctjziskL6NhURs4knulhHr+gC7FrLYJtae2KUyCUcs0ybgKc0vz6o/Y6ZraqdjqdMAOCSjG4mDL5Px1iOSFk4Gqk6zumwAtREYpinTjpkqLPbHd/m4oN+lF3U2v2TWb5KBPYSsLmNGa+m0EZA==,iv:nLnfRA8PL4TNDhZ/dRsDJ7ZYdqsisEPE9JQDvevcWv0=,tag:HTlfI8w288l38H4LK1UM6A==,type:str]
-luz-key: ENC[AES256_GCM,data:+7kmm3Qk049eBZ6RodwCPSQPiWaCtJIHfQTVZAXijMYfjU00JAc2vfAjeuMbnTG1bIj6nl2aTNnOlX6FYI5Jl1trPBwJrKgLlJ83rvxv7WFBhnk16Zm02rRFtYXL+W+CtLqZUSgjbqQZepEbJcEyM0lBC28/frAbr5PqNSd3XPDhUqVwG3ZR/eIt0D/fHZ+zx8LEqtkZAawTylO+PRpBrZ+ZlxA+1/8SLRhnffrWSbUYREAini+pPjAe/waTPsbpNuBtLezWNg3sZ3hgQBahtdvhZKA7mzE5X8Zq+prl4tgbgZ5CCM0kCXcFEW9SX/C00xl76kRmd+jg5P3FEVQ8L3+EwRnqwr5j4oEM4MMJstJ2OUOxxcs1hq3thOnBjVNpxcoxBULZMx1IrZvGWlv2l5Shogf3DL01aiWuMM5DwBaN/8CZrZjMSyxT71IVNpR23lfdiIbZNPPFBT4JX+jmV1DnhutwLAo9oPQV8BecSFqRI7lUp9hgEYbObbZtS3tsGdNkWsA3s/ugpO4du53dNzAtsEM5DJgT94X2cbS3XB/gxJGeXh7tG7Z/+/iqc9cfwZyOqj5GmswaiM6TeM1d+s1xhike9zHPdR/V1M4N1wasMfFdAFFDpiWMG4loY1Fjads3Q88kB1+B7SNn6/V+cIt5o2D8e7SZUg/4Mfw1xk9gtgzQuR5pm/cIUrEOYgWNoRK4MsQ+n0/M2u1mXHCburIWAFNknU1dKN+tG7dI7qqScKwPO8O9lgrL1W7tR1BQe/bYYC6Z/Kfm8dNBSMvnBnCbTfEashF6ltP3S3JHrtbh5tdSmL0LeAR7CVC0ApYauX463tHvwiu1KaKtJze8T2dAuDjybk5D9+uApcw+cvaI/8XNrZBCA/Zocw4DIXh0B3yPKGE1784NRyNOwGBcnMqgzrFnJiMFtJKGp7jGstwXFYbYzlhe+YUFo/jyBLP7gCrKOdwYM7nel5VtjLZsqJZ+ZuGQjgDIGlY8Sk3SwLn02FFrz7VbCEFVGKX86L0Tm0Y278jL3AU0j4uAo2XxdVVkN7SXVUC5jLdxFiLHfYnI0STw7BVxZ6UyfSEo23b4bzYasRSfedh+yVDq0tQVFTyymb7t2WFCLhFkmvupPryw6EWzNmeMRx7QIqrodUb061zpZ74ymKfpOY2cMq9zJuLvsBMCjqYP8mupsW3n9y8neOAP4P5KuTSaaHMuQVKA7THFX/otzGtp53znlSPm7stSkO0hyku+zEkzcbb6HDBHM3x3Y4KOgAmLfjZMVnJ6Yfxc5uCTEzaZgIMJzE4H1/rpX9YJ6lyhZOpCd4bgGupffjv89MPa9hmnynIrgadE8tuiA9VWrRDCXm6gi1O6FtibMXgF+hftctEqA0tWayfeOCY9FjiGpp/Fwnd6HTmzx6ngD6A8IGHOKmMsOTKe5bvkIorZbM0wKjSDpJMxqb0pJ+SWCcSjXBoVp2oXN2G6u1G7yFGeu/ji/JdyD7Aep8ElGeSWCjI+8bPoaw/DKBDz0bTlhbENQrhN1S4BISS9tJnh0PJCeH8RLBOo7nObE0g/lpasmugWJvl1nY/WPU0UMDt7YVqwL74fYzm3qLDrJL42v+j4sYGHpAyoWD3ndX3d/0ZAn/jdVIoGTHwOBleDPbVsEe15SeporyLt1w2O53CKE/Dr2amhrxxHHXe6ZW5zG/dmV4IWmJ5SROls/OTuLDaYyVF4zsRbLNSVQ5oXoriX74cecfm8wqU3a0K5PXmAQEy4a2szJNYLLXcUbITns0/mAJUs6bjTnPykp9EfdcFdmIcERStDzL8VJH490SbigAxcrBkhuwA4sOhgOw+R1Z1gwiEE68LxK80tv2rHRSInpXj0oEN1MaSLaYhiCv2Mz8j90ixhCacz5vqQChXIr7OqSbs6DxruG60B1rDBKUQAEFmYTj2aoipdxSZieVYJHiVN34AdOPSTtMGtqRigfa4Ib2Sw+n/FO5pzUKq2vbICRHtXRRYSkkjHX3MflMPosuEUCNmSoAMoNJGqrz987fTf1gJqdb5UOCpxg3eXnV4v9ZcM3SM5lu5jgcDVk86t8Hyg3X7Ftw1NMh2AOwpaqr29j53hRtwk6w/Iw0O0v+46yxDeZftiOyLlsN3DTXxCDihqs5Mw7eOScZA91gdeNQhsxlU5ZX9aPhHn5OusS8JFw/vE2i/ODwsBZWDV+ZQU7ZPhnBeeqjMAkF6F7i6luvW85diVDPJmJ6o9sqk=,iv:KaZxvOKLJKFRggfiSKpE6CylO58eNQpRN24q8MlALQ4=,tag:XcITCHBz2h+ihZe4p981kQ==,type:str]
openvpn-key: ENC[AES256_GCM,data:Rn0OVYwwB/gnJ1cdypPuiiQVTp1yqC1ozFPcUCBlWdcdbyytS9RVZwTePAST5DxEkd/ChDFid2pBQ3+JXwtzrq+sDAi64zPKLzDm0TBJMPLL/Npv0cKQf+pfp25REP24Ajo93ZAFinXT3IJyYF70P9VJ1AaAIvz16CreM3ZkQdV4M6AfXQvPf7/OmXThG86aDqvNXE2rPxTe6Q2JrhWkmKuGUdAQ/Nfqvk/bfK/0k3MbN1zE4NPftXNm69HippiIzJlrFAS08ANZGR67u18yj9bCXdaujyUHxGlnWoYh8HBrJozcKRh+xd/aKJb73dB9+6ZcLPG5S6aYjnqGoTwk4fFlhQYtSGb7199Z08xpDZ9e9yyAs3mHqh7Bts8+ikTmMZCO9NqxAzSgXn1xNRi+buLDMtwg7f6cyxCc6wEz5FZwXBvk9x1shCThNeQ/F3S7wT0jPzU/ZzW/zEpsSMgQ75V68yTW4rxtv63gSnNJZSOlLLKT+9CRym0doiNqd67uw9hP9A1YBCx/1wQg5gTYZ7xevhNFDAR5My0EDsQ0V11SsTRlct/ShHVAwAQocgjfcLDNMDl1xZ8FNOpk1RFhJiPIu9X6qrxqIfS1E3TGGDZZyXiC1GpHvqwqcpKmFQYHTmEXJUTIu6fKPky3cksrBgXfvt+/eNcDMTvkFOcD50i4w2u4ugb4WzGTGw0fh6OtZYMpwIZDbOzPZQM5q3IBy+UnhJzaBDq7b8qHMEdjcM30BZagrjFAvOx1hrVLNG1+rgDzz8Oq3+auEVPnWi/y+dLBdG723Hb/ruTD+NMd3EGLpo/+X63XgIsPludNNdbWi8Rhh1rzSNKXZ098kWRy85IuuUizyJfPIsqyS0I3s0iXvpv7k4ULBQQeISPqWKgs9jVSLy7MORUtnq7dfSxyrXRCxSuryN2SpRR77MBDhum4BtLz4LuSz3x35TBmTk/lmaDuWrQzCU5O5OTO5PBZ9Imgu4xEsGG9DVnQ4NbnibTLq+pTJDrUG9M1FcRX3NXp0Um/yrMmYZvg9zgt31WREVnTQYwsOu/yPCU/2Yrd/5/pndRjRuSiD35Y4k34h2R5k0XJp3hn6OJ+60oVHN0UPU3fH6GEA7zqVPZzx5Qo3Fpjl3QsSzsYZibdd/sq4hDx5WbFzizI23brYJU0FPyBxrk+vClPjotDfUUI63xOXfhHpR2yiUNqBxIOaXidCQv5rScIETSDnWd/B8wiYl2BQ75vp/OYzNvXg95baekCDvmR5ShvAIvmINfYOx1lToiMFr1L9KHKawrdW21cNCrPXkYbEHtDesLyuSohGyIJCXlQqPjvtCE2m7ikcN2WBpJJlWP3j/HgdmZxhdy5hQv4Mups+BN/zSdPJEiPONP3songdseXHNwmmTR32BS1cwKyFPk5t2Q19i4JpPdBnLypTu+0iHBT3ESLKnHxLNwOiR5RWJpdQ9jKzKc7Re5soiaxE1Qq3VcMfC2mxNalvMa2gWZg/kUMKa0l93HLbRCBet2icZuKP/02cbrxBoxb4sUhQ9gyHbIJlDKmjm8j9pX7s0+N4/i95gwA+o3mSFZjKV+VuWRSKEhCrVgMLdLrnScWVlzXnttwTL/qXj4ZP50RXVrEl8bO1GSgZTIPQ0ULFBCgZi0y/xhahUQZvRRY/iS0EIh2xE6HRyBx7OlCvD0gFHPi9oesMTkG1SUniOGOZfsR9oulV7Umzy9qojeKU4js2h3Dy0Y2rRaG3+0LZZ5SiZNbC4mrT6wUeEqv7ofo4jrnW6TtT3EP8fWKs1nvDYLnd9MojX+xmVkWj9y6/rIeMoqaYcxO1wdvWclTeL38gSL8neTpvOuaPf2IoXmf643h4/iUlEElq2LiP7RcwoU2zJpOfd+9cA41zI31dl3R3BTMg89mBmOnYAO4t32JklQ9Ah3hd7aulvUEG4uEUCGPR5wQJtWNoU5jeAeIAnVPr1U6Dzcy6LAWBj3ysegSMZCGGiyqEHffX87X7oYYK4dBFZR1GaAzWDa9jOLmKz46ivcO7GrHb6eBDW9/KYvM8+aikL05ZS2rO6Hz1bHcY1y4J4KvQozJQrVo1I7/xikxQfQ3fX0h/YrNK2abYobKQXz6xjFqIxbqivCQRGsTcLMJuVcfJVecDG4Ntg3qdDgd+i8Wqk3S42pK7JjfXOdrWyQo42SRnj/JDdS1RhBVwvrkAW59icsS6r6Xdz1ytHIAsxN8zzMyNabpHtBCdFPAlJ4=,iv:gTgcdNA/mKt18eNXoiaN0dWPMxjlH/iOkRPmsohN2Wc=,tag:sRhQABYI9t3JvqEqYPKUjQ==,type:str]
-hydra-key: ENC[AES256_GCM,data:O5Xix1LDJRiG/LGeyzjnsSNpCxNebza7FxTjX0Q+vqOka8UZs3OCLiWxsaGzf5jwvE9IoUPZyvsD1cUPoZ6PyQvv/m8krGQZglyPWDv3Q5tpR5JjB9mVCqTI0k9Z88IJagGjpLnDC9excnig6s2vA3/01FHOnbXR0WIYBEoUMlOGUSlU5vFrHsog9MV1yHM0VYN+pxjqIad2P2IIbimEb8IaHhm+ZS1ReOXkGFU15c8t1xmGwr6bqOx9QltY6h1YhsWHuS5idq7uiDwhw0Yqcy+BGS/7fTRYkfot735wzAcaAHMkafcgxyvPZLFavkD0iAfYpQUkEy2+HExTYWP0QeA4RZ2RFI4dnn93hLiwFg+GV3xIooE+h/HY0h/Rwk/2BY9CqLdszwAaxeHisGLo5qsEIG3VXZGDLWs/qarur/WBcfsnFcLMxF41+aliCGMNOjNvQkNkkDx/0JSTqv/o3E12exPQbDbq5+1pX9UqGvKVRmpXfBvkqn4e6nKKUNc1KBiNbg0qnC3idMaBCYFiuGmhVHbVxbKdIUVJ32E/5DLu8tbl0ERmh9umh+5IFxjqQJGVuNCtre7Hb9jPNHyHsOCNJlc85BhjBfFKI9LRhMIQQTSGwIoaNHuwZX5j0VdN4PGz4WCg5vFqVMTTDgHRysqQnXs5/sGtO3l4MK3sBqGVx+Qjeo6CC8p3HSAd1qv48XxbmnBdwJ9wxqoRSloSymP2N2tVDdcay3rkAGj/5Lm7JtNfuSdcjjbpR3djXoV4f2AUl855rgYGJqXND0do47SSNoBio00036y7mMWcmePhwXbpXvul6F+J6IZC1Pcy6m98G8RqC+VzFf/2HAsM6fK84sZptL71HuydWHEfLbc60BPLu6CwhNZ6tn14c39/Rglonqi/RBcFjYzasY4FZwwWqadTDkDmY4XZJGYOuexPpOyJW/AyNLBLQPnR+GzC8Q9dhSuxL036JVFvI6YFv7aNDWi8Tb0tGTxhYDhIpHvQ4Lz8yQud6gu79LhM2N71TNkep9r85hF0nAlqtBZm/2pCDO/EyMiZRB9jTC5POvMW59hAkEiNihkfMnH7tCD+jzZGZ+r7rF52FlIiz6jgpHnUynZajcMfX8DziY/YG0jv7A7QsWf82rDYmvCuGPKHWZ73pSwXMat189QgDxOmmPTYhsi7ID13tTPz6Fyr9VWyXTuA2GFI8qZPthfCKiPBylw9hZokBH43EvRXjqc5cUX65WzICtl0f2bTlg9nZ5fXVH7sTDU6DJfG7GW+0Cc0Pd6Uj1bOTU42JOUmn+YdrCs6tBuEQTmn6vv59eMVXhWjLHMhhbwOJIbrkjs7yCv7w+1Rqy0l77lxD5dLgiCg0QppasmF6bSIR00aLQPUyj+CfcJ91NMXeBI8EkOG5xX2wM5hl1WrVFqUztGsSZ41y28O2Z/dpdcsZrvASZNhsaM85Qb3mHL4Nc7UaF5ui+308G50C9A6rWtr1JJ/EMAGSIf/gvqr5MMVSWj+A2yHSUNIMzFdy/pI5QC2gpt/KgAeNsafrcsCXgM4Ptx2Ze1uohZVo8ZnJ65Be73vaOrIEbvhGpAhDuY0azvexrvUjQyQPvnor2BSQ0wIWaXJS785v0L76dFcQC5AKWOC6XSiLMRsKBrc/m9tD2FkKryR3yUB6FLTrg6bV6LnC8NXKrL1HLwqY+DA5kh9wmKK6ETI3NvKe4nTYY26pfhdMHY79jj6WIHspZTLHgyb7qjijWNpB0f0m9SkvLgq2oxstwaFrnSs/hB00XUIPdgVVbLLj+E+QhZ0uwycQXI2b+w9j10spqxj9EhlDz6mTAjmwj6QUQA8jRxH/vREIGoKCpiqJ7B3cUUEpgLDbn7PKeT6JZOzzlsy2XuH0JU6/ypfmyx4E8BMmTQtdAOx0ywzJKAVUdW2NJFFwYqWu+zzCjme+0XhSAkV3rG9rVDQ88SJZRtWJxjyH8zgWj8LWKe55Qs2ltIaQBepxJ/5KFbvQDMEahqrahQfHvok8siH5YG6Xvwx+xVrTrFgzhPBJ60wILvLEk7iDKyprG/2sqy7wQn5PAVVAmut3uic+8Is+FtVfDwRM7/ZtP3xDDFx1Mn1oj4HbFub35qrX1g/jNTHtgR40wG3C7EtHd2ver+E3VA+WWMDFoL2GmLu+5SmFxBqYKUXjEyWjmuqgNiArmzsLJQO2BH5JdX9dqJFo8KdN4+PtfrB50+htMDTXYoNR0N+o5GiQX443j0QHfYCK6U0KFiQVjRI+rwyInxToop2uufKXxLYiEdk6DHeb0UHUDVQbFvZ5S1PG+MGCA54rYuEw96jHETHdpEs5F+F7xtw/PmTcxlFdvfBN5HZeD/cVYnegCsGSDAJyKOWjD0mhCogbDJt2/xoHIjq0oenaguCGX+msdFLiWg2EBD6aLBH6x/algM7duTouYubgol1XCpUxY8qWFfqWpZytYw6nYssVbAPWHqP/uu/Pa/Mi2ijwtk/Lyq1cGNjGaambvKfP51Kg6+hqr/nZmpYt1kb2pNNeSF/Q5uyetfRr79g7EblueikA+iUUF5JVxdhhjfEOV5/Duy2Ie9VH4Eyr+NH4PE1rJyoJgN+LdzV6kzY5GZnvNBBUa4WhwGNkKLZ6ZxPeFMPDLvJA7u3RV091T+HVqxhpb1TRk8lBq81Y9H+opgj5HvVuZRNqHOpFQDik/YSmajp8CksyS76ECwoAderrrL9x64huuhTZayCQ4fpG92Y8Oc5iu3pWTxwjQU2+zCZcpHW0ChJZ4zWftGJeL+MjxplglaqWhCChq1ixpYi2hvCFar7o+qRQrQjJIggJvI/cZzdXZN+zPP1Ynf1VtFd9+cbhxp9c4KVLPHbn1IPF0y1oJ/cfcySzeOhFBSOwyP7AxSWQldBvT8bBV2f3Azkgn0aVsaE3aWJ7DTd0AJY2dj5Sdu3qze7mCRnn5Ma5TY0fL4E0dwsNX8wxLa9yvtF1jBPn5NNb8k/r+/v1o8bLyBjBMbs6Vj0PDGXoxUsJj52VyFEwsp6aDmAkA6wcRdCUZve+DSSfwFYnX3sVwYXLseskfRIC+OCB3BO8a46h+hh4+jjLm4RaJ08k2HaFE12cyuLBl6hKwj6kV8ks1mOQ/8yTv4yjI4Cf0Y2PP8zqlq5gqlzh/qaVvF/bRa0Wrhk7Z+HvXr9vAfK+Dd6tpbUsoc5A7nF3OH1TM5d0OH0Y4KxY4PdZLyFgMZshoKQhQ/spMImx5YwoiRm2s9fKLWKK135U/GO09jjo3ZNHEge0e5dqB/qK+OtTjJ9OHOQKYCbRfW/zQZZEwLa+uCDnjA8NOd+f/we3nRGCihki3IhVd9nqHZ+6+wNfYjEk+Kxvjk4BIa1qEQjUUeuYrBy3shKz6/lP4tmf/f5FkPw8YlQeVmMYP5Cne4jMQXXY6MPa2PTL+JGgyR6LSr88Z+M+qDiVuYYNZeYqryRaYSc/XIPOySGAMmP7A==,iv:FYjKCz5cklkjzExq+9uzNtGHaeSGZCDQdyhXl7dKH7M=,tag:HKpWbsJnxkoCAvY3PX9Pbw==,type:str]
-hydra-key-pub: ENC[AES256_GCM,data:ljYq3S2ktde1Lw/E68x9gKaw6M3jakA2hYXRlJgCmQWRUIaGuVmIcb0z7DhzAVQmfGZ5J+iPgH32nVk/84/OXexByxOLHaj9W3gPTLxZIPtu4AXPpwIgySUO9jFYzdJcv27J8o7m/tR77zv/RDJcp5l/8oKB9/Z6gOoG3qZ00URsfDaueljoQ4FBMvI9cT2UEivo+AYP/w7uJm85PLgP1Ana5PdeiNOuYVvR1YXI4OP+pKr9KHm84RtuFFdB0p1nZc6k0AX5R/pxvx7fwOA61bQFUnFodLo0TnjZLWe5KgKMXkNktnR/ozRDD1g0QcYOoiCl5kYKfgRnNhvWP/JS8IPzY6a1mLDkB5uwYiIhw4PJ/wM4mG2TvmGSJ30W4E6MW2V9P99Cnatq62KaaY3H2hvzJn3aNjspaN+lq+bxxPROykb1+N4xOmbn+1bCavforOVOiJcHXZXHHVLzAlXTfN27au0w1WqKOQBTxb2hdKn3OAn9vTFOXXC5BIq63gakH/aSG0+FTF/LL6Sx3YRLxWIDynsekecLq4PLc7gLt3CjfHh/DzCRGsuaCSNw9+CwtmrDI/qN3ISzjsMxDrZ0szcoMcqxS5eIOA8lx/6omqj6XV+Wy34gi0NtmUOnJreSBXP2TW6f4KamruRo/fdwr+i3EIign3Aw/hKf2wSG/YMLsxmlkIXYQZAkXBuU+eqKeZxl4XIlsziNW5izvlRuSGJgheZH8eDPHtszG9vlIQ==,iv:Q1aT7V6aCZdPxpWgszmbRBLiAeknKEpn+m/3umRzGLo=,tag:ttabAuYHhFeOA3szf8q4XQ==,type:str]
-bernie-key: ENC[AES256_GCM,data:n9v6tR4SJ9rj8epYWtvr0bJGY/yPwJ9DBQA9O6HiHsOPChdYobn9jHuIccep9lRh8eoRmQjQHHyvhZHTS1XHvk8icBCu6SUJ7TKJMqJ0ACSRCKXKck6USDcYeRvX18T33ID9hQJW2bDWwnuWBlrbeiP4yRXKCD5pTYchXn88oARpLiTG+tIRvCD/I4sfoR707YyU/m3frR0QSPoUyvX1FnykpJylyz5ioIZv+ukwbqU7quzbESme/12NAc9RQEHf7puPfURctblRO7LlbSR0qgVy331NjBDOzqfxAtTZ4DfIq1aQRPalU/X8gzBDeJvdzwoWkzC0M4SfdRAnbTrtPHduZGAFjEsr8WCIcEjMUrF/TKR+K4EXBdA8CugKlHOcBwW2bTJK5CdmdTN9rzs2JLO6MlSZopO2vpkzQM3mEagOnM0MXia3rDgUnQKrBGbKDGuazRDIFbz0jAn2XQF+6izJUMakczX4YJme/NHb+/00PoOAEgpavHDkogfGpBBjCiE9eXnI7e6t2/1DOQNtxqVOqTwkU1pd3R6iK7ctGq9Z0+Qllrxz6Yivm6/jpD4TX0PMyOnWPVAO0p6x7y/zhOffXWU9huEMppiKu56TnuIAi1LVpZm5YW/W01jzK31s6/SdhVn6o1so7TbRxqtfeDa7yAnc7He8MDvvFBKwr/Ra4lt/Sz8x35EAS8O1J2IZQ0te9WP77Cto/c4l00wzoQyfPF167OzrSzSD9t/7qO189HbB3F22TBuwuOSZyntgODPAgkHbmcf6L7QWrazNYlAEN+xtdQwm4k8z1M9hHv+4N+qtd+St3Ty0iEiKgp6kB2spPWF96btllsIeCOkQH4hpMY0XMINnN9IeoigrSXFiEB9d7Lx5isksFIZ0JamEc+RgR1mYmBMllf5CSYMIs80aGhNqBePW2EnSrC+q3DP9d01Gfpt0vpGFtL3FONJVIW8Ga+mh2nFFa/B+RxaVMwBhXrClQo03979WLzctmsjuxj6CYD1jJKr9sWcEJchhWC84k9SQGGJF1VgnPhiI9LIugIGOOdZIKb+Nb5MyHLjnrix7nXlS8ufmKIEVanE18K3W3p4mF09vd9xA/83Kki6HGajt+f8TJyX9JX9d+gKVvm1mqBrpG4e5+ruLO176MZtWfiXtFRy1LBrcxuUt3UV7F7yetJ6YBiJW7m0znD2aW57B7rtmfv3NdRZxwZSarpcLB1EfVnFKJVvn1n92VnhyRXnrm0zTCwYEuszLgRyb2P7jY8ae5ZJpGp2cYVsQEeZz72BE+l0oj6aD2qtam9E/1bmnOogY+BQ77Q40PlXSKMIMggdNqmBHJN9nGEiElimRCuKMrpSHZa2l6MXVcplxBgEHtMvHulEqjnbd/8PyfFtN4h+vedkPPvzHexMtdne79hHTd7qE4CqECQguRHBdRcb+pBpeBM0+DIw5ZLGl19PGwbjPUOdJX5ubuxmxPaHvZXsNpQdu51SJOpZ8IOe1Ma7cQE2oL6ay0v/KrT4jd5slvnpjxI91UIjTVWIXZjVaO2z5FtH0h9w4J0P4GwnaQQkK4ArguKblCXAnQQMr0uQnd9v40FlLsoYBz7FdwFlQJZqZPo6aLNLRfqtRyy4Bolib1U3XJ+CuvBgc3O91G515PgO5+TfV/jjpt9r0ytrzzwbBkWbnIS8plU8gpWJ/Om3OYj4X0pGEcSd924cjUV5SiKIMTM9A6EYjv4KXqxqfCWD0INHfVUCoGrVN/Td6GQBikFHt2ta1MESciqfi+4CwBPcwHT0bSmwnb+GHDquTQf+3fGW+LMiYQ1uIVBWbYFyHmfJeGExGOZjNt87AU2cuIjjqU8B2nLSpxyZMkTperxLXx8LcDJSDQiy6v/kldpopVm1lvwvloAeeSGGEn2Ed2RKusXD0P8TcOkuxUvR6NY8nKDhj7igdFkiTnJ1kiGelyiUyss1pToOEWmfJyCPU7apgIWN0LRfrsWEg48jql1zkUer+pbMFm+W+PHvBwTMvKmztD9OlhNNQ/aFjJrEcXdKkaaK9s1YHNrYLLlsHfGq4/kzmCerI6/B26j1mHvj8ZUSQy+wHTj8NjM8Ir5OZt2xZ0p/ziivz7muWLbndPBoLiT/gjKOZzJPxwkSmbZ/MxBIoOStnLm+wgJg6RXy2PHduJslHHp2zUwdZwW+BjxZGlb/u+r7IhvNRp6hZxfv7HXqFBFascKnqGhfBbeaXk7WqXTltxmX0jMPTyCBFavL8y4553gh0fYDN6Yb1Unj7WFrPucjY7AsgtjKGnmhDSgH8+k8fBLODbWLhb3XK2vdbQTFm1mAn1X7ZXjeC+qNG0Z6llOLvZ5sNGmxfvY1vCFnYgXfqYW2pjerPi3jjLMiSwid50Uq0ZKO9BSwqEkYPN9qtSLUxOn291rdfOHaYbsHDL7NXbFvrCf/Hse1FT6FR0IqextuSZCRSrW/xj33IbigAKez3nd8jj2NDeusCiXms/rp26JP58ChX9H2lpVPRurvm1Ae8uLnJEG5FMnMk8l8P0wx3OF3HhRedc8wM4Po+IaNbdvd4m1L/SP+jzPJcsiVnadw7cb6WWG/Ycqm+GeYDo0H0Ew02erkHZpsm3Bc4n/0f9ya/XuCyYdDifxCOBHYT685qpHM7mK/3qNL+m7gESEEiHVBSxyjOjfuadMQAzIThSFUmvChr+hFME4JenIUJt9b/eW3jZ155RZr9y8M1N49pAFZgTZ/Zp8m73NYgs8oP/BXsbcHVDbg4nzc7rcL+wPwMEbTwn1aWWDhieib6NEsHAFQL64VuXoMcigJrYcOEulc1hexqDo+HTKM1rQI0y8nDnLANPgoONdVQ6RxWe8DwApPfYn0o9CywKW3vbuoEeUg/MwzlowNb4+XrAnxirZtCI/0D29Nc9gMi+frnikVhV6SIkqSUMImma8isuyanm1Pil9EAZAMtbP5m353bm0UtrldJ38mX2yUHqpbD9oEq2oCMTWamhERUJbrzV9TAqT76N3CTxmwMIJKKOFOkCgSNBuab/+e/f2zA4926qkK4lvVdEir2xx6PRme3xzhJNJInUElcGYLcZIkHJHed4nav5O7Ba/xz7HCrTqqtOf0kvs5rzPhqxC+C33M5HQ1aIQpyd9qAXqgGQAhw2tEegLxtDz9gIaIIFECFV0ReriWd2NRjntTYbaz4+3SIgMEu03z5vw+d5BRRBC9jqTre8NUAjEwmMBKSFhRcFOHXs4l7GHbIt8XeI8TpgeSi9UZmH4ZpeXqvy/chLrfxQB8O4J4+D0ct9qd6Dq03K1hEVkTNeQGKcGLNb1n53jWuhIOmAtOadF+dYpGOrjzre7yRuEg46ystyYddLJdytKJopK77bMEYwKxBSS+S6pnmR3cwahLrl+jr7GicCL+3Et57axLMxTXb2CcG0hwJCQ69ihEVO4dbTW6MRmfsrK2pX1hb1upul8cyS4lkWEUlQCpCmg==,iv:vygMsq1+zxUMHdu1+rtoZKWw4U2nkIm5Xd+r0S+Updk=,tag:KE5dpipxaMmear1UELtKsA==,type:str]
+nixos-key: ENC[AES256_GCM,data:IEAp3ic6GYgS9432X2u0TTS+uykDAjsZFeo64S48mqphUQe0R04xTUz8qa4/QhdeiZeBysK86D5Wk9V7T/RMRw/Fzb3E0+xdvwQy9b6IFAWOxKXziyJzZAJRoHYIjiV6TsmkuwG2/tc0pojo9JeFPJhRwtgOax45i2VAwcyw6OeSdNn49YHtL1T5R7t5SCWLaRP+55Vp5gnr1DvnVMr439kOvAVFNB/HZ0515lH9iOXU5QPkcINJ4Mj1zx2iI6O7xL61Y/HfDX7F4E2baQQmqDqsiiKHS5vmqs29NSG1pd1G/8l2CsLpxnKiwYR8r0LyGIbD3PmMQod5lvvW8MDzw+/R3IiTbcJIwhFewRBNXwhCYd90Zr3YgntuNU35DeQ8z5xuELNkjwLSKpTCV2AAAIgtQk/8fUXaTCNaHLL7ZAEAah3twDa5E0ggwf009HCvwTBI3/F8H1i1+YZpCtdBDMKY5ldKPyXhIWChW+YbfaiIu8C+U5Cm+TiDHEX0zGnU2oq36BUiwB7CGsSgkX4XUVxE6SzeZ1xEx5LrFnKDcIzTP0g=,iv:75Sp1pZbVDqW1oZjigMoxvIuCpvZmyImHV0wgKEPvvY=,tag:74/GHjpktd8fm5qnoe4DHA==,type:str]
+nixos-key-pub: ENC[AES256_GCM,data:NxnOa49ek2h8b4Fy1enRc+9l3+QEkqp9pUFWmJE9cw0/ACPbyqpNP259wINolwChbYA50Q5Oy30ix0Cvkw4CVxC1mwOHxk5z0wIKzNCBKIfxs9XzcNOT/Drc6Df3ycM4WU1jVXSFig==,iv:NflErE1TuZWTtGoWM3DOjWtdtCE/FYcIDtjhHSy+fJY=,tag:LYvz8rtNeDzLMmZU6s9FMQ==,type:str]
+amity-key: ENC[AES256_GCM,data:YOqI+DT9EXkQuLaepKXXG44CG95KZ/mUdmmwaizjpw3kFzZkCDbm+Wuau4gCM7Y/BX0J46ZHxU85jo7Sh0kOi84ZmxlU/fCc62P7woxhTbWRUmBsmjH+PeZ4XORXPKQxVkLNl+vdLZxI9nag2+xE00CC9FeOFUJB7qlOyG1Tjn7xr8XpPgvrYfy5qdhl2X2sZfnBCvDTJsfL5c5nceriJsFDgH7AHsvk0k7XvY9TlH/FFTrTZ9MWUeHP9K/0wHC7glvl86RX8ME87CmDRMOfXY/mua3e/5cEqfzHwxU1pt4npEu7m+5whlNCzeLZ7GgA3Mr03soKky0YBctdrP/dOvvbMD9M9nEgFBOSfodkwyYJsUFT8TvTFl4BqPm+IfmQkJV4sP9BqMQT3I5fKSqqUnkh4q2H1Xfk0YlKZhtQRz/a8tUR/I6t6z7c79KzeDKVBT1DgAyEXdAhyFjoOvQcJuOHHQkYvu/SYxdwPgCiItwio77izljy9yOn9Da2v5L88i/TmIkz3N7Ddh4SVSkmWXHxO6V4yN8Yvrd6pyeN3V+gLy1M95/isj8mjB9g4qaVOLhtYRjqEs66/Zu9OB9rhY+9uwCi2OOGKrb4ifnur25bNQPQEsd6o9oISIsqAxhuApcVyyR/mBMsZm0hl2QGo3Rn4kkpFRfqf9PwFSVltvdW5GrMUwc0OVau8ZMHxfypck7/Ti6FeLR2Y+LS6g3LnWsanpgy9V6xIAOqs6zh+n3zNp8yIH9QvEr/aICHeo9QZ0l9OcGIgWJmsBb0FCacSPIuS3jp5MTB6x7z4NEddmQNIB7GHydI7Ai5GhfePKAzwicX4ZkxTnjPX888gILv/YikrNhSJs8s6nhbKZ6HtlxI/rm0E6knKbNzP+WNdeJW+xgLJS55hXFhaOFDlSPalZ3KDYVDLOKjEliJffIGxpBZvbhZhdw80Y2Va3I6fuBchP1LT3LBlbgV7pJ8fhgvsidJYTieR9ciPSTO5bvXIRShP71txiJxDfI23NVXsKbAIMJWa0990co3HW3RsphRp02CU3XvWrq268CgfeC7QHvLV4GoVqX3uyOMPxEFtWBzC4I+TtgQc5MiA7Ox6U3ujVYs+F6iMopcmXGdzku56EbFu+RJsKcfnRaCqv/WR3JU9JRD9Uvux6iyhthIusaUu0t6LQ47eVSjcfC3p16bGLqjGxotvI2KWrKfqRjRTTpXDWIiLCf4J34vOyrLPZM5JeWzaZH7Muyo/3EJMBT7AKtREpZ/MggyRX6XLTrXNbx/u3ciidqLcKk8kRGiP2SB3c/FWlPUUDIHowZ/hMIXYBxZFIbfYmBBRKmRtWqqDdlPEAv/dy+T/HEocKbOGXUIF7XeujOVQePhXpd4Lo7trpEHh52MWselL0+3O2kFXMQBtwZl9pypZWlbimx04TCfl78Pi1kv0mMQ1CvsQscB/8OMGVv451z9/8ZOWt+kOdRM/nCbIR3UuufJ+0uao+iSqLDNlHhROoUrABbViffVHjhOaWAk+ITgzrVnVugqpV1K40M0uRoDwUe+9a/pdXe2QbbS4f86052dmwQioMuvkV00A09YbwWa4twKTifODMDwiD/AFNlgCSNyF4W47vhwNJ8HdgTsM0K1LRovi5ouSuanDtQ+KL5Ww1r+0blq9GybP9eIgvrSi7Y084Z8w5DQfCCsFS9gcqaA1Wx6/0XLzVmMAeEtY/LfkvKW+udX/yyCBXBwm/6rl8GAYpmJFGn2gVg0K/bKm1bgLXBtxg9Vc1dQb+m+7M+RAPb51msKSl7C7V5hPCQwBUyx6RNe7MbfQXURkTG8CsAW8hRprpLyYFohVyeEznfrjnIGyJ7rLbVSlprygr8jbCURyu4Qduq95PkXrWiUTqEpDZEhiF9IYxaLAPqckeSlRjw2clB8de0Ic4+8ptrlRA/qsJoJ52IGDMRiyuOQCNybrTr0ZXfezESfF8B+USSlXZFGCZeQb4qF1gHJByllEEtnFNds97gR2JdR5uewKQO/UOuKc8HjbQbGgFTToFtoA0OPM/BlJ2QXJkAsfl9tg8drjPuruOkNxtZqYOyG+KyzUOifx+3g8clUmf8B4RI+idWfGiLOYplMxnlnulQb9DIj0e3BHyRneMa3SdqyYqYB2yhHltppKn+nrsXtQ8H1CGuC6bYnmYtMbjpvaKkaNJZrnEQA8JkoK3gZV3vN/ArVN5+20mPGnnTc9YjmgF8xI/KSR/Q5OXVtBVRM4UbsKuPeypjQZzAFnwbOF9IK1O+BTIoM1+S3ocztLnXQ2AGN6RyG9+dI93svGTMbUb82+YzhZryRTkLwpR4OeGD6+ERk7yzM/DhX/mOytledOJ1FjAuWrNpc9hgyEHjPQxPwyPp5D1Jvnnl4HJNBuNKe786qwyP4IQf6FoT+K308CBTzi2doRsezxoZ6qjukAxi8HeekXe4GSo77GEk1GLr7Txjq7+5EI5jX6ctIBFj8sK8OLPQaq3miqkljaTlLC7ZQgljbuuVujNCG09W+FiekIhHfoBMgHJJeu4+llwNcxLxfE2qxt2AQScRvJV66HJbbW1Ar9h8jJq9jhO8y8h+ObWRRrfiKZ+TczvzpgGmSQGqXJLqc7zuNIisMyhFOZ3g+whreZNbytU7nTYh3A2/dZAtCa0WSzPQX6omnz2+KulfrteqRGG8+kjTFi217zqDFMUiMQbHnPt4fPKr36ut5XSLOy8NX4pjJhwy5y+rvWTKt+t2g5r4OvdJlLeXDZRl2+5hDz72ZtP4m+NfLaG5wrenm5upEK2xSxiLjGoFNa3Jm8jtu24KOLogYBnkZRZedQSNr9ZMs/hAiDnLLeJ+7SsgSkyhwO5O+Lzll1VbMMFuyyssZwRanmJnxt7epW8UY8b2PgjYuiyILWp9cjN85OmgGPHDU7kwWs5Sj0Z0NFevUjbe4k+1Hob12iP2yrFCc9DX4ff6YhEvHNww+6RmjV8MYpvDMb24zMXeyu2QYgT9izJ9M4byq/fZyq4GSZDiY2OtprudLbaQUCBAKD43gMG+1gSrS7n4oc/+CqNjNlxicgFoa0HoMdJg4s6OYOPl1QQZJ2+0fxTFIVFgznT7fu96CSwD/Oq/d3e/EgMah9yZKlUTKe8XNLDDFFEaX2DF9vhCsWeJ+QK/TD9jFAO3q8vY0XO3UE191lawBV4vvbwkpeawJjq0Kdsb5rvcxhHEzlVKheKN2WkH8RExhOhEDBLkbAruNZbYWm71qsEEvN1YNenXzr7LHBKETwQnavag7yChcGNNUE+kuwCaYbv8LwB04RBTuyC+dVqOiF8nX5U7VNpI3CCzj0Ny08jwRxnzT0OM7gv/csxCJ9rBd40m/EtW47Nt6GzKLHCXRfFOgQm3R39inSqz/K/fXiNQqkuQwcN9iMATnQXzTbCllOoUPyzvcz+T4eEXF23mFFO+ridibha2HdsgylPnAqXTweAjm0Tg/WQ==,iv:s7/Q+eQJpRnKLFKweNfI4NXM3TWm97KPDHIFu8cAwqM=,tag:HXJDO/YmKtZiUKhI0VSEuw==,type:str]
sops:
kms: []
gcp_kms: []
@@ -32,8 +42,8 @@ sops:
cDRpZkkxZWhiVmN1Y1FSRm5seVpmbnMKl7CHdNdXOr67tCjYp+jhUSYImndyvhQP
heUpcdBCJADlE9oG6lDr4ngwdHFqVrN757uMqZWEbT80hzZUXVRArw==
-----END AGE ENCRYPTED FILE-----
- lastmodified: "2023-08-18T19:45:59Z"
- mac: ENC[AES256_GCM,data:1dNhVFD2+V8tlIjC2/0X7m9cpBZAN7iIkSLqZJfeGYVBWreBS1Bst0n+jw41mCsM5KTz4S2jE559M+P552UAcqsYBCu7CmHtmBcLuGuouL3Nl0rlGsJLC+61O1/7bo2qg7OP+Bu9A40mtl8rSfCU4i4Axd3kBTN0Z+upNBG7f4M=,iv:sEymKxdswbUZweMw3xMpwdYZ/75vPGvtmVU7WZzlE2w=,tag:ZkAMomlWe+dg1Nsfel8FYw==,type:str]
+ lastmodified: "2023-10-26T22:09:17Z"
+ mac: ENC[AES256_GCM,data:nNAr/yIJ15akWZ+qQx4ax8LxNBjChkYstCKPzi89jAxmtRZNH1Io4zrDmNE4JWO4wjb9RYPtVlxeQkGZ0HeGAp5GfXnlEM8XtpMEPDfk6fLJ2yxPHdHwQs0BAdSB2QuAfDheGCJYlxSAyaUuN4EUlPHcbgFWBokdUb96JuPY1eM=,iv:wm9kq2S40pwXPCfFI2H/WwWGNofqB3PTYfxf2FSA3A0=,tag:9RPArhEwTYNEzBCX0UANSA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
- version: 3.7.3
+ version: 3.8.1
diff --git a/home/isabel/services/x11/default.nix b/modules/common/types/desktop/default.nix
similarity index 100%
rename from home/isabel/services/x11/default.nix
rename to modules/common/types/desktop/default.nix
diff --git a/modules/common/types/laptop/adb.nix b/modules/common/types/laptop/adb.nix
index 2c915b01e..ebdbf6f77 100644
--- a/modules/common/types/laptop/adb.nix
+++ b/modules/common/types/laptop/adb.nix
@@ -4,12 +4,10 @@
...
} @ args:
with lib; let
- device = config.modules.device;
+ inherit (config.modules) device;
in {
config = mkIf (device.type == "laptop" || device.type == "hybrid") {
services = {
- # TODO: move android adb rule elsewhere
- # this should probably be a device or programs option
udev.extraRules = let
inherit (import ./plugged.nix args) plugged unplugged;
in ''
diff --git a/modules/common/types/laptop/default.nix b/modules/common/types/laptop/default.nix
index 4328f787f..d3c6a3f2e 100644
--- a/modules/common/types/laptop/default.nix
+++ b/modules/common/types/laptop/default.nix
@@ -1,18 +1,7 @@
-{
- config,
- lib,
- ...
-}:
-with lib; let
- device = config.modules.device;
-in {
+_: {
imports = [
./power
./adb.nix
./touchpad.nix
];
-
- config =
- mkIf (device.type == "laptop" || device.type == "hybrid") {
- };
}
diff --git a/modules/common/types/laptop/power/default.nix b/modules/common/types/laptop/power/default.nix
index 7f47b5a06..408f4fd35 100644
--- a/modules/common/types/laptop/power/default.nix
+++ b/modules/common/types/laptop/power/default.nix
@@ -2,13 +2,16 @@
config,
lib,
pkgs,
+ inputs,
...
-} @ args:
-with lib; let
- device = config.modules.device;
+} @ args: let
+ inherit (lib) mkDefault mkIf;
+ inherit (config.modules) device;
MHz = x: x * 1000;
in {
+ imports = [inputs.auto-cpufreq.nixosModules.default];
+
config = mkIf (device.type == "laptop" || device.type == "hybrid") {
hardware.acpilight.enable = true;
@@ -17,10 +20,29 @@ in {
powertop
];
+ programs.auto-cpufreq = {
+ enable = true;
+ settings = {
+ battery = {
+ governor = "powersave";
+ scaling_min_freq = mkDefault (MHz 1200);
+ scaling_max_freq = mkDefault (MHz 1800);
+ turbo = "never";
+ };
+ charger = {
+ governor = "performance";
+ scaling_min_freq = mkDefault (MHz 1800);
+ scaling_max_freq = mkDefault (MHz 3000);
+ turbo = "auto";
+ };
+ };
+ };
+
services = {
- # superior power management
- auto-cpufreq.enable = true;
+ # handle ACPI events
+ acpid.enable = true;
+ # a very cool user-selected power profiles helping my system not die 5 mins into my lecture
power-profiles-daemon.enable = true;
# temperature target on battery
@@ -29,6 +51,10 @@ in {
package = pkgs.undervolt;
};
+ /*
+ # superior power management
+ auto-cpufreq.enable = true;
+
auto-cpufreq.settings = {
battery = {
governor = "powersave";
@@ -43,6 +69,7 @@ in {
turbo = "auto";
};
};
+ */
# DBus service that provides power management support to applications.
upower = {
@@ -63,11 +90,12 @@ in {
};
boot = {
kernelModules = ["acpi_call"];
- extraModulePackages = with config.boot.kernelPackages; [
- acpi_call
- cpupower
- pkgs.cpupower-gui
- ];
+ extraModulePackages = with config.boot.kernelPackages;
+ [
+ acpi_call
+ cpupower
+ ]
+ ++ [pkgs.cpupower-gui];
};
};
}
diff --git a/modules/common/types/laptop/touchpad.nix b/modules/common/types/laptop/touchpad.nix
index b1b42d8ef..1d9592bd7 100644
--- a/modules/common/types/laptop/touchpad.nix
+++ b/modules/common/types/laptop/touchpad.nix
@@ -2,29 +2,30 @@
config,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.modules) device;
in {
- # TODO: touchpads shouldn't be enabled on *all* hybrid devices (server/personal)
- # this should be an option under the device module
- config = mkIf (device.type == "laptop" || device.type == "hybrid") {
+ config = lib.mkIf (device.type == "laptop" || device.type == "hybrid") {
services = {
# Input settings for libinput
xserver.libinput = {
enable = true;
- # disable mouse acceleration
- mouse.accelProfile = "flat";
- mouse.accelSpeed = "0";
- mouse.middleEmulation = false;
+ # disable mouse acceleration (yes im gamer)
+ mouse = {
+ accelProfile = "flat";
+ accelSpeed = "0";
+ middleEmulation = false;
+ };
# touchpad settings
- touchpad.naturalScrolling = true;
- touchpad.tapping = true;
- touchpad.clickMethod = "clickfinger";
- touchpad.horizontalScrolling = false;
- touchpad.disableWhileTyping = true;
+ touchpad = {
+ naturalScrolling = true;
+ tapping = true;
+ clickMethod = "clickfinger";
+ horizontalScrolling = false;
+ disableWhileTyping = true;
+ };
};
};
};
diff --git a/modules/common/types/server/default.nix b/modules/common/types/server/default.nix
index 32d413966..e6eb35f38 100644
--- a/modules/common/types/server/default.nix
+++ b/modules/common/types/server/default.nix
@@ -1,53 +1,6 @@
-{
- config,
- lib,
- ...
-}: let
- inherit (lib) mkIf;
- inherit (config.modules) device;
- acceptedTypes = ["server"];
-in {
+_: {
imports = [
./services
./system
];
-
- config = mkIf (builtins.elem device.type acceptedTypes) {
- sound.enable = false;
- environment = {
- # we don't need any x libs on a server
- # noXlibs = true;
-
- # print the URL instead on servers
- variables.BROWSER = "echo";
- };
-
- # https://github.com/numtide/srvos/blob/main/nixos/server/default.nix
- systemd = {
- # given that our systems are headless, emergency mode is useless.
- # we prefer the system to attempt to continue booting so
- # that we can hopefully still access it remotely.
- enableEmergencyMode = false;
-
- # For more detail, see:
- # https://0pointer.de/blog/projects/watchdog.html
- watchdog = {
- # systemd will send a signal to the hardware watchdog at half
- # the interval defined here, so every 10s.
- # If the hardware watchdog does not get a signal for 20s,
- # it will forcefully reboot the system.
- runtimeTime = "20s";
- # Forcefully reboot if the final stage of the reboot
- # hangs without progress for more than 30s.
- # For more info, see:
- # https://utcc.utoronto.ca/~cks/space/blog/linux/SystemdShutdownWatchdog
- rebootTime = "30s";
- };
-
- sleep.extraConfig = ''
- AllowSuspend=no
- AllowHibernation=no
- '';
- };
- };
}
diff --git a/modules/common/types/server/services/cloudflare/default.nix b/modules/common/types/server/services/cloudflared/default.nix
similarity index 62%
rename from modules/common/types/server/services/cloudflare/default.nix
rename to modules/common/types/server/services/cloudflared/default.nix
index 2ab402d6d..2153ab12e 100644
--- a/modules/common/types/server/services/cloudflare/default.nix
+++ b/modules/common/types/server/services/cloudflared/default.nix
@@ -4,15 +4,15 @@
...
}: let
inherit (lib) mkIf;
+ inherit (config.networking) domain;
in {
- services.cloudflared = mkIf (config.modules.services.cloudflare.enable) {
+ services.cloudflared = mkIf (config.modules.services.cloudflared.enable) {
enable = true;
- user = "${config.modules.system.mainUser}";
- tunnels."${config.modules.services.cloudflare.id}" = {
+ tunnels.${config.networking.hostName} = {
credentialsFile = "${config.sops.secrets.cloudflared-hydra.path}";
default = "http_status:404";
ingress = {
- "tv.isabelroses.com" = "http://localhost:8096";
+ "tv.${domain}" = "http://localhost:8096";
};
};
};
diff --git a/modules/common/types/server/services/containers/default.nix b/modules/common/types/server/services/containers/default.nix
new file mode 100644
index 000000000..b3456eeb2
--- /dev/null
+++ b/modules/common/types/server/services/containers/default.nix
@@ -0,0 +1,29 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ cfg = config.modules.services;
+in {
+ virtualisation.oci-containers = {
+ backend = "docker"; # podman hates this image
+
+ containers = {
+ "isabelroses-com" = lib.mkIf cfg.isabelroses-web.enable {
+ image = "docker.io/isabelroses/isabelroses.com:latest";
+ ports = ["3000:3000"];
+ extraOptions = [
+ "--pull=newer"
+ ];
+ environmentFiles = [
+ config.sops.secrets.isabelroses-web-env.path
+ ];
+ login = {
+ registry = "docker.io";
+ username = "isabelroses";
+ passwordFile = config.sops.secrets.docker-hub.path;
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/cyberchef/default.nix b/modules/common/types/server/services/cyberchef/default.nix
new file mode 100644
index 000000000..5e7f1dec5
--- /dev/null
+++ b/modules/common/types/server/services/cyberchef/default.nix
@@ -0,0 +1,24 @@
+{
+ self,
+ lib,
+ config,
+ pkgs,
+ ...
+}: let
+ inherit (config.networking) domain;
+in {
+ services.nginx.virtualHosts."chef.${domain}" = lib.mkIf config.modules.services.cyberchef.enable {
+ default = true;
+ forceSSL = true;
+ enableACME = true;
+ listen = [
+ {
+ ssl = false;
+ port = 8000;
+ addr = "127.0.0.1";
+ }
+ ];
+ root = self.packages.${pkgs.hostPlatform.system}.cyberchef;
+ };
+ networking.firewall.allowedTCPPorts = [8000];
+}
diff --git a/modules/common/types/server/services/databases/default.nix b/modules/common/types/server/services/databases/default.nix
new file mode 100644
index 000000000..8d3d569f2
--- /dev/null
+++ b/modules/common/types/server/services/databases/default.nix
@@ -0,0 +1,8 @@
+_: {
+ imports = [
+ ./mongodb
+ ./postgresql
+ ./mysql
+ ./redis
+ ];
+}
diff --git a/modules/common/types/server/services/databases/mongodb/default.nix b/modules/common/types/server/services/databases/mongodb/default.nix
new file mode 100644
index 000000000..faca428d2
--- /dev/null
+++ b/modules/common/types/server/services/databases/mongodb/default.nix
@@ -0,0 +1,25 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ dev = config.modules.device;
+ cfg = config.modules.services;
+ acceptedTypes = ["server" "hybrid"];
+in {
+ config = mkIf ((builtins.elem dev.type acceptedTypes) && cfg.database.mongodb.enable) {
+ services.mongodb = {
+ enable = true;
+ package = pkgs.mongodb;
+ enableAuth = true;
+ initialRootPassword = config.sops.secrets.mongodb-passwd.path;
+ #bind_ip = "0.0.0.0";
+ extraConfig = ''
+ operationProfiling.mode: all
+ '';
+ };
+ };
+}
diff --git a/modules/common/types/server/services/databases/mysql/default.nix b/modules/common/types/server/services/databases/mysql/default.nix
new file mode 100644
index 000000000..cc31916de
--- /dev/null
+++ b/modules/common/types/server/services/databases/mysql/default.nix
@@ -0,0 +1,30 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ dev = config.modules.device;
+ cfg = config.modules.services;
+ acceptedTypes = ["server" "hybrid"];
+in {
+ config = mkIf ((builtins.elem dev.type acceptedTypes) && cfg.database.mysql.enable) {
+ services.mysql = {
+ enable = true;
+ package = pkgs.mariadb;
+
+ # databases and users
+ ensureDatabases = ["mkm"];
+ ensureUsers = [
+ {
+ name = "mkm";
+ ensurePermissions = {
+ "mkm.*" = "ALL PRIVILEGES";
+ };
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/common/types/server/services/databases/postgresql/default.nix b/modules/common/types/server/services/databases/postgresql/default.nix
new file mode 100644
index 000000000..ff8acb966
--- /dev/null
+++ b/modules/common/types/server/services/databases/postgresql/default.nix
@@ -0,0 +1,60 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ dev = config.modules.device;
+ cfg = config.modules.services;
+ acceptedTypes = ["server" "hybrid"];
+in {
+ config = mkIf ((builtins.elem dev.type acceptedTypes) && cfg.database.postgresql.enable) {
+ services.postgresql = {
+ enable = true;
+ package = pkgs.postgresql;
+ dataDir = "/srv/storage/postgresql/${config.services.postgresql.package.psqlSchema}";
+
+ enableTCPIP = false;
+
+ checkConfig = true;
+ settings = {
+ log_connections = true;
+ log_statement = "all";
+ logging_collector = true;
+ log_disconnections = true;
+ log_destination = lib.mkForce "syslog";
+ };
+
+ ensureDatabases = [
+ "nextcloud"
+ "forgejo"
+ "grafana"
+ "vaultwarden"
+ ];
+ ensureUsers = [
+ {
+ name = "postgres";
+ ensurePermissions."ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
+ }
+ {
+ name = "forgejo";
+ ensurePermissions."DATABASE forgejo" = "ALL PRIVILEGES";
+ }
+ {
+ name = "grafana";
+ ensurePermissions."DATABASE grafana" = "ALL PRIVILEGES";
+ }
+ {
+ name = "nextcloud";
+ ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
+ }
+ {
+ name = "vaultwarden";
+ ensurePermissions."DATABASE vaultwarden" = "ALL PRIVILEGES";
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/common/types/server/services/databases/redis/default.nix b/modules/common/types/server/services/databases/redis/default.nix
new file mode 100644
index 000000000..e0b7999a8
--- /dev/null
+++ b/modules/common/types/server/services/databases/redis/default.nix
@@ -0,0 +1,40 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ cfg = config.modules.services;
+in {
+ config = mkIf cfg.database.redis.enable {
+ services.redis = {
+ vmOverCommit = true;
+ servers = {
+ nextcloud = mkIf cfg.nextcloud.enable {
+ enable = true;
+ user = "nextcloud";
+ port = 0;
+ };
+
+ forgejo = mkIf cfg.forgejo.enable {
+ enable = true;
+ user = "forgejo";
+ port = 6371;
+ databases = 16;
+ logLevel = "debug";
+ requirePass = "forgejo";
+ };
+
+ searxng = mkIf cfg.searxng.enable {
+ enable = true;
+ user = "searx";
+ port = 6370;
+ databases = 16;
+ logLevel = "debug";
+ requirePass = "searxng";
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/default.nix b/modules/common/types/server/services/default.nix
index 67b234ee8..e486ef9d3 100644
--- a/modules/common/types/server/services/default.nix
+++ b/modules/common/types/server/services/default.nix
@@ -1,11 +1,19 @@
_: {
imports = [
- ./cloudflare
- ./gitea
+ ./cloudflared
+ ./containers
+ ./cyberchef
+ ./databases
+ ./forgejo
./jellyfin
./mailserver
+ ./matrix
+ ./miniflux
+ ./monitoring
+ ./nextcloud
./nginx
./photoprism
./vaultwarden
+ ./wakatime
];
}
diff --git a/modules/common/types/server/services/forgejo/default.nix b/modules/common/types/server/services/forgejo/default.nix
new file mode 100644
index 000000000..dd2948754
--- /dev/null
+++ b/modules/common/types/server/services/forgejo/default.nix
@@ -0,0 +1,147 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.modules.services.forgejo;
+ inherit (config.networking) domain;
+ forgejo_domain = "git.${domain}";
+
+ # stole this from https://git.winston.sh/winston/deployment-flake/src/branch/main/config/services/gitea.nix who stole it from https://github.com/getchoo
+ theme = pkgs.fetchzip {
+ url = "https://github.com/catppuccin/gitea/releases/download/v0.4.1/catppuccin-gitea.tar.gz";
+ sha256 = "sha256-14XqO1ZhhPS7VDBSzqW55kh6n5cFZGZmvRCtMEh8JPI=";
+ stripRoot = false;
+ };
+in {
+ config = mkIf cfg.enable {
+ networking.firewall.allowedTCPPorts = [
+ config.services.forgejo.settings.server.HTTP_PORT
+ config.services.forgejo.settings.server.SSH_PORT
+ ];
+
+ modules.services.database = {
+ redis.enable = true;
+ postgresql.enable = true;
+ };
+
+ systemd.services = {
+ forgejo = {
+ after = ["sops-nix.service"];
+ preStart = let
+ inherit (config.services.forgejo) stateDir;
+ in
+ lib.mkAfter ''
+ rm -rf ${stateDir}/custom/public
+ mkdir -p ${stateDir}/custom/public
+ ln -sf ${theme} ${stateDir}/custom/public/css
+ '';
+ };
+ };
+
+ services = {
+ forgejo = {
+ enable = true;
+ package = pkgs.forgejo;
+ stateDir = "/srv/storage/forgejo/data";
+ lfs.enable = true;
+
+ mailerPasswordFile = config.sops.secrets.mailserver-git-nohash.path;
+
+ settings = {
+ server = {
+ ROOT_URL = "https://${forgejo_domain}";
+ HTTP_PORT = 7000;
+ DOMAIN = "${forgejo_domain}";
+
+ BUILTIN_SSH_SERVER_USER = "git";
+ DISABLE_ROUTER_LOG = true;
+ LANDING_PAGE = "/explore/repos";
+
+ START_SSH_SERVER = true;
+ SSH_CREATE_AUTHORIZED_KEYS_FILE = true;
+ SSH_PORT = 2222;
+ SSH_LISTEN_PORT = 2222;
+ };
+
+ api.ENABLE_SWAGGER = false;
+
+ default.APP_NAME = "iztea";
+ attachment.ALLOWED_TYPES = "*/*";
+
+ ui = {
+ DEFAULT_THEME = "catppuccin-mocha-sapphire";
+ THEMES =
+ builtins.concatStringsSep
+ ","
+ (["auto,forgejo-auto,forgejo-dark,forgejo-light,arc-gree,gitea"]
+ ++ (map (name: lib.removePrefix "theme-" (lib.removeSuffix ".css" name))
+ (builtins.attrNames (builtins.readDir theme))));
+ };
+
+ # "ui.meta" = {
+ # AUTHOR = "Isabel Roses";
+ # DESCRIPTION = "A super cool place to host git repos";
+ # KEYWORDS = "git,self-hosted,gitea,forgejo,isabelroses,catppuccin,open-source,nix,nixos";
+ # };
+
+ actions = {
+ ENABLED = true;
+ DEFAULT_ACTIONS_URL = "https://code.forgejo.org";
+ };
+
+ database = {
+ DB_TYPE = lib.mkForce "postgres";
+ HOST = "/run/postgresql";
+ NAME = "forgejo";
+ USER = "forgejo";
+ PASSWD = "forgejo";
+ };
+
+ cache = {
+ ENABLED = true;
+ ADAPTER = "redis";
+ HOST = "redis://:forgejo@localhost:6371";
+ };
+
+ service = {
+ DISABLE_REGISTRATION = true;
+ EMAIL_DOMAIN_ALLOWLIST = "isabelroses.com";
+ };
+
+ other = {
+ SHOW_FOOTER_VERSION = false;
+ SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
+ ENABLE_FEED = false;
+ };
+
+ migrations.ALLOWED_DOMAINS = "github.com, *.github.com, gitlab.com, *.gitlab.com";
+ packages.ENABLED = false;
+ repository.PREFERRED_LICENSES = "MIT,GPL-3.0,GPL-2.0,LGPL-3.0,LGPL-2.1";
+
+ "repository.upload" = {
+ FILE_MAX_SIZE = 100;
+ MAX_FILES = 10;
+ };
+
+ mailer = {
+ ENABLED = true;
+ PROTOCOL = "smtps";
+ SMTP_ADDR = "mail.${domain}";
+ USER = "git@${domain}";
+ };
+ };
+
+ # backup
+ dump = {
+ enable = true;
+ backupDir = "/srv/storage/forgejo/dump";
+ interval = "06:00";
+ type = "tar.zst";
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/gitea/default.nix b/modules/common/types/server/services/gitea/default.nix
deleted file mode 100644
index dbbc32da2..000000000
--- a/modules/common/types/server/services/gitea/default.nix
+++ /dev/null
@@ -1,79 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- device = config.modules.device;
- acceptedTypes = ["server" "hybrid"];
- cfg = config.modules.services.gitea;
- domain = "git.isabelroses.com";
-in {
- config = mkIf (builtins.elem device.type acceptedTypes && cfg.enable) {
- networking.firewall.allowedTCPPorts = [config.services.gitea.settings.server.HTTP_PORT];
-
- services = {
- gitea = {
- enable = true;
- package = pkgs.forgejo;
- appName = "iztea";
- lfs.enable = true;
- user = "git";
- database.user = "git";
- stateDir = "/srv/storage/gitea/data";
-
- mailerPasswordFile = config.sops.secrets.mailserver-gitea.path;
- dump = {
- enable = true;
- backupDir = "/srv/storage/gitea/dump";
- interval = "06:00";
- type = "tar.zst";
- };
-
- settings = {
- server = {
- ROOT_URL = "https://${domain}";
- HTTP_PORT = 7000;
- DOMAIN = "${domain}";
-
- START_SSH_SERVER = false;
- BUILTIN_SSH_SERVER_USER = "git";
- SSH_PORT = 22;
- DISABLE_ROUTER_LOG = true;
- SSH_CREATE_AUTHORIZED_KEYS_FILE = true;
- LANDING_PAGE = "/explore/repos";
- };
-
- attachment.ALLOWED_TYPES = "*/*";
- service.DISABLE_REGISTRATION = true;
- ui.DEFAULT_THEME = "arc-green";
- migrations.ALLOWED_DOMAINS = "github.com, *.github.com, gitlab.com, *.gitlab.com";
- packages.ENABLED = false;
- repository.PREFERRED_LICENSES = "MIT,GPL-3.0,GPL-2.0,LGPL-3.0,LGPL-2.1";
-
- "repository.upload" = {
- FILE_MAX_SIZE = 100;
- MAX_FILES = 10;
- };
-
- mailer = {
- ENABLED = true;
- PROTOCOL = "smtps";
- SMTP_ADDR = "mail.isabelroses.com";
- USER = "gitea@isabelroses.com";
- };
- };
- };
-
- openssh = {
- extraConfig = ''
- Match User git
- AuthorizedKeysCommandUser git
- AuthorizedKeysCommand ${lib.getExe pkgs.forgejo} keys -e git -u %u -t %t -k %k
- Match all
- '';
- };
- };
- };
-}
diff --git a/modules/common/types/server/services/jellyfin/default.nix b/modules/common/types/server/services/jellyfin/default.nix
index 8bf784379..f4d6701ae 100644
--- a/modules/common/types/server/services/jellyfin/default.nix
+++ b/modules/common/types/server/services/jellyfin/default.nix
@@ -4,40 +4,14 @@
...
}: let
inherit (lib) mkIf;
- device = config.modules.device;
cfg = config.modules.services.jellyfin;
- acceptedTypes = ["server" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && cfg.enable) {
- # NOT docker
- services = mkIf (!cfg.asDockerContainer) {
- jellyfin = {
- enable = true;
- group = "jellyfin";
- user = "jellyfin";
- openFirewall = true;
- };
- };
-
- # with docker
- modules.system.virtualization = mkIf (cfg.asDockerContainer) {
+ config = mkIf cfg.enable {
+ services.jellyfin = {
enable = true;
- docker.enable = true;
- };
-
- virtualisation.oci-containers.containers.jellyfin = mkIf (cfg.asDockerContainer) {
- image = "lscr.io/linuxserver/jellyfin:latest";
- environment = {
- "PUID" = "1000";
- "PGID" = "1000";
- "TZ" = "Europe/London";
- };
- volumes = [
- "/home/isabel/docker/jellyfin:/config"
- "/mnt/media:/data"
- ];
- ports = ["8096:8096"];
- autoStart = true;
+ group = "jellyfin";
+ user = "jellyfin";
+ openFirewall = true;
};
};
}
diff --git a/modules/common/types/server/services/mailserver/default.nix b/modules/common/types/server/services/mailserver/default.nix
index f61e59bbf..2c7e534f1 100644
--- a/modules/common/types/server/services/mailserver/default.nix
+++ b/modules/common/types/server/services/mailserver/default.nix
@@ -4,45 +4,64 @@
pkgs,
inputs,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.networking) domain;
cfg = config.modules.services.mailserver;
- acceptedTypes = ["server" "hybrid"];
in {
imports = [
inputs.simple-nixos-mailserver.nixosModule
];
- config = mkIf (builtins.elem device.type acceptedTypes && cfg.enable) {
+ config = lib.mkIf cfg.enable {
# required for roundcube
networking.firewall.allowedTCPPorts = [80 443];
+ systemd.services = let
+ template = {after = ["sops-nix.service"];};
+ in {
+ roundcube = template;
+ mailserver = template;
+ };
+
services = {
roundcube = {
enable = true;
+
+ package = pkgs.roundcube.withPlugins (
+ plugins:
+ with plugins; [
+ persistent_login
+ # carddav
+ ]
+ );
+
database.username = "roundcube";
maxAttachmentSize = 50;
+
dicts = with pkgs.aspellDicts; [en];
- # this is the url of the vhost, not necessarily the same as the fqdn of
- # the mailserver
- hostName = "webmail.isabelroses.com";
+
+ plugins = [
+ # "carddav"
+ "persistent_login"
+ ];
+
+ # this is the url of the vhost, not necessarily the same as the fqdn of the mailserver
+ hostName = "webmail.${domain}";
extraConfig = ''
$config['imap_host'] = array(
- 'tls://mail.isabelroses.com' => "Isabelroses's Mail Server",
+ 'ssl://${config.mailserver.fqdn}' => "Isabelroses's Mail Server",
'ssl://imap.gmail.com:993' => 'Google Mail',
);
$config['username_domain'] = array(
- 'mail.isabelroses.com' => 'isabelroses.com',
+ '${config.mailserver.fqdn}' => '${domain}',
'mail.gmail.com' => 'gmail.com',
);
$config['x_frame_options'] = false;
# starttls needed for authentication, so the fqdn required to match
# the certificate
- $config['smtp_host'] = "tls://${config.mailserver.fqdn}";
+ $config['smtp_host'] = "ssl://${config.mailserver.fqdn}";
$config['smtp_user'] = "%u";
$config['smtp_pass'] = "%p";
- $config['plugins'] = [ "carddav" ];
'';
};
@@ -54,17 +73,12 @@ in {
"blacklist.woody.ch"
];
dnsBlacklistOverrides = ''
- isabelroses.com OK
- mail.isabelroses.com OK
+ ${domain} OK
+ ${config.mailserver.fqdn} OK
127.0.0.0/8 OK
+ 10.0.0.0/8 OK
192.168.0.0/16 OK
'';
- headerChecks = [
- {
- action = "IGNORE";
- pattern = "/^User-Agent.*Roundcube Webmail/";
- }
- ];
config = {
smtp_helo_name = config.mailserver.fqdn;
@@ -79,9 +93,11 @@ in {
mailserver = {
enable = true;
- mailDirectory = "/srv/storage/mail/vmail";
- dkimKeyDirectory = "/srv/storage/mail/dkim";
- sieveDirectory = "/srv/storage/mail/sieve";
+ # make sure the perms here is
+ # /srv/storage/mail/ # 775
+ mailDirectory = "/srv/storage/mail/vmail"; # 770
+ dkimKeyDirectory = "/srv/storage/mail/dkim"; # 775
+ sieveDirectory = "/srv/storage/mail/sieve"; # 770
openFirewall = true;
enableImap = true;
enableImapSsl = true;
@@ -91,24 +107,52 @@ in {
enableSubmissionSsl = true;
hierarchySeparator = "/";
localDnsResolver = false;
- fqdn = "mail.isabelroses.com";
+ fqdn = "mail.${domain}";
certificateScheme = "acme-nginx";
- domains = ["isabelroses.com"];
+ domains = ["${domain}"];
loginAccounts = {
- "isabel@isabelroses.com" = {
+ "isabel@${domain}" = {
hashedPasswordFile = config.sops.secrets.mailserver-isabel.path;
- aliases = ["isabel" "me@isabelroses.com" "admin" "admin@isabelroses.com" "root" "root@isabelroses.com" "postmaster" "postmaster@isabelroses.com"];
+ aliases = [
+ "isabel"
+ "isabelroses"
+ "isabelroses@${domain}"
+ "bell"
+ "bell@${domain}"
+ "me@${domain}"
+ "admin"
+ "admin@${domain}"
+ "root"
+ "root@${domain}"
+ "postmaster"
+ "postmaster@${domain}"
+ ];
};
- "gitea@isabelroses.com" = {
- aliases = ["gitea"];
- hashedPasswordFile = config.sops.secrets.mailserver-gitea.path;
+ "git@${domain}" = {
+ aliases = ["git" "git@${domain}"];
+ hashedPasswordFile = config.sops.secrets.mailserver-git.path;
};
- "vaultwarden@isabelroses.com" = {
- aliases = ["vaultwarden"];
+ "vaultwarden@${domain}" = {
+ aliases = ["vaultwarden" "bitwarden" "bitwarden@${domain}"];
hashedPasswordFile = config.sops.secrets.mailserver-vaultwarden.path;
};
+
+ "grafana@${domain}" = {
+ aliases = ["grafana" "monitor" "monitor@${domain}"];
+ hashedPasswordFile = config.sops.secrets.mailserver-grafana.path;
+ };
+
+ "noreply@${domain}" = {
+ aliases = ["noreply"];
+ hashedPasswordFile = config.sops.secrets.mailserver-noreply.path;
+ };
+
+ "spam@${domain}" = {
+ aliases = ["spam" "shush" "shush@${domain}" "stfu" "stfu@${domain}"];
+ hashedPasswordFile = config.sops.secrets.mailserver-spam.path;
+ };
};
mailboxes = {
diff --git a/modules/common/types/server/services/matrix/default.nix b/modules/common/types/server/services/matrix/default.nix
new file mode 100644
index 000000000..1d314aec1
--- /dev/null
+++ b/modules/common/types/server/services/matrix/default.nix
@@ -0,0 +1,156 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf;
+ inherit (config.networking) domain;
+
+ cfg = config.modules.services;
+
+ port = 8008;
+ bindAddress = "::1";
+ serverConfig."m.server" = "${config.services.matrix-synapse.settings.server_name}:443";
+ clientConfig = {
+ "m.homeserver".base_url = "https://${config.networking.hostName}${domain}";
+ "m.identity_server" = {};
+ };
+
+ mkWellKnown = data: ''
+ add_header Content-Type application/json;
+ add_header Access-Control-Allow-Origin *;
+ add_header 'Referrer-Policy' 'origin-when-cross-origin';
+ add_header X-Frame-Options DENY;
+ add_header X-Content-Type-Options nosniff;
+ return 200 '${builtins.toJSON data}';
+ '';
+in {
+ config = mkIf cfg.matrix.enable {
+ networking.firewall.allowedTCPPorts = [port];
+
+ services = {
+ postgresql = {
+ enable = true;
+ initialScript = pkgs.writeText "synapse-init.sql" ''
+ CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
+ CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
+ TEMPLATE template0
+ LC_COLLATE = "C"
+ LC_CTYPE = "C";
+ '';
+ };
+
+ nginx.virtualHosts = {
+ "${domain}" = {
+ locations = {
+ "= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
+ "= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
+ "/_matrix".proxyPass = "http://[${bindAddress}]:${toString port}";
+ "/_synapse/client".proxyPass = "http://[${bindAddress}]:${toString port}";
+ };
+ };
+ };
+
+ matrix-synapse = {
+ enable = true;
+
+ extraConfigFiles = [config.sops.secrets.matrix.path];
+ settings = {
+ withJemalloc = true;
+ enable_registration = true;
+ registration_requires_token = true;
+
+ bcrypt_rounds = 14;
+
+ # Don't report anonymized usage statistics
+ report_stats = false;
+
+ /*
+ # db
+ database = {
+ name = "psycopg2";
+ args = {
+ user = "matrix-synapse";
+ database = "matrix-synapse";
+ };
+ };
+ */
+ server_name = domain;
+ public_baseurl = "https://${domain}";
+
+ # media
+ media_retention.remote_media_lifetime = "30d";
+ max_upload_size = "100M";
+ url_preview_enabled = true;
+ url_preview_ip_range_blacklist = [
+ "127.0.0.0/8"
+ "10.0.0.0/8"
+ "172.16.0.0/12"
+ "192.168.0.0/16"
+ "100.64.0.0/10"
+ "192.0.0.0/24"
+ "169.254.0.0/16"
+ "192.88.99.0/24"
+ "198.18.0.0/15"
+ "192.0.2.0/24"
+ "198.51.100.0/24"
+ "203.0.113.0/24"
+ "224.0.0.0/4"
+ "::1/128"
+ "fe80::/10"
+ "fc00::/7"
+ "2001:db8::/32"
+ "ff00::/8"
+ "fec0::/10"
+ ];
+
+ # listener configuration
+ listeners = [
+ {
+ inherit port;
+ bind_addresses = ["${bindAddress}"];
+ resources = [
+ {
+ names = ["client" "federation"];
+ compress = true;
+ }
+ ];
+ tls = false;
+ type = "http";
+ x_forwarded = true;
+ }
+ ];
+
+ logConfig = ''
+ version: 1
+
+ # In systemd's journal, loglevel is implicitly stored, so let's omit it
+ # from the message text.
+ formatters:
+ journal_fmt:
+ format: '%(name)s: [%(request)s] %(message)s'
+
+ filters:
+ context:
+ (): synapse.util.logcontext.LoggingContextFilter
+ request: ""
+
+ handlers:
+ journal:
+ class: systemd.journal.JournalHandler
+ formatter: journal_fmt
+ filters: [context]
+ SYSLOG_IDENTIFIER: synapse
+
+ root:
+ level: WARNING
+ handlers: [journal]
+
+ disable_existing_loggers: False
+ '';
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/miniflux/default.nix b/modules/common/types/server/services/miniflux/default.nix
new file mode 100644
index 000000000..4085471ac
--- /dev/null
+++ b/modules/common/types/server/services/miniflux/default.nix
@@ -0,0 +1,89 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ cfg = config.modules.services;
+in {
+ config = mkIf cfg.miniflux.enable {
+ # https://github.com/Gerg-L/nixos/blob/master/hosts/gerg-desktop/services/miniflux.nix
+
+ systemd.services = {
+ miniflux = {
+ description = "Miniflux service";
+ wantedBy = ["multi-user.target"];
+ requires = ["miniflux-dbsetup.service"];
+ after = ["network.target" "postgresql.service" "miniflux-dbsetup.service"];
+ script = lib.getExe' pkgs.miniflux "miniflux";
+
+ serviceConfig = {
+ User = "miniflux";
+ RuntimeDirectory = "miniflux";
+ RuntimeDirectoryMode = "0770";
+ EnvironmentFile = config.sops.secrets.miniflux-env.path;
+
+ # Hardening
+ CapabilityBoundingSet = [""];
+ DeviceAllow = [""];
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ PrivateDevices = true;
+ PrivateUsers = true;
+ ProcSubset = "pid";
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectProc = "invisible";
+ RestrictAddressFamilies = ["AF_INET" "AF_INET6" "AF_UNIX"];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallArchitectures = "native";
+ SystemCallFilter = ["@system-service" "~@privileged"];
+ UMask = "0077";
+ };
+
+ environment = {
+ BASE_URL = "https://flux.isabelroses.com";
+ LISTEN_ADDR = "/run/miniflux/miniflux.sock";
+ DATABASE_URL = "user=miniflux host=/run/postgresql dbname=miniflux";
+ RUN_MIGRATIONS = "1";
+ CREATE_ADMIN = "1";
+ };
+ };
+ miniflux-dbsetup = {
+ description = "Miniflux database setup";
+ requires = ["postgresql.service"];
+ after = ["network.target" "postgresql.service"];
+ script = ''
+ ${lib.getExe' config.services.postgresql.package "psql"} "miniflux" -c "CREATE EXTENSION IF NOT EXISTS hstore"
+ '';
+ serviceConfig = {
+ Type = "oneshot";
+ User = config.services.postgresql.superUser;
+ };
+ };
+ };
+ users = {
+ groups.miniflux = {
+ gid = 377;
+ };
+ users = {
+ miniflux = {
+ group = "miniflux";
+ extraGroups = ["postgres"];
+ isSystemUser = true;
+ uid = 377;
+ };
+ ${config.services.nginx.user}.extraGroups = ["miniflux"];
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/monitoring/default.nix b/modules/common/types/server/services/monitoring/default.nix
new file mode 100644
index 000000000..2d4770acc
--- /dev/null
+++ b/modules/common/types/server/services/monitoring/default.nix
@@ -0,0 +1,6 @@
+_: {
+ imports = [
+ ./grafana
+ ./prometheus
+ ];
+}
diff --git a/modules/common/types/server/services/monitoring/grafana/default.nix b/modules/common/types/server/services/monitoring/grafana/default.nix
new file mode 100644
index 000000000..ad0cbd8d3
--- /dev/null
+++ b/modules/common/types/server/services/monitoring/grafana/default.nix
@@ -0,0 +1,73 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf;
+ inherit (config.networking) domain;
+
+ cfg = config.modules.services.monitoring.grafana;
+
+ port = 3100;
+in {
+ config = mkIf cfg.enable {
+ networking.firewall.allowedTCPPorts = [port];
+
+ services.grafana = {
+ enable = true;
+ settings = {
+ analytics = {
+ reporting_enabled = false;
+ check_for_updates = false;
+ };
+
+ server = {
+ http_port = port;
+ http_addr = "0.0.0.0";
+ domain = "graph.${domain}";
+ enforce_domain = true;
+ };
+
+ "auth.anonymous".enabled = false;
+ "auth.basic".enabled = false;
+
+ users = {
+ allow_signup = false;
+ };
+
+ database = {
+ type = "postgres";
+ host = "/run/postgresql";
+ name = "grafana";
+ user = "grafana";
+ ssl_mode = "disable";
+ };
+
+ smtp = let
+ mailer = "grafana@${domain}";
+ in {
+ enabled = true;
+
+ user = mailer;
+ password = "$__file{" + config.sops.secrets.mailserver-grafana-nohash.path + "}";
+
+ host = "mail.${domain}:465";
+ from_address = mailer;
+ startTLS_policy = "MandatoryStartTLS";
+ };
+ };
+ provision = {
+ datasources.settings = {
+ datasources = [
+ {
+ name = "Prometheus";
+ type = "prometheus";
+ url = "http://localhost:9090";
+ orgId = 1;
+ }
+ ];
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/monitoring/prometheus/default.nix b/modules/common/types/server/services/monitoring/prometheus/default.nix
new file mode 100644
index 000000000..a91b14978
--- /dev/null
+++ b/modules/common/types/server/services/monitoring/prometheus/default.nix
@@ -0,0 +1,69 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf;
+
+ cfg = config.modules.services.monitoring.prometheus;
+in {
+ config = mkIf cfg.enable {
+ services = {
+ # Prometheus exporter for Grafana
+ prometheus = {
+ enable = true;
+ port = 9100;
+ # enabled exporters
+ exporters = {
+ node = {
+ enable = true;
+ port = 9101;
+ enabledCollectors = [
+ "logind"
+ "systemd"
+ ];
+ disabledCollectors = [
+ "textfile"
+ ];
+ openFirewall = true;
+ };
+
+ redis = {
+ enable = true;
+ openFirewall = true;
+ port = 9002;
+ };
+
+ postgres = {
+ enable = true;
+ openFirewall = true;
+ port = 9003;
+ };
+ };
+
+ scrapeConfigs = [
+ {
+ job_name = "prometheus";
+ scrape_interval = "30s";
+ static_configs = [{targets = ["localhost:9090"];}];
+ }
+ {
+ job_name = "node";
+ scrape_interval = "30s";
+ static_configs = [{targets = ["localhost:9100"];}];
+ }
+ {
+ job_name = "redis_exporter";
+ scrape_interval = "30s";
+ static_configs = [{targets = ["localhost:9002"];}];
+ }
+ {
+ job_name = "postgres";
+ scrape_interval = "30s";
+ static_configs = [{targets = ["localhost:9003"];}];
+ }
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/nextcloud/default.nix b/modules/common/types/server/services/nextcloud/default.nix
new file mode 100644
index 000000000..6e601dd9c
--- /dev/null
+++ b/modules/common/types/server/services/nextcloud/default.nix
@@ -0,0 +1,72 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ inherit (config.networking) domain;
+ nextcloud_domain = "cloud.${domain}";
+
+ cfg = config.modules.services;
+in {
+ config = mkIf cfg.nextcloud.enable {
+ modules.services.database = {
+ redis.enable = true;
+ postgresql.enable = true;
+ };
+
+ services = {
+ nextcloud = {
+ enable = true;
+ package = pkgs.nextcloud27;
+ caching.redis = true;
+ extraOptions = {
+ redis = {
+ host = "/run/redis-default/redis.sock";
+ dbindex = 0;
+ timeout = 1.5;
+ };
+ };
+
+ hostName = nextcloud_domain;
+ home = "/opt/nextcloud";
+ maxUploadSize = "4G";
+ enableImagemagick = true;
+
+ autoUpdateApps = {
+ enable = true;
+ startAt = "02:00";
+ };
+
+ config = {
+ overwriteProtocol = "https";
+ extraTrustedDomains = ["https://${toString nextcloud_domain}"];
+ trustedProxies = ["https://${toString nextcloud_domain}"];
+ adminuser = "isabel";
+ adminpassFile = config.sops.secrets.nextcloud-passwd.path;
+ defaultPhoneRegion = "UK";
+
+ # database
+ dbtype = "pgsql";
+ dbhost = "/run/postgresql";
+ dbname = "nextcloud";
+ };
+ nginx.recommendedHttpHeaders = true;
+ https = true;
+ };
+ };
+
+ systemd.services = {
+ phpfpm-nextcloud.aliases = ["nextcloud.service"];
+ "nextcloud-setup" = {
+ requires = ["postgresql.service"];
+ after = ["postgresql.service"];
+ serviceConfig = {
+ Restart = "on-failure";
+ RestartSec = "10s";
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/nginx/default.nix b/modules/common/types/server/services/nginx/default.nix
index 0fcf7acc6..0e8654978 100644
--- a/modules/common/types/server/services/nginx/default.nix
+++ b/modules/common/types/server/services/nginx/default.nix
@@ -2,27 +2,27 @@
lib,
config,
...
-}:
-with lib; let
- device = config.modules.device;
- acceptedTypes = ["server" "hybrid"];
+}: let
+ cfg = config.modules.services;
+ inherit (lib) mkIf;
+ domain = "isabelroses.com";
in {
- config = mkIf (builtins.elem device.type acceptedTypes) {
- networking.domain = "isabelroses.com";
+ config = {
+ networking.domain = domain;
security = {
acme = {
acceptTerms = true;
- defaults.email = "isabel@isabelroses.com";
+ defaults.email = "isabel@${domain}";
};
};
- services.nginx = {
+ services.nginx = mkIf cfg.nginx.enable {
enable = true;
commonHttpConfig = ''
real_ip_header CF-Connecting-IP;
add_header 'Referrer-Policy' 'origin-when-cross-origin';
- add_header X-Frame-Options DENY;
+ add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options nosniff;
'';
@@ -31,57 +31,86 @@ in {
recommendedGzipSettings = true;
recommendedProxySettings = true;
- virtualHosts = let
- template = {
+ virtualHosts = {
+ # website + other stuff
+ "${domain}" = mkIf cfg.isabelroses-web.enable {
forceSSL = true;
enableACME = true;
+ locations."/".proxyPass = "http://127.0.0.1:3000";
};
- in {
- # website + other stuff
- "isabelroses.com" =
- mkIf (config.modules.services.isabelroses-web.enable)
- template
- // {
- serverAliases = ["isabelroses.com"];
- root = "/home/isabel/dev/isabelroses.com-pub";
- };
+
# vaultwawrden
- "vault.isabelroses.com" =
- mkIf (config.modules.services.vaultwarden.enable)
- template
- // {
- locations."/" = {
- proxyPass = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}";
- extraConfig = "proxy_pass_header Authorization;";
- };
- };
- # gitea
- "git.isabelroses.com" =
- mkIf (config.modules.services.gitea.enable)
- template
- // {
- locations."/".proxyPass = "http://127.0.0.1:${toString config.services.gitea.settings.server.HTTP_PORT}";
+ "vault.${domain}" = mkIf cfg.vaultwarden.enable {
+ forceSSL = true;
+ enableACME = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}";
+ extraConfig = "proxy_pass_header Authorization;";
};
+ };
+
+ # forgejo
+ "git.${domain}" = mkIf cfg.forgejo.enable {
+ locations."/".proxyPass = "http://127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}";
+ forceSSL = true;
+ enableACME = true;
+ };
+
+ "cloud.${domain}" = {
+ forceSSL = true;
+ enableACME = true;
+ };
# mailserver
- "mail.isabelroses.com" = mkIf (config.modules.services.mailserver.enable) template;
+ "mail.${domain}" = mkIf cfg.mailserver.enable {
+ forceSSL = true;
+ enableACME = true;
+ };
+ "rspamd.${domain}" = mkIf (cfg.mailserver.enable && cfg.mailserver.rspamd-web.enable) {
+ forceSSL = true;
+ enableACME = true;
+ basicAuthFile = config.sops.secrets.rspamd-web.path;
+ locations."/".proxyPass = "http://unix:/run/rspamd/worker-controller.sock:/";
+ };
+ "webmail.${domain}" = mkIf cfg.mailserver.enable {
+ forceSSL = true;
+ enableACME = true;
+ };
- # webmail
- "webmail.isabelroses.com" = mkIf (config.modules.services.mailserver.enable) template;
+ # searxng
+ "search.${domain}" = mkIf cfg.searxng.enable {
+ forceSSL = true;
+ enableACME = true;
+ locations."/".proxyPass = "http://127.0.0.1:8888";
+ extraConfig = ''
+ access_log /dev/null;
+ error_log /dev/null;
+ proxy_connect_timeout 60s;
+ proxy_send_timeout 60s;
+ proxy_read_timeout 60s;
+ '';
+ };
- "search.isabelroses.com" =
- mkIf (config.modules.services.searxng.enable)
- template
- // {
- locations."/".proxyPass = "http://127.0.0.1:8888";
- extraConfig = ''
- access_log /dev/null;
- error_log /dev/null;
- proxy_connect_timeout 60s;
- proxy_send_timeout 60s;
- proxy_read_timeout 60s;
- '';
+ "graph.${domain}" = mkIf cfg.monitoring.grafana.enable {
+ locations."/" = {
+ proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}/";
+ proxyWebsockets = true;
};
+ addSSL = true;
+ enableACME = true;
+ };
+
+ "flux.${domain}" = mkIf cfg.miniflux.enable {
+ locations."/".proxyPass = "http://unix:${config.systemd.services.miniflux.environment.LISTEN_ADDR}";
+ forceSSL = true;
+ enableACME = true;
+ };
+
+ "matrix.${domain}" = mkIf cfg.matrix.enable {
+ locations."/".proxyPass = "http://127.0.0.1:8008";
+ forceSSL = true;
+ enableACME = true;
+ };
};
};
};
diff --git a/modules/common/types/server/services/photoprism/default.nix b/modules/common/types/server/services/photoprism/default.nix
index 159f07fb9..389a587b4 100644
--- a/modules/common/types/server/services/photoprism/default.nix
+++ b/modules/common/types/server/services/photoprism/default.nix
@@ -3,13 +3,11 @@
config,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.networking) domain;
cfg = config.modules.services.photoprism;
- acceptedTypes = ["server" "hybrid"];
in {
- services = mkIf (builtins.elem device.type acceptedTypes && cfg.enable) {
+ services = lib.mkIf cfg.enable {
photoprism = {
enable = true;
port = 2342;
@@ -23,7 +21,7 @@ in {
PHOTOPRISM_DATABASE_NAME = "photoprism";
PHOTOPRISM_DATABASE_SERVER = "/run/mysqld/mysqld.sock";
PHOTOPRISM_DATABASE_USER = "photoprism";
- PHOTOPRISM_SITE_URL = "https://photos.isabelroses.com";
+ PHOTOPRISM_SITE_URL = "https://photos.${domain}";
PHOTOPRISM_SITE_TITLE = "My PhotoPrism";
};
};
diff --git a/modules/common/types/server/services/smb/default.nix b/modules/common/types/server/services/smb/default.nix
index 6ee09caf8..1e495561f 100644
--- a/modules/common/types/server/services/smb/default.nix
+++ b/modules/common/types/server/services/smb/default.nix
@@ -4,11 +4,9 @@
...
}: let
inherit (lib) mkIf;
- device = config.modules.device;
cfg = config.modules.services.smb;
- acceptedTypes = ["server" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && cfg.enable) {
+ config = mkIf cfg.enable {
services = {
# https://nixos.wiki/wiki/Samba
# make shares visible for windows 10 clients
diff --git a/modules/common/types/server/services/vaultwarden/default.nix b/modules/common/types/server/services/vaultwarden/default.nix
index 50a750e56..d69ce9e67 100644
--- a/modules/common/types/server/services/vaultwarden/default.nix
+++ b/modules/common/types/server/services/vaultwarden/default.nix
@@ -3,17 +3,17 @@
lib,
...
}: let
- inherit (lib) mkIf;
-
+ inherit (config.networking) domain;
cfg = config.modules.services.vaultwarden;
- device = config.modules.device;
- acceptedTypes = ["server" "hybrid"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes && cfg.enable) {
+ config = lib.mkIf cfg.enable {
# this forces the system to create backup folder
- systemd.services.backup-vaultwarden.serviceConfig = {
- User = "root";
- Group = "root";
+ systemd.services = {
+ vaultwarden.after = ["sops-nix.service"];
+ backup-vaultwarden.serviceConfig = {
+ User = "root";
+ Group = "root";
+ };
};
services.vaultwarden = {
@@ -21,22 +21,22 @@ in {
environmentFile = config.sops.secrets.vaultwarden-env.path;
backupDir = "/srv/storage/vaultwarden/backup";
config = {
- DOMAIN = "https://vault.isabelroses.com";
+ DOMAIN = "https://vault.${domain}";
SIGNUPS_ALLOWED = false;
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8222;
extendedLogging = true;
- invitationsAllowed = false;
+ invitationsAllowed = true;
useSyslog = true;
logLevel = "warn";
showPasswordHint = false;
signupsAllowed = false;
- signupsDomainsWhitelist = "isabelroses.com";
+ signupsDomainsWhitelist = "${domain}";
signupsVerify = true;
smtpAuthMechanism = "Login";
- smtpFrom = "vaultwarden@isabelroses.com";
- smtpFromName = "isabelroses's Vaultwarden Service";
- smtpHost = "mail.isabelroses.com";
+ smtpFrom = "vaultwarden@${domain}";
+ smtpFromName = "Isabelroses's Vaultwarden Service";
+ smtpHost = "mail.${domain}";
smtpPort = 465;
smtpSecurity = "force_tls";
dataDir = "/srv/storage/vaultwarden";
diff --git a/modules/common/types/server/services/wakatime/config.nix b/modules/common/types/server/services/wakatime/config.nix
new file mode 100644
index 000000000..c39105d8f
--- /dev/null
+++ b/modules/common/types/server/services/wakatime/config.nix
@@ -0,0 +1,26 @@
+{
+ config,
+ pkgs,
+ lib,
+ ...
+}: let
+ inherit (config.networking) domain;
+in {
+ services.wakapi = lib.mkIf config.modules.services.wakapi.enable {
+ enable = true;
+ package = pkgs.wakapi;
+
+ domain = "wakapi.${domain}";
+ port = 15912;
+ nginx.enable = true;
+ passwordSaltFile = config.sops.secrets.wakapi.path;
+ settings = {
+ app.avatar_url_template = "https://www.gravatar.com/avatar/{email_hash}.png";
+ mail.enabled = false;
+ security = {
+ allow_signup = false;
+ disable_frontpage = true;
+ };
+ };
+ };
+}
diff --git a/modules/common/types/server/services/wakatime/default.nix b/modules/common/types/server/services/wakatime/default.nix
new file mode 100644
index 000000000..a88393988
--- /dev/null
+++ b/modules/common/types/server/services/wakatime/default.nix
@@ -0,0 +1,6 @@
+_: {
+ imports = [
+ ./config.nix
+ ./module.nix
+ ];
+}
diff --git a/modules/common/types/server/services/wakatime/module.nix b/modules/common/types/server/services/wakatime/module.nix
new file mode 100644
index 000000000..af34224df
--- /dev/null
+++ b/modules/common/types/server/services/wakatime/module.nix
@@ -0,0 +1,196 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ # stolen from https://git.winston.sh/winston/deployment-flake/src/branch/main/modules/wakapi.nix
+ cfg = config.services.wakapi;
+ settingsFormat = pkgs.formats.yaml {};
+ inherit (lib) types;
+
+ settingsFile = settingsFormat.generate "wakapi-settings" cfg.settings;
+
+ serviceConfig = {
+ systemd.services.wakapi = {
+ description = "Wakapi (self-hosted WakaTime-compatible backend)";
+ wants = ["network-online.target"];
+ after = ["network-online.target"];
+ wantedBy = ["multi-user.target"];
+
+ script = ''
+ exec ${lib.getExe pkgs.wakapi} -config ${settingsFile}
+ '';
+
+ serviceConfig = {
+ Environment = lib.mkIf (cfg.passwordSalt != null) "WAKAPI_PASSWORD_SALT=${cfg.passwordSalt}";
+ EnvironmentFile = lib.mkIf (cfg.passwordSaltFile != null) cfg.passwordSaltFile;
+
+ User = "wakapi";
+ Group = "wakapi";
+
+ DynamicUser = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectProc = "invisible";
+ ProtectSystem = "strict";
+ RestrictAddressFamilies = ["AF_INET" "AF_INET6" "AF_UNIX"];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ };
+ };
+
+ services.wakapi.settings = {
+ env = lib.mkDefault "production";
+ inherit (cfg) db;
+ server = {
+ inherit (cfg) port;
+ };
+ };
+
+ assertions = [
+ {
+ assertion = cfg.passwordSalt != null || cfg.passwordSaltFile != null;
+ message = "Either `passwordSalt` or `passwordSaltFile` must be set.";
+ }
+ ];
+ };
+
+ databaseConfig = {
+ services.postgresql = {
+ enable = true;
+ ensureDatabases = lib.singleton cfg.settings.db.name;
+ ensureUsers = lib.singleton {
+ name = cfg.settings.db.user;
+ ensurePermissions = {
+ "DATABASE ${cfg.settings.db.name}" = "ALL PRIVILEGES";
+ };
+ };
+ authentication = ''
+ host ${cfg.settings.db.name} ${cfg.settings.db.user} 127.0.0.1/32 trust
+ '';
+ };
+
+ services.wakapi.settings.db = {
+ dialect = "postgres";
+ };
+
+ systemd.services.wakapi = {
+ requires = ["postgresql.service"];
+ after = ["postgresql.service"];
+ };
+ };
+
+ nginxConfig = lib.mkIf cfg.nginx.enable {
+ services.nginx = {
+ enable = true;
+ virtualHosts.${cfg.domain} = {
+ locations."/".proxyPass = "http://127.0.0.1:${toString cfg.port}";
+
+ enableACME = lib.mkDefault true;
+ forceSSL = lib.mkDefault true;
+ };
+ };
+
+ services.wakapi.settings.server = {
+ public_url = lib.mkDefault cfg.domain;
+ };
+ };
+in {
+ options.services.wakapi = {
+ enable = lib.mkEnableOption "Wakapi";
+ package = lib.mkPackageOption pkgs "wakapi" {};
+
+ port = lib.mkOption {
+ type = types.int;
+ default = 3000;
+ description = ''
+ The port to serve Wakapi on.
+ This is used to configure nginx.
+ '';
+ };
+ domain = lib.mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ The FQDN of the domain to serve Wakapi on.
+ This is used to configure nginx.
+ '';
+ };
+
+ db = {
+ host = lib.mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ The database host to use for Wakapi.
+ '';
+ };
+ port = lib.mkOption {
+ type = types.int;
+ default = 5432;
+ description = ''
+ The port to use for the database.
+ '';
+ };
+ name = lib.mkOption {
+ type = types.str;
+ default = "wakapi";
+ description = ''
+ The database name to use for Wakapi.
+ '';
+ };
+ user = lib.mkOption {
+ type = types.str;
+ default = "wakapi";
+ description = ''
+ The database user to use for Wakapi.
+ '';
+ };
+ password = lib.mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ The database password to use for Wakapi.
+ '';
+ };
+ };
+
+ nginx.enable = lib.mkEnableOption "Wakapi Nginx";
+
+ passwordSalt = lib.mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ The password salt to use for Wakapi.
+ '';
+ };
+ passwordSaltFile = lib.mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ The path to a file containing the password salt to use for Wakapi.
+ '';
+ };
+
+ settings = lib.mkOption {
+ inherit (settingsFormat) type;
+ default = {};
+ description = lib.mkDoc ''
+ Settings for Wakapi.
+
+ See [config.default.yml](https://github.com/muety/wakapi/blob/master/config.default.yml) for a list of all possible options.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable (lib.mkMerge [
+ databaseConfig
+ nginxConfig
+ serviceConfig
+ ]);
+}
diff --git a/modules/common/types/server/system/default.nix b/modules/common/types/server/system/default.nix
index e46be8f94..44bc7c177 100644
--- a/modules/common/types/server/system/default.nix
+++ b/modules/common/types/server/system/default.nix
@@ -1,5 +1,8 @@
_: {
imports = [
- ./users.nix
+ ./users
+
+ ./enviroment.nix
+ ./systemd.nix
];
}
diff --git a/modules/common/types/server/system/enviroment.nix b/modules/common/types/server/system/enviroment.nix
new file mode 100644
index 000000000..81ee97390
--- /dev/null
+++ b/modules/common/types/server/system/enviroment.nix
@@ -0,0 +1,10 @@
+_: {
+ environment = {
+ # normally we wouldn't need any Xlibs on a headless server but for whatever reason
+ # this affects whether or not some programs can build - such as pipewire
+ # noXlibs = true;
+
+ # print the URL instead on servers
+ variables.BROWSER = "echo";
+ };
+}
diff --git a/modules/common/types/server/system/systemd.nix b/modules/common/types/server/system/systemd.nix
new file mode 100644
index 000000000..e222280a3
--- /dev/null
+++ b/modules/common/types/server/system/systemd.nix
@@ -0,0 +1,29 @@
+_: {
+ # https://github.com/numtide/srvos/blob/main/nixos/server/default.nix
+ systemd = {
+ # given that our systems are headless, emergency mode is useless.
+ # we prefer the system to attempt to continue booting so
+ # that we can hopefully still access it remotely.
+ enableEmergencyMode = false;
+
+ # For more detail, see:
+ # https://0pointer.de/blog/projects/watchdog.html
+ watchdog = {
+ # systemd will send a signal to the hardware watchdog at half
+ # the interval defined here, so every 10s.
+ # If the hardware watchdog does not get a signal for 20s,
+ # it will forcefully reboot the system.
+ runtimeTime = "20s";
+ # Forcefully reboot if the final stage of the reboot
+ # hangs without progress for more than 30s.
+ # For more info, see:
+ # https://utcc.utoronto.ca/~cks/space/blog/linux/SystemdShutdownWatchdog
+ rebootTime = "30s";
+ };
+
+ sleep.extraConfig = ''
+ AllowSuspend=no
+ AllowHibernation=no
+ '';
+ };
+}
diff --git a/modules/common/types/server/system/users.nix b/modules/common/types/server/system/users.nix
deleted file mode 100644
index b3d3252b8..000000000
--- a/modules/common/types/server/system/users.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- lib,
- config,
- ...
-}: let
- inherit (lib) mkIf;
-in {
- users.users.git = mkIf config.modules.services.gitea.enable {
- isSystemUser = true;
- extraGroups = [];
- useDefaultShell = true;
- home = "/var/lib/gitea";
- group = "gitea";
- };
-}
diff --git a/modules/common/types/server/system/users/default.nix b/modules/common/types/server/system/users/default.nix
new file mode 100644
index 000000000..07a11ac68
--- /dev/null
+++ b/modules/common/types/server/system/users/default.nix
@@ -0,0 +1,6 @@
+_: {
+ imports = [
+ ./git.nix
+ ./wakapi.nix
+ ];
+}
diff --git a/modules/common/types/server/system/users/git.nix b/modules/common/types/server/system/users/git.nix
new file mode 100644
index 000000000..aff8862de
--- /dev/null
+++ b/modules/common/types/server/system/users/git.nix
@@ -0,0 +1,18 @@
+{
+ lib,
+ config,
+ ...
+}: let
+ inherit (lib) mkIf;
+ cfg = config.modules.services.forgejo;
+in {
+ users = mkIf cfg.enable {
+ groups.git = {};
+
+ users.git = {
+ isSystemUser = true;
+ createHome = false;
+ group = "git";
+ };
+ };
+}
diff --git a/modules/common/types/server/system/users/wakapi.nix b/modules/common/types/server/system/users/wakapi.nix
new file mode 100644
index 000000000..73cc3c89a
--- /dev/null
+++ b/modules/common/types/server/system/users/wakapi.nix
@@ -0,0 +1,18 @@
+{
+ lib,
+ config,
+ ...
+}: let
+ inherit (lib) mkIf;
+ cfg = config.modules.services.wakapi;
+in {
+ users = mkIf cfg.enable {
+ groups.wakapi = {};
+
+ users.wakapi = {
+ isSystemUser = true;
+ createHome = false;
+ group = "wakapi";
+ };
+ };
+}
diff --git a/modules/common/types/workstation/default.nix b/modules/common/types/workstation/default.nix
index 96d570a2f..21f2d8c6a 100644
--- a/modules/common/types/workstation/default.nix
+++ b/modules/common/types/workstation/default.nix
@@ -1,6 +1,5 @@
_: {
imports = [
- ./gaming
./programs
./services
./system
diff --git a/modules/common/types/workstation/gaming/default.nix b/modules/common/types/workstation/gaming/default.nix
deleted file mode 100644
index 53152e1db..000000000
--- a/modules/common/types/workstation/gaming/default.nix
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- config,
- lib,
- pkgs,
- inputs,
- ...
-}:
-with lib; let
- programs = makeBinPath (with pkgs; [
- inputs.hyprland.packages.${pkgs.system}.default
- coreutils
- power-profiles-daemon
- systemd
- ]);
-
- startscript = pkgs.writeShellScript "gamemode-start" ''
- export PATH=$PATH:${programs}
- export HYPRLAND_INSTANCE_SIGNATURE=$(ls -w1 /tmp/hypr | tail -1)
- hyprctl --batch 'keyword decoration:blur 0 ; keyword animations:enabled 0 ; keyword misc:vfr 0'
- ${pkgs.libnotify}/bin/notify-send -a 'Gamemode' 'Optimizations activated'
- powerprofilesctl set performance
- '';
-
- endscript = pkgs.writeShellScript "gamemode-end" ''
- export PATH=$PATH:${programs}
- export HYPRLAND_INSTANCE_SIGNATURE=$(ls -w1 /tmp/hypr | tail -1)
- hyprctl --batch 'keyword decoration:blur 1 ; keyword animations:enabled 1 ; keyword misc:vfr 1'
- ${pkgs.libnotify}/bin/notify-send -a 'Gamemode' 'Optimizations deactivated'
- powerprofilesctl set power-saver
- '';
-
- cfg = config.modules.programs;
-in {
- config = mkIf cfg.gaming.enable {
- programs = {
- gamemode = {
- enable = true;
- enableRenice = true;
- settings = {
- general = {
- softrealtime = "auto";
- renice = 15;
- };
- custom = {
- start = startscript.outPath;
- end = endscript.outPath;
- };
- };
- };
-
- steam = {
- enable = true;
- # Open ports in the firewall for Steam Remote Play
- remotePlay.openFirewall = true;
- # Open ports in the firewall for Source Dedicated Server
- dedicatedServer.openFirewall = true;
- # Compatibility tools to install
- # this option is provided by modules/shared/nixos/steam
- withProtonGE = true;
- };
- };
- };
-}
diff --git a/modules/common/types/workstation/programs/ccache/default.nix b/modules/common/types/workstation/programs/ccache/default.nix
new file mode 100644
index 000000000..90c27ac89
--- /dev/null
+++ b/modules/common/types/workstation/programs/ccache/default.nix
@@ -0,0 +1,49 @@
+{
+ config,
+ lib,
+ ...
+}: {
+ programs.ccache = {
+ enable = true;
+ cacheDir = "/var/cache/sccache";
+ };
+
+ systemd.tmpfiles.rules = [
+ "z ${config.programs.ccache.cacheDir} 770 root nixbld - -"
+ ];
+
+ nix.settings.extra-sandbox-paths = [
+ config.programs.ccache.cacheDir
+ "/var/cache/sccache"
+ ];
+
+ nixpkgs.overlays = lib.mkIf (config.programs.ccache.enable && config.programs.ccache.packageNames == []) [
+ (_: super: {
+ ccacheWrapper = super.ccacheWrapper.override {
+ extraConfig = ''
+ export CCACHE_COMPRESS=1
+ export CCACHE_DIR="${config.programs.ccache.cacheDir}"
+ export CCACHE_UMASK=007
+ export CCACHE_SLOPPINESS=include_file_mtime,time_macros
+ export CCACHE_NODIRECT=1
+ if [ ! -d "$CCACHE_DIR" ]; then
+ echo "====="
+ echo "Directory '$CCACHE_DIR' does not exist"
+ echo "Please create it with:"
+ echo " sudo mkdir -m0770 '$CCACHE_DIR'"
+ echo " sudo chown root:nixbld '$CCACHE_DIR'"
+ echo "====="
+ exit 1
+ fi
+ if [ ! -w "$CCACHE_DIR" ]; then
+ echo "====="
+ echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
+ echo "Please verify its access permissions"
+ echo "====="
+ exit 1
+ fi
+ '';
+ };
+ })
+ ];
+}
diff --git a/modules/common/types/workstation/programs/cli.nix b/modules/common/types/workstation/programs/cli.nix
index 94b19894b..b078abfd2 100644
--- a/modules/common/types/workstation/programs/cli.nix
+++ b/modules/common/types/workstation/programs/cli.nix
@@ -21,8 +21,7 @@ in {
};
programs = {
- # home-manager is quirky as ever, and wants this to be set in system config
- # instead of just home-manager
+ # home-manager is so strange and needs these declared muliple times
fish.enable = true;
# type "fuck" to fix the last command that made you go "fuck"
@@ -30,10 +29,18 @@ in {
# help manage android devices via command line
adb.enable = true;
+
+ # direnv is cool
+ direnv = {
+ enable = true;
+ silent = true;
+
+ # faster, persistent
+ nix-direnv.enable = true;
+ };
};
- # determine which version of wine to be used
- # then add it to systemPackages
+ # determine which version of wine to use
environment.systemPackages = with pkgs; let
winePackage =
if (env.isWayland)
diff --git a/modules/common/types/workstation/programs/default.nix b/modules/common/types/workstation/programs/default.nix
index f1d088373..b48a0f892 100644
--- a/modules/common/types/workstation/programs/default.nix
+++ b/modules/common/types/workstation/programs/default.nix
@@ -1,5 +1,6 @@
_: {
imports = [
+ ./ccache
./flatpak
./xdg-ninja
diff --git a/modules/common/types/workstation/programs/flatpak/default.nix b/modules/common/types/workstation/programs/flatpak/default.nix
index 9cc573d9b..9d4e25014 100644
--- a/modules/common/types/workstation/programs/flatpak/default.nix
+++ b/modules/common/types/workstation/programs/flatpak/default.nix
@@ -1,5 +1,5 @@
_: {
- # enable flatpak, as well as xdgp to communicate with the host filesystems
+ # enable flatpak
services.flatpak.enable = false;
environment.sessionVariables.XDG_DATA_DIRS = ["/var/lib/flatpak/exports/share"];
diff --git a/modules/common/types/workstation/programs/gui.nix b/modules/common/types/workstation/programs/gui.nix
index d4bddeb59..025462eae 100644
--- a/modules/common/types/workstation/programs/gui.nix
+++ b/modules/common/types/workstation/programs/gui.nix
@@ -1,4 +1,8 @@
-{pkgs, ...}: {
+{
+ pkgs,
+ config,
+ ...
+}: {
environment = {
systemPackages = with pkgs; [
# packages necessery for thunar thumbnails
@@ -20,13 +24,12 @@
];
};
- # registry for linux, thanks to gnome
dconf.enable = true;
# gnome's keyring manager
seahorse.enable = true;
- # networkmanager tray uility
- nm-applet.enable = true;
+ # networkmanager tray uility, pretty useful actually
+ nm-applet.enable = config.modules.programs.defaults.bar == "waybar";
};
}
diff --git a/modules/common/types/workstation/services/default.nix b/modules/common/types/workstation/services/default.nix
index a368e060b..65c768cb7 100644
--- a/modules/common/types/workstation/services/default.nix
+++ b/modules/common/types/workstation/services/default.nix
@@ -6,5 +6,7 @@ _: {
./misc.nix
./printing.nix
./runners.nix
+ ./tor.nix
+ ./xserver.nix
];
}
diff --git a/modules/common/types/workstation/services/gnome.nix b/modules/common/types/workstation/services/gnome.nix
index 3bf03a7ac..859eb4163 100644
--- a/modules/common/types/workstation/services/gnome.nix
+++ b/modules/common/types/workstation/services/gnome.nix
@@ -3,12 +3,11 @@
pkgs,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.modules) device;
acceptedTypes = ["desktop" "laptop" "hybrid" "lite"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes) {
+ config = lib.mkIf (builtins.elem device.type acceptedTypes) {
services = {
udev.packages = with pkgs; [
gnome.gnome-settings-daemon
@@ -16,13 +15,10 @@ in {
gnome = {
evolution-data-server.enable = true;
- # optional to use google/nextcloud calendar
gnome-online-accounts.enable = true;
- # optional to use google/nextcloud calendar
gnome-keyring.enable = true;
- # hard fails rebuilds for whatever reason, PLEASE stay disabled
- # spoiler: it didn't - building gnome-control-center still breaks rebuilds
- # entirely because of gnome-remote-desktop
+
+ # stupid thing i want disabled
gnome-remote-desktop.enable = lib.mkForce false;
};
};
diff --git a/modules/common/types/workstation/services/location.nix b/modules/common/types/workstation/services/location.nix
index 09c11dc41..4470c8ef9 100644
--- a/modules/common/types/workstation/services/location.nix
+++ b/modules/common/types/workstation/services/location.nix
@@ -2,12 +2,11 @@
config,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.modules) device;
acceptedTypes = ["desktop" "laptop" "lite"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes) {
+ config = lib.mkIf (builtins.elem device.type acceptedTypes) {
location.provider = "geoclue2";
services.geoclue2 = {
diff --git a/modules/common/types/workstation/services/login.nix b/modules/common/types/workstation/services/login.nix
index 73bd6366f..caba0fed3 100644
--- a/modules/common/types/workstation/services/login.nix
+++ b/modules/common/types/workstation/services/login.nix
@@ -1,43 +1,87 @@
{
config,
+ lib,
pkgs,
...
-}: {
+}: let
+ inherit (config.modules) system usrEnv programs;
+ inherit (lib) mkIf;
+ sessionData = config.services.xserver.displayManager.sessionData.desktops;
+ sessionPath = lib.concatStringsSep ":" [
+ "${sessionData}/share/xsessions"
+ "${sessionData}/share/wayland-sessions"
+ ];
+in {
config = {
# unlock GPG keyring on login
- security.pam.services.login = {
- enableGnomeKeyring = true;
- gnupg = {
- enable = true;
- noAutostart = true;
- storeOnly = true;
+ security.pam.services = {
+ login = {
+ enableGnomeKeyring = true;
+ gnupg = {
+ enable = true;
+ noAutostart = true;
+ storeOnly = true;
+ };
};
- };
- systemd.services = {
- # login manager
- seatd = {
- enable = true;
- description = "Seat management daemon";
- script = "${pkgs.seatd}/bin/seatd -g wheel";
- serviceConfig = {
- Type = "simple";
- Restart = "always";
- RestartSec = "1";
- };
- wantedBy = ["multi-user.target"];
+ greetd = mkIf (programs.defaults.loginManager == "greetd") {
+ gnupg.enable = true;
+ enableGnomeKeyring = true;
};
};
services = {
+ xserver.displayManager.session = [
+ {
+ manage = "desktop";
+ name = "hyprland";
+ start = ''
+ Hyprland
+ '';
+ }
+ ];
+
+ greetd = {
+ enable = programs.defaults.loginManager == "greetd";
+ vt = 2;
+ restart = !system.autoLogin;
+ settings = {
+ # pick up desktop variant (i.e Hyprland) and username from usrEnv
+ # this option is usually defined in host//system.nix
+ initial_session = mkIf system.autoLogin {
+ command = "${usrEnv.desktop}";
+ user = "${system.mainUser}";
+ };
+
+ default_session =
+ if (!system.autoLogin)
+ then {
+ command = lib.concatStringsSep " " [
+ (lib.getExe pkgs.greetd.tuigreet)
+ "--time"
+ "--remember"
+ "--remember-user-session"
+ "--asterisks"
+ "--sessions '${sessionPath}'"
+ ];
+ user = "greeter";
+ }
+ else {
+ command = "${usrEnv.desktop}";
+ user = "${system.mainUser}";
+ };
+ };
+ };
+
gnome = {
+ glib-networking.enable = true;
gnome-keyring.enable = true;
};
logind = {
lidSwitch = "ignore";
- lidSwitchDocked = "ignore";
- lidSwitchExternalPower = "ignore";
+ lidSwitchDocked = "lock";
+ lidSwitchExternalPower = "lock";
powerKey = "suspend-then-hibernate";
};
};
diff --git a/modules/common/types/workstation/services/misc.nix b/modules/common/types/workstation/services/misc.nix
index 2824541d6..5a390d5b4 100644
--- a/modules/common/types/workstation/services/misc.nix
+++ b/modules/common/types/workstation/services/misc.nix
@@ -3,9 +3,9 @@
pkgs,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (lib) mkIf;
+ inherit (config.modules) device;
acceptedTypes = ["desktop" "laptop" "hybrid" "lite"];
in {
config = mkIf (builtins.elem device.type acceptedTypes) {
@@ -16,6 +16,9 @@ in {
# thumbnail support on thunar
tumbler.enable = true;
+ # storage daemon required for udiskie auto-mount
+ udisks2.enable = true;
+
dbus = {
packages = with pkgs; [dconf gcr udisks2];
enable = true;
@@ -35,7 +38,7 @@ in {
in {
inherit extraConfig;
user = {inherit extraConfig;};
- services."getty@tty1".enable = false;
+ services."getty@tty1".enable = false; # if you want to use tty1 enable
services."autovt@tty1".enable = false;
services."getty@tty7".enable = false;
services."autovt@tty7".enable = false;
diff --git a/modules/common/types/workstation/services/printing.nix b/modules/common/types/workstation/services/printing.nix
index 667bef32d..1b06e3430 100644
--- a/modules/common/types/workstation/services/printing.nix
+++ b/modules/common/types/workstation/services/printing.nix
@@ -3,12 +3,11 @@
lib,
pkgs,
...
-}:
-with lib; let
+}: let
sys = config.modules.system;
in {
- config = mkIf (sys.printing.enable) {
- # enable cups and add some drivers for common printers
+ config = lib.mkIf sys.printing.enable {
+ # enable cups and some drivers for common printers
services = {
printing = {
enable = true;
@@ -21,9 +20,7 @@ in {
# required for network discovery of printers
avahi = {
enable = true;
- # resolve .local domains for printers
nssmdns = true;
- # pass avahi port(s) to the firewall
openFirewall = true;
};
};
diff --git a/modules/common/types/workstation/services/runners.nix b/modules/common/types/workstation/services/runners.nix
index 6b2cc1c2f..77f51554f 100644
--- a/modules/common/types/workstation/services/runners.nix
+++ b/modules/common/types/workstation/services/runners.nix
@@ -6,7 +6,7 @@
...
}: let
inherit (lib) mkIf;
- device = config.modules.device;
+ inherit (config.modules) device;
in {
imports = [inputs.nix-ld.nixosModules.nix-ld];
@@ -22,16 +22,27 @@ in {
# run unpatched linux binaries with nix-ld
programs.nix-ld.dev = {
- enable = false;
+ enable = true;
libraries = with pkgs; [
+ stdenv.cc.cc
openssl
curl
glib
- gjs
util-linux
glibc
+ icu
+ libunwind
+ libuuid
+ zlib
+ libsecret
+ # graphical
+ freetype
+ libglvnd
libnotify
+ SDL2
+ vulkan-loader
gdk-pixbuf
+ xorg.libX11
];
};
};
diff --git a/modules/common/types/workstation/services/tor.nix b/modules/common/types/workstation/services/tor.nix
new file mode 100644
index 000000000..3489baf88
--- /dev/null
+++ b/modules/common/types/workstation/services/tor.nix
@@ -0,0 +1,12 @@
+{
+ lib,
+ config,
+ ...
+}: {
+ services.tor = lib.mkIf config.modules.system.security.tor.enable {
+ enable = true;
+ client.enable = true;
+ client.dns.enable = true;
+ torsocks.enable = true;
+ };
+}
diff --git a/modules/common/types/workstation/services/xserver.nix b/modules/common/types/workstation/services/xserver.nix
new file mode 100644
index 000000000..53bdbee64
--- /dev/null
+++ b/modules/common/types/workstation/services/xserver.nix
@@ -0,0 +1,26 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkIf;
+ inherit (config.modules) device programs system;
+ acceptedTypes = ["desktop" "laptop" "hybrid" "lite"];
+in {
+ config = mkIf (system.video.enable && builtins.elem device.type acceptedTypes) {
+ services.xserver = {
+ enable = true;
+ displayManager.gdm.enable = programs.defaults.loginManager == "gdm";
+ displayManager.lightdm.enable = programs.defaults.loginManager == "lightdm";
+ displayManager.sddm = {
+ enable = programs.defaults.loginManager == "sddm";
+ wayland.enable = true;
+ theme = "${import ../../../../../parts/pkgs/sddm.nix {inherit pkgs lib;}}";
+ settings = {
+ General = {InputMethod = "";};
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/types/workstation/system/default.nix b/modules/common/types/workstation/system/default.nix
index 8175026ef..9b36398d8 100644
--- a/modules/common/types/workstation/system/default.nix
+++ b/modules/common/types/workstation/system/default.nix
@@ -1,7 +1,6 @@
_: {
imports = [
./fonts.nix
- ./environment.nix
./misc.nix
];
}
diff --git a/modules/common/types/workstation/system/environment.nix b/modules/common/types/workstation/system/environment.nix
deleted file mode 100644
index e63a20111..000000000
--- a/modules/common/types/workstation/system/environment.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- config,
- lib,
- ...
-}:
-with lib; let
- device = config.modules.device;
- progs = config.modules.programs.default;
- acceptedTypes = ["desktop" "laptop" "hybrid" "lite"];
-in {
- config = mkIf (builtins.elem device.type acceptedTypes) {
- environment.variables = {
- # open links with the default browser
- BROWSER = progs.browser;
- };
- };
-}
diff --git a/modules/common/types/workstation/system/misc.nix b/modules/common/types/workstation/system/misc.nix
index d383e7b47..d24d6d0be 100644
--- a/modules/common/types/workstation/system/misc.nix
+++ b/modules/common/types/workstation/system/misc.nix
@@ -2,17 +2,11 @@
config,
lib,
...
-}:
-with lib; let
- device = config.modules.device;
+}: let
+ inherit (config.modules) device;
acceptedTypes = ["desktop" "laptop" "hybrid" "lite"];
in {
- config = mkIf (builtins.elem device.type acceptedTypes) {
- qt = {
- enable = true;
- platformTheme = "qt5ct";
- };
-
+ config = lib.mkIf (builtins.elem device.type acceptedTypes) {
# enable polkit for privilege escalation
security.polkit.enable = true;
diff --git a/modules/extra/shared/home-manager/gtklock/default.nix b/modules/extra/shared/home-manager/gtklock/default.nix
index f95a15509..40635d296 100644
--- a/modules/extra/shared/home-manager/gtklock/default.nix
+++ b/modules/extra/shared/home-manager/gtklock/default.nix
@@ -1,3 +1,4 @@
+# stolen from https://github.com/NotAShelf/nyx/blob/refactor/modules/extra/shared/home-manager/gtklock/default.nix
{
config,
lib,
diff --git a/modules/extra/shared/nixos/default.nix b/modules/extra/shared/nixos/default.nix
index 00e7ed19c..87a13d7f8 100644
--- a/modules/extra/shared/nixos/default.nix
+++ b/modules/extra/shared/nixos/default.nix
@@ -1,5 +1,2 @@
_: {
- imports = [
- ./steam
- ];
}
diff --git a/modules/extra/shared/nixos/steam/default.nix b/modules/extra/shared/nixos/steam/default.nix
deleted file mode 100644
index 5ec5c4214..000000000
--- a/modules/extra/shared/nixos/steam/default.nix
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- config,
- lib,
- inputs',
- ...
-}:
-with lib; let
- cfg = config.programs.steam;
-in {
- options.programs.steam = {
- withProtonGE = mkOption {
- type = types.bool;
- default = false;
- description = mdDoc ''
- Whether or not proton-ge from nix-gaming should be appended to `extraCompatPackages`.
- '';
- };
-
- extraCompatPackages = mkOption {
- type = with types; listOf package;
- default = [];
- defaultText = literalExpression "[]";
- example = literalExpression ''
- with pkgs; [
- luxtorpeda
- proton-ge
- ]
- '';
- description = mdDoc ''
- Extra packages to be used as compatibility tools for Steam on Linux. Packages will be included
- in the `STEAM_EXTRA_COMPAT_TOOLS_PATHS` environmental variable. For more information see
- .
- '';
- };
- };
-
- config = let
- CompatPackages =
- if cfg.withProtonGE == true
- then cfg.extraCompatPackages ++ [inputs'.nix-gaming.packages.proton-ge]
- else cfg.extraCompatPackages;
- in
- mkIf cfg.enable {
- # Steam hardware (just in case)
- hardware.steam-hardware.enable = true;
-
- # Append the extra compatibility packages to whatever else the env variable was populated with.
- # For more information see https://github.com/ValveSoftware/steam-for-linux/issues/6310.
- environment.sessionVariables = mkIf (CompatPackages != []) {
- STEAM_EXTRA_COMPAT_TOOLS_PATHS = [
- (makeBinPath CompatPackages)
- ];
- };
- };
-}
diff --git a/modules/common/options/default.nix b/modules/options/default.nix
similarity index 86%
rename from modules/common/options/default.nix
rename to modules/options/default.nix
index ea8cb5541..0502025eb 100644
--- a/modules/common/options/default.nix
+++ b/modules/options/default.nix
@@ -2,6 +2,7 @@ _: {
imports = [
./device
./programs
+ ./services
./system
./themes
./usrEnv
diff --git a/modules/options/device/capabilities.nix b/modules/options/device/capabilities.nix
new file mode 100644
index 000000000..5ad686be1
--- /dev/null
+++ b/modules/options/device/capabilities.nix
@@ -0,0 +1,22 @@
+{lib, ...}:
+with lib; {
+ options.modules.device = {
+ hasBluetooth = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Whether or not the system has bluetooth support";
+ };
+
+ hasSound = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Whether the system has sound support (usually true except for servers)";
+ };
+
+ hasTPM = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether the system has tpm support";
+ };
+ };
+}
diff --git a/modules/options/device/default.nix b/modules/options/device/default.nix
new file mode 100644
index 000000000..5a9dd8b75
--- /dev/null
+++ b/modules/options/device/default.nix
@@ -0,0 +1,6 @@
+_: {
+ imports = [
+ ./capabilities.nix
+ ./hardware.nix
+ ];
+}
diff --git a/modules/options/device/hardware.nix b/modules/options/device/hardware.nix
new file mode 100644
index 000000000..6466a7f40
--- /dev/null
+++ b/modules/options/device/hardware.nix
@@ -0,0 +1,36 @@
+{lib, ...}: let
+ inherit (lib) mdDoc mkOption types;
+in {
+ options.modules.device = {
+ type = mkOption {
+ type = types.enum ["laptop" "desktop" "server" "hybrid" "lite" "vm"];
+ default = "";
+ };
+
+ cpu = mkOption {
+ type = types.enum ["pi" "intel" "vm-intel" "amd" "vm-amd" null];
+ default = null;
+ };
+
+ gpu = mkOption {
+ type = types.enum ["amd" "intel" "nvidia" null];
+ default = null;
+ description = "The manifacturer/type of the primary system gpu";
+ };
+
+ monitors = mkOption {
+ type = with types; listOf str;
+ default = [];
+ description = mdDoc ''
+ this does not affect any drivers and such, it is only necessary for
+ declaring things like monitors in window manager configurations
+ you can avoid declaring this, but I'd rather if you did declare
+ '';
+ };
+
+ keyboard = mkOption {
+ type = types.enum ["us" "gb"];
+ default = "gb";
+ };
+ };
+}
diff --git a/modules/options/programs/default.nix b/modules/options/programs/default.nix
new file mode 100644
index 000000000..dd07e2bde
--- /dev/null
+++ b/modules/options/programs/default.nix
@@ -0,0 +1,27 @@
+{lib, ...}: let
+ inherit (lib) mkEnableOption mkOption types;
+in {
+ imports = [
+ ./defaults
+ ./gaming.nix
+ ];
+
+ options.modules.programs = {
+ cli = {
+ enable = mkEnableOption "Enable CLI programs";
+ modernShell.enable = mkEnableOption "Enable modern shell programs";
+ };
+ tui.enable = mkEnableOption "Enable TUI programs";
+ gui.enable = mkEnableOption "Enable GUI programs";
+
+ zathura.enable = mkEnableOption "Enable zathura PDF reader";
+
+ git = {
+ signingKey = mkOption {
+ type = types.str;
+ default = "";
+ description = "The default gpg key used for signing commits";
+ };
+ };
+ };
+}
diff --git a/modules/options/programs/defaults/default.nix b/modules/options/programs/defaults/default.nix
new file mode 100644
index 000000000..b58bacb22
--- /dev/null
+++ b/modules/options/programs/defaults/default.nix
@@ -0,0 +1,59 @@
+{lib, ...}: let
+ inherit (lib) mkOption types mdDoc;
+in {
+ options.modules.programs.defaults = {
+ terminal = mkOption {
+ type = types.enum ["alacritty" "kitty" "wezterm" "foot"];
+ default = "kitty";
+ };
+
+ fileManager = mkOption {
+ type = types.enum ["thunar" "dolphin" "nemo"];
+ default = "thunar";
+ };
+
+ browser = mkOption {
+ type = types.enum ["schizofox" "chromium"];
+ default = "schizofox";
+ };
+
+ editor = mkOption {
+ type = types.enum ["nvim" "codium"];
+ default = "nvim";
+ };
+
+ launcher = mkOption {
+ type = types.enum ["rofi" "wofi"];
+ default = "rofi";
+ };
+
+ bar = mkOption {
+ type = types.enum ["eww" "waybar" "ags"];
+ default = "eww";
+ };
+
+ screenLocker = mkOption {
+ type = with types; nullOr (enum ["swaylock" "gtklock"]);
+ default = "gtklock";
+ description = mdDoc ''
+ The lockscreen module to be loaded by home-manager.
+ '';
+ };
+
+ loginManager = mkOption {
+ type = with types; nullOr (enum ["greetd" "gdm" "lightdm" "sddm"]);
+ default = "greetd";
+ description = mdDoc ''
+ The login manager to be used by the system.
+ '';
+ };
+
+ noiseSupressor = mkOption {
+ type = with types; nullOr (enum ["rnnoise" "noisetorch"]);
+ default = "rnnoise";
+ description = lib.mdDoc ''
+ The noise supressor to be used for desktop systems with sound enabled.
+ '';
+ };
+ };
+}
diff --git a/modules/options/programs/gaming.nix b/modules/options/programs/gaming.nix
new file mode 100644
index 000000000..0f6dc0de3
--- /dev/null
+++ b/modules/options/programs/gaming.nix
@@ -0,0 +1,19 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkEnableOption;
+in {
+ options.modules.programs.gaming = let
+ cfg = config.modules.programs.gaming;
+ in {
+ enable = mkEnableOption "Enable packages required for the device to be gaming-ready";
+ emulation.enable = mkEnableOption "Enable programs required to emulate other platforms";
+ minecraft.enable = mkEnableOption "Enable minecraft";
+
+ gamescope.enable = mkEnableOption "Gamescope compositing manager" // {default = cfg.enable;};
+ steam.enable = mkEnableOption "Enable Steam" // {default = cfg.enable;};
+ mangohud.enable = mkEnableOption "Enable MangoHud" // {default = cfg.enable;};
+ };
+}
diff --git a/modules/options/services/default.nix b/modules/options/services/default.nix
new file mode 100644
index 000000000..679292278
--- /dev/null
+++ b/modules/options/services/default.nix
@@ -0,0 +1,60 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkEnableOption;
+ cfg = config.modules.services;
+
+ # mkEnableOption is the same as mkEnableOption but with the default value being equal to cfg.monitoring.enable
+ mkEnableOption' = desc: mkEnableOption "${desc}" // {default = cfg.monitoring.enable;};
+in {
+ options.modules.services = {
+ nextcloud.enable = mkEnableOption "Nextcloud service";
+ matrix.enable = mkEnableOption "Enable matrix server";
+ miniflux.enable = mkEnableOption "Enable miniflux rss news aggreator service";
+ forgejo.enable = mkEnableOption "Enable the forgejo service";
+ cyberchef.enable = mkEnableOption "Enable the cyberchef website";
+ vaultwarden.enable = mkEnableOption "Enable the vaultwarden service";
+ photoprism.enable = mkEnableOption "Enable the photoprism service";
+ vscode-server.enable = mkEnableOption "Enables remote ssh vscode server";
+ isabelroses-web.enable = mkEnableOption "Enables my website";
+ searxng.enable = mkEnableOption "Enables searxng search engine service";
+ nginx.enable = mkEnableOption "Enables nginx webserver";
+ cloudflared.enable = mkEnableOption "Enables cloudflared tunnels";
+ wakapi.enable = mkEnableOption "Enables wakapi";
+ jellyfin.enable = mkEnableOption "Enables the jellyfin service";
+
+ mailserver = {
+ enable = mkEnableOption "Enable the mailserver service";
+ rspamd-web.enable = mkEnableOption "Enable rspamd web ui";
+ };
+
+ # monitoring tools
+ monitoring = {
+ enable = mkEnableOption "system monitoring services"; # // {default = ifOneEnabled cfg "grafana" "prometheus" "loki";};
+ prometheus.enable = mkEnableOption' "Prometheus monitoring service";
+ grafana.enable = mkEnableOption' "Grafana monitoring service";
+ loki.enable = mkEnableOption' "Loki monitoring service";
+ };
+
+ # database backends
+ database = {
+ mysql.enable = mkEnableOption "MySQL database service";
+ mongodb.enable = mkEnableOption "MongoDB service";
+ postgresql.enable = mkEnableOption "Postgresql service";
+ redis.enable = mkEnableOption "Redis service";
+ };
+
+ smb = {
+ enable = mkEnableOption "Enables smb shares";
+ host.enable = mkEnableOption "Enables hosting of smb shares";
+
+ # should smb shares be enabled as a recpient machine
+ recive = {
+ general = mkEnableOption "genral share";
+ media = mkEnableOption "media share";
+ };
+ };
+ };
+}
diff --git a/modules/options/system/activation.nix b/modules/options/system/activation.nix
new file mode 100644
index 000000000..87a3731ce
--- /dev/null
+++ b/modules/options/system/activation.nix
@@ -0,0 +1,7 @@
+{lib, ...}: let
+ inherit (lib) mkEnableOption mdDoc;
+in {
+ options.modules.system.activation = {
+ diffGenerations = mkEnableOption (mdDoc "diff view between rebuilds");
+ };
+}
diff --git a/modules/options/system/boot.nix b/modules/options/system/boot.nix
new file mode 100644
index 000000000..29cc4d501
--- /dev/null
+++ b/modules/options/system/boot.nix
@@ -0,0 +1,116 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkOption mkEnableOption types;
+in {
+ options.modules.system.boot = {
+ enableKernelTweaks = mkEnableOption "security and performance related kernel parameters";
+ enableInitrdTweaks = mkEnableOption "quality of life tweaks for the initrd stage";
+ recommendedLoaderConfig = mkEnableOption "tweaks for common bootloader configs per my liking";
+ loadRecommendedModules = mkEnableOption "kernel modules that accommodate for most use cases";
+ tmpOnTmpfs = mkEnableOption "`/tmp` living on tmpfs. false means it will be cleared manually on each reboot";
+
+ kernel = mkOption {
+ type = types.raw;
+ default = pkgs.linuxPackages_latest;
+ description = "The kernel to use for the system.";
+ };
+
+ # https://nixos.wiki/wiki/Secure_Boot
+ secureBoot = mkEnableOption ''
+ secure-boot and load necessary packages, say good bye to systemd-boot
+ '';
+
+ extraModprobeConfig = mkOption {
+ type = types.str;
+ default = ''options hid_apple fnmode=1'';
+ description = "Extra modprobe config that will be passed to system modprobe config.";
+ };
+
+ silentBoot =
+ mkEnableOption (lib.mdDoc ''
+ almost entirely silent boot process through `quiet` kernel parameter
+ '')
+ // {default = config.modules.system.boot.plymouth.enable;};
+
+ extraKernelParams = mkOption {
+ type = with types; listOf str;
+ default = [];
+ };
+
+ extraModulePackages = mkOption {
+ type = with types; listOf package;
+ default = with config.boot.kernelPackages; [acpi_call];
+ description = "Extra kernel modules to be loaded.";
+ };
+
+ loader = mkOption {
+ type = types.enum ["none" "grub" "systemd-boot"];
+ default = "none";
+ description = "The bootloader that should be used for the device.";
+ };
+
+ device = mkOption {
+ type = with types; nullOr str;
+ default = "nodev";
+ description = "The device to install the bootloader to.";
+ };
+
+ memtest = {
+ enable = mkEnableOption "memtest86+";
+ package = mkOption {
+ type = types.package;
+ default = pkgs.memtest86plus;
+ description = "The memtest package to use.";
+ };
+ };
+
+ encryption = {
+ enable = mkEnableOption "LUKS encryption";
+
+ device = mkOption {
+ type = types.str;
+ default = "enc";
+ description = ''
+ The LUKS label for the device that will be decrypted on boot.
+ Currently does not support multiple devices at once.
+ '';
+ };
+
+ keyFile = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ description = ''
+ The path to the keyfile that will be used to decrypt the device.
+ Needs to be an absolute path, and the file must exist. Set to `null`
+ to disable.
+ '';
+ };
+
+ keySize = mkOption {
+ type = types.int;
+ default = 4096;
+ description = ''
+ The size of the keyfile in bytes.
+ '';
+ };
+
+ fallbackToPassword = mkOption {
+ type = types.bool;
+ default = !config.boot.initrd.systemd.enable;
+ description = ''
+ Whether or not to fallback to password authentication if the keyfile
+ is not present.
+ '';
+ };
+ };
+
+ plymouth = {
+ enable = mkEnableOption "plymouth boot splash";
+ withThemes = mkEnableOption "plymouth theme";
+ };
+ };
+}
diff --git a/modules/options/system/default.nix b/modules/options/system/default.nix
new file mode 100644
index 000000000..1110f0e1e
--- /dev/null
+++ b/modules/options/system/default.nix
@@ -0,0 +1,88 @@
+{
+ lib,
+ config,
+ ...
+}: let
+ inherit (lib) mkOption mkEnableOption optionals types mdDoc;
+in {
+ imports = [
+ ./activation.nix
+ ./boot.nix
+ ./emulation.nix
+ ./encryption.nix
+ ./networking.nix
+ ./printing.nix
+ ./security.nix
+ ./virtualization.nix
+ ];
+
+ options.modules.system = {
+ warnings = optionals (config.modules.system.users == []) [
+ ''
+ You have not added any users to be supported by your system. You may end up with an unbootable system!
+ Consider setting `config.modules.system.users` in your configuration
+ ''
+ ];
+
+ mainUser = mkOption {
+ type = types.enum config.modules.system.users;
+ description = "The username of the main user for your system";
+ default = builtins.elemAt config.modules.system.users 0;
+ };
+
+ users = mkOption {
+ type = with types; listOf str;
+ default = ["isabel"];
+ description = mdDoc ''
+ A list of users that you wish to declare as your non-system users. The first username
+ in the list will be treated as your main user unless `modules.system.mainUser` is set.
+ '';
+ };
+
+ hostname = mkOption {
+ type = types.str;
+ description = "The name of the device for the system";
+ };
+
+ autoLogin = mkOption {
+ type = types.bool;
+ default = false;
+ description = mdDoc ''
+ Whether to enable passwordless login. This is generally useful on systems with
+ FDE (Full Disk Encryption) enabled. It is a security risk for systems without FDE.
+ '';
+ };
+
+ fs = mkOption {
+ type = with types; listOf str;
+ default = ["vfat" "ext4"];
+ description = mdDoc ''
+ A list of filesystems available supported by the system
+ it will enable services based on what strings are found in the list.
+
+ It would be a good idea to keep vfat and ext4 so you can mount USBs.
+ '';
+ };
+
+ flakePath = mkOption {
+ type = types.str;
+ default = "/home/isabel/.config/flake";
+ description = "The path to the configuration";
+ };
+
+ sound = {
+ enable = mkEnableOption "sound";
+ description = "Does the device have sound and its related programs be enabled";
+ };
+
+ video = {
+ enable = mkEnableOption "video drivers";
+ description = "Does the device allow for graphical programs";
+ };
+
+ bluetooth = {
+ enable = mkEnableOption "bluetooth";
+ description = "should the device load bluetooth drivers and enable blueman";
+ };
+ };
+}
diff --git a/modules/options/system/emulation.nix b/modules/options/system/emulation.nix
new file mode 100644
index 000000000..01250d3c0
--- /dev/null
+++ b/modules/options/system/emulation.nix
@@ -0,0 +1,25 @@
+{
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkEnableOption mkOption types;
+in {
+ options.modules.system.emulation = {
+ # should we enable emulation for additional architechtures?
+ # enabling this option will make it so that you can build for, e.g.
+ # aarch64 on x86_&4 and vice verse - not recommended on weaker machines
+ enable = mkEnableOption ''
+ emulation of additional arcitechtures via binfmt. enabling this option will make it so that the system can build for
+ addiitonal systems such as aarc64 on x86_64 and vice versa.
+ '';
+
+ systems = mkOption {
+ type = with types; listOf str;
+ default = builtins.filter (system: system != pkgs.system) ["aarch64-linux" "i686-linux"];
+ description = ''
+ the systems to enable emulation for
+ '';
+ };
+ };
+}
diff --git a/modules/options/system/encryption.nix b/modules/options/system/encryption.nix
new file mode 100644
index 000000000..0ddd4ce8c
--- /dev/null
+++ b/modules/options/system/encryption.nix
@@ -0,0 +1,57 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (lib) mkEnableOption mkOption types mkIf;
+in {
+ config = mkIf config.modules.system.encryption.enable {
+ warnings =
+ if config.modules.system.encryption.device == ""
+ then [
+ ''
+ You have enabled LUKS encryption, but have not selected a device, you may not be able to decrypt your disk on boot.
+ ''
+ ]
+ else [];
+ };
+ options.modules.system.encryption = {
+ enable = mkEnableOption "LUKS encryption";
+
+ device = mkOption {
+ type = types.str; # this should actually be a list
+ default = "";
+ description = ''
+ The LUKS label for the device that will be decrypted on boot.
+ Currently does not support multiple devices at once.
+ '';
+ };
+
+ keyFile = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ description = ''
+ The path to the keyfile that will be used to decrypt the device.
+ Needs to be an absolute path, and the file must exist. Set to `null`
+ to disable.
+ '';
+ };
+
+ keySize = mkOption {
+ type = types.int;
+ default = 4096;
+ description = ''
+ The size of the keyfile in bytes.
+ '';
+ };
+
+ fallbackToPassword = mkOption {
+ type = types.bool;
+ default = !config.boot.initrd.systemd.enable;
+ description = ''
+ Whether or not to fallback to password authentication if the keyfile
+ is not present.
+ '';
+ };
+ };
+}
diff --git a/modules/common/options/system/networking.nix b/modules/options/system/networking.nix
similarity index 77%
rename from modules/common/options/system/networking.nix
rename to modules/options/system/networking.nix
index 7ae69aef5..f45b9568f 100644
--- a/modules/common/options/system/networking.nix
+++ b/modules/options/system/networking.nix
@@ -1,6 +1,5 @@
{lib, ...}:
with lib; {
- # should we optimize tcp networking
options.modules.system.networking = {
optimizeTcp = mkEnableOption "Enable tcp optimizations";
};
diff --git a/modules/options/system/printing.nix b/modules/options/system/printing.nix
new file mode 100644
index 000000000..a3fc4eec6
--- /dev/null
+++ b/modules/options/system/printing.nix
@@ -0,0 +1,13 @@
+{lib, ...}: let
+ inherit (lib) mkEnableOption mkOption types;
+in {
+ options.modules.system.printing = {
+ enable = mkEnableOption "printing";
+
+ drivers = mkOption {
+ type = with types; listOf str;
+ default = [];
+ description = "A list of additional drivers to install for printing";
+ };
+ };
+}
diff --git a/modules/options/system/security.nix b/modules/options/system/security.nix
new file mode 100644
index 000000000..21a63104b
--- /dev/null
+++ b/modules/options/system/security.nix
@@ -0,0 +1,88 @@
+{
+ pkgs,
+ lib,
+ ...
+}: let
+ inherit (lib) mkOption mkEnableOption mdDoc types;
+in {
+ options.modules.system.security = {
+ fixWebcam = mkEnableOption (mdDoc "Fix the purposefully broken webcam by un-blacklisting the related kernel module.");
+ tor.enable = mkEnableOption (mdDoc "Tor daemon");
+ lockModules = mkEnableOption (mdDoc "Lock kernel modules to the ones specified in the configuration. Highly breaking.");
+
+ auditd = {
+ enable = mkEnableOption (mdDoc "Enable the audit daemon.");
+ autoPrune = {
+ enable = mkEnableOption (mdDoc "Enable auto-pruning of audit logs.");
+
+ size = mkOption {
+ type = types.int;
+ default = 524288000; # roughly 500 megabytes
+ description = "The maximum size of the audit log in bytes.";
+ };
+
+ dates = mkOption {
+ type = types.str;
+ default = "daily";
+ example = "weekly";
+ description = "How often cleaning is triggered. Passed to systemd.time";
+ };
+ };
+ };
+
+ clamav = {
+ enable = mkEnableOption (mdDoc "Enable ClamAV daemon.");
+
+ daemon = {
+ settings = mkOption {
+ type = with types; attrsOf (oneOf [bool int str (listOf str)]);
+ default = {
+ LogFile = "/var/log/clamd.log";
+ LogTime = true;
+ VirusEvent = lib.escapeShellArgs [
+ "${pkgs.libnotify}/bin/notify-send"
+ "--"
+ "ClamAV Virus Scan"
+ "Found virus: %v"
+ ];
+ DetectPUA = true;
+ };
+ description = lib.mdDoc ''
+ ClamAV configuration. Refer to ,
+ for details on supported values.
+ '';
+ };
+ };
+
+ updater = {
+ enable = mkEnableOption (lib.mdDoc "ClamAV freshclam updater");
+
+ frequency = mkOption {
+ type = types.int;
+ default = 12;
+ description = lib.mdDoc ''
+ Number of database checks per day.
+ '';
+ };
+
+ interval = mkOption {
+ type = types.str;
+ default = "hourly";
+ description = lib.mdDoc ''
+ How often freshclam is invoked. See systemd.time(7) for more
+ information about the format.
+ '';
+ };
+
+ settings = mkOption {
+ type = with types; attrsOf (oneOf [bool int str (listOf str)]);
+ default = {};
+ description = lib.mdDoc ''
+ freshclam configuration. Refer to ,
+ for details on supported values.
+ '';
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/options/system/virtualization.nix b/modules/options/system/virtualization.nix
similarity index 77%
rename from modules/common/options/system/virtualization.nix
rename to modules/options/system/virtualization.nix
index f5d18b593..c9d57a8e7 100644
--- a/modules/common/options/system/virtualization.nix
+++ b/modules/options/system/virtualization.nix
@@ -2,9 +2,8 @@
inherit (lib) mkEnableOption;
in {
options.modules.system = {
- # should virtualization (docker, qemu, podman etc.) be enabled
virtualization = {
- enable = mkEnableOption "virtualization";
+ enable = mkEnableOption "Should the device be allowed to virtualizle processes";
docker = {enable = mkEnableOption "docker";};
podman = {enable = mkEnableOption "podman";};
qemu = {enable = mkEnableOption "qemu";};
diff --git a/modules/options/themes/default.nix b/modules/options/themes/default.nix
new file mode 100644
index 000000000..1fac1c3a8
--- /dev/null
+++ b/modules/options/themes/default.nix
@@ -0,0 +1,59 @@
+{
+ lib,
+ pkgs,
+ config,
+ ...
+}: let
+ inherit (lib) mkOption mkEnableOption types mdDoc;
+ cfg = config.modules.style;
+in {
+ imports = [./gtk.nix ./qt.nix];
+ options = {
+ modules = {
+ style = {
+ forceGtk = mkEnableOption "Force GTK applications to use the GTK theme";
+ useKvantum = mkEnableOption "Use Kvantum to theme QT applications";
+
+ # choose a colorscheme
+ colorScheme = {
+ # "Name Of The Scheme"
+ name = mkOption {
+ type = with types; nullOr (enum ["Catppuccin Mocha" "Tokyo Night"]);
+ description = "The colorscheme that should be used globally to theme your system.";
+ default = "Catppuccin Mocha";
+ };
+
+ # "name-of-the-scheme"
+ slug = mkOption {
+ type = types.str;
+ default = lib.serializeTheme "${cfg.colorScheme.name}";
+ description = mdDoc ''
+ The serialized slug for the colorScheme you are using. Defaults to a lowercased version of the theme name with spaces
+ replaced with hyphens. Only change if the slug is expected to be different."
+ '';
+ };
+ };
+
+ pointerCursor = {
+ package = mkOption {
+ type = types.package;
+ description = "The package providing the cursors";
+ default = pkgs.catppuccin-cursors.mochaDark;
+ };
+
+ name = mkOption {
+ type = types.str;
+ description = "The name of the cursor inside the package";
+ default = "Catppuccin-Mocha-Dark-Cursors";
+ };
+
+ size = mkOption {
+ type = types.int;
+ description = "The size of the cursor";
+ default = 24;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/options/themes/gtk.nix b/modules/options/themes/gtk.nix
new file mode 100644
index 000000000..0501f5d15
--- /dev/null
+++ b/modules/options/themes/gtk.nix
@@ -0,0 +1,68 @@
+{
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkOption mkEnableOption types;
+in {
+ options = {
+ modules = {
+ style = {
+ gtk = {
+ enable = mkEnableOption "GTK theming optionss";
+ usePortal = mkEnableOption "native desktop portal use for filepickers";
+
+ theme = {
+ name = mkOption {
+ type = types.str;
+ default = "Catppuccin-Mocha-Standard-Sapphire-Dark";
+ description = "The name for the GTK theme package";
+ };
+
+ package = mkOption {
+ type = types.package;
+ description = "The theme package to be used for GTK programs";
+ default = pkgs.catppuccin-gtk.override {
+ size = "standard";
+ accents = ["sapphire"];
+ variant = "mocha";
+ tweaks = ["normal"];
+ };
+ };
+ };
+
+ iconTheme = {
+ name = mkOption {
+ type = types.str;
+ description = "The name for the icon theme that will be used for GTK programs";
+ default = "Papirus-Dark";
+ };
+
+ package = mkOption {
+ type = types.package;
+ description = "The GTK icon theme to be used";
+ default = pkgs.catppuccin-papirus-folders.override {
+ accent = "sapphire";
+ flavor = "mocha";
+ };
+ };
+ };
+
+ font = {
+ name = mkOption {
+ type = types.str;
+ description = "The name of the font that will be used for GTK applications";
+ default = "RobotoMono Nerd Font Regular";
+ };
+
+ size = mkOption {
+ type = types.int;
+ description = "The size of the font";
+ default = 14;
+ };
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/options/themes/qt.nix b/modules/options/themes/qt.nix
new file mode 100644
index 000000000..f75e5c368
--- /dev/null
+++ b/modules/options/themes/qt.nix
@@ -0,0 +1,43 @@
+{
+ lib,
+ pkgs,
+ config,
+ ...
+}: let
+ inherit (lib) mkEnableOption mkOption types;
+ cfg = config.modules.style;
+in {
+ options = {
+ modules = {
+ style = {
+ qt = {
+ enable = mkEnableOption "QT Style Module";
+
+ theme = {
+ package = mkOption {
+ type = types.package;
+ default = pkgs.catppuccin-kde.override {
+ flavour = ["mocha"];
+ accents = ["sapphire"];
+ winDecStyles = ["modern"];
+ };
+ description = "The theme package to be used for QT programs";
+ };
+
+ name = mkOption {
+ type = types.str;
+ default = "Catppuccin-Mocha-Dark";
+ description = "The name for the QT theme package";
+ };
+ };
+
+ kdeglobals.source = mkOption {
+ type = types.path;
+ default = "${cfg.qt.theme.package}/share/color-schemes/CatppuccinMochaSapphire.colors";
+ description = "The source file for the kdeglobals file. Usually provided by the qt theme package";
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/common/options/usrEnv/default.nix b/modules/options/usrEnv/default.nix
similarity index 66%
rename from modules/common/options/usrEnv/default.nix
rename to modules/options/usrEnv/default.nix
index dbc09cfac..384d488ed 100644
--- a/modules/common/options/usrEnv/default.nix
+++ b/modules/options/usrEnv/default.nix
@@ -1,10 +1,19 @@
-{lib, ...}:
-with lib; {
+{lib, ...}: let
+ inherit (lib) mkOption types mdDoc;
+in {
options.modules.usrEnv = {
+ useHomeManager = mkOption {
+ type = types.bool;
+ default = true;
+ description = mdDoc ''
+ Whether to use home-manager or not. Username MUST be set if this option is enabled.
+ '';
+ };
+
desktop = mkOption {
type = types.enum ["Hyprland"];
default = "Hyprland";
- description = lib.mdDoc ''
+ description = mdDoc ''
The desktop environment to be used.
'';
};
@@ -12,7 +21,7 @@ with lib; {
isWayland = mkOption {
type = types.bool;
default = true;
- description = lib.mdDoc ''
+ description = mdDoc ''
Whether to enable Wayland compatibility module. This generally includes:
- Wayland nixpkgs overlay
- Wayland only services
@@ -21,21 +30,5 @@ with lib; {
- Wayland compatible versions of packages
'';
};
-
- useHomeManager = mkOption {
- type = types.bool;
- default = true;
- description = lib.mdDoc ''
- Whether to use home-manager or not. Username MUST be set if this option is enabled.
- '';
- };
-
- noiseSupressor = mkOption {
- type = with types; nullOr (enum ["rnnoise" "noisetorch"]);
- default = "rnnoise";
- description = lib.mdDoc ''
- The noise supressor to be used for desktop systems with sound enabled.
- '';
- };
};
}